**CVSTrac Coding Guidelines** These are more like observations from a latecomer, but better than nothing. CvstracArchitecture is a big picture overview. This talks about the nitty-gritty coding details. *Indentation* CVSTrac source uses two spaces for indentation, no tabs. *Braces and Parentheses* Braces are a modified K&R. Generally, there should be no whitespace between the trailing paren and the leading brace. i.e. void function(args){ if( condition ){ } } In the case of _else_ and _else if_ keywords, also eliminate extra whitespace: if( condition ){ }else if( condition2 ){ }else{ } Within parentheses, rules differ. For example, _if_ and _while_ statements use internal whitespace: if( condition ){ while( v[i] ) i++; } but _for_ loops are a bit different: for(i=0; i<40; i++){ } Note that single-line _if_, _for_ and occasionally _while_ constructs are perfectly acceptable: if( tn<=0 ) tn = 1; for(nChng=0; az[nChng]; nChng++){} *Preprocessing* CVSTrac has a magical preprocessor which extracts HTML strings prefixed inline by '@' characters and basically turns them into _cgi_printf()_ calls. CvstracArchitecture discusses this further. *Variables* Variable naming is partially Hungarian style. *: 'z' prefixes NUL-terminated strings *: 'az' prefixes an array of 'z' strings. 'az' strings also appear to be NULL terminated. *: 'p' prefixes a pointer to something *: 'n' occasionally prefixes integers Some commonly used variable names *: =tn= is a ticket number *: =cn= is a change/checkin number *: =rn= is a report number *Frequently Seen Functions* _Not even close to a complete list._ *: =P(x)= the CGI parameter _x_, or =NULL= *: =PD(x,y)= the CGI parameter _x_, or _y_ *: =cgi_printf()= writes a formatted string into the CGI output buffer *: =mprintf()= is a custom function to format a string into a new memory buffer *: =output_formatted(zText,zPage)= output _zText_ to the CGI buffer, doing any needed wiki formatting. _zPage_ indicates the source page (i.e. wiki page) and is used for finding embeddable attachments like images. *: =db_query()= execute a SQLite query against the database and return the results as an _az_ array. Deallocate results with =db_query_free()=. *: =db_short_query()=, returns a single NUL-terminated string. Clean up with =free()=. *: =db_execute()= executes a SQLite query, returning nothing. *: =OS_VAL(unix,win)= expands to _unix_ under non-Windows builds and to _win_ under Windows builds. Used to select platform dependent constants and expressions. *Memory* CVSTrac doesn't worry about memory management! It's assumed that a CVSTrac instance will live only long enough to serve out a request and then resources will be reclaimed (AKA garbage collection by exit()). As such, you frequently see constructs like: zPath = mprintf("%s/%s", zDir, zFile); without a corresponding _free()_. The only time memory is really a concern happens when a large amount of activity happens in a loop. In such instances, _free()_ or _db_query_free()_ will be used. *Format Strings* CVSTrac uses a custom mprintf() which supports additional formatting. For security purposes, the following are preferred over just *%s*: *: %h Escapes HTML markup *: %T For URLs. Preserves "/" characters *: %t For URLs. Translates "/" into "%2F" *: %q Escapes ' characters in SQL *Security* CVSTrac cares about security. This means dynamic memory allocation where possible, really large static buffers with limits on the size of copies, heavy use of the %q format (as found in _mprintf()_ and _db_query()_), and a lot of heavily used helper functions to manage all this. *Platform Dependent Code* Platform dependent code is generally caused Windows API incompatibility with general UNIX (POSIX) specification and Windows command line and shell command line differences. Where it is possible Windows code parts are distinguished with =OS_VAL= macro. Where it is not possible, =#ifdef CVSTRAC_WINDOWS= preprocessor conditional block is used (=CVSTRAC_WINDOWS= is defined within the code in Windows) and appropriate comment regarding the difference is provided.