***Architecture Of The CVSTrac Program***
*1.0 Introduction*
This note gives a high-level overview of how the CVSTrac program works
and how it is put together.
It is assumed that the reader is already familiar with what CVSTrac
does. The purpose of this document is to provide some additional
background information on the internal operation of CVSTrac in order
to guide potential contributors in making improvements to the code.
*2.0 Design Rules*
CVSTrac is designed so that each incoming HTTP request is handled by
a separate process. No attempt is made to avoid memory leaks, since the
process will terminate as soon as the HTTP request is finished. Global
variables are used where it is convenient since only a single thread
will be running in the address space.
Some people worry that using
a separate process for each HTTP request is inefficient. It may be true
that one process per request is not the most efficient design, but it
appears to be efficient enough. A 166MHz Pentium with 32MB of RAM has
proven to be more than adequate to service a large development group.
So for now, CVSTrac will stick with a simple but adequate design that
avoids subtle bugs rather than push the envelope with a high-performance
design that is harder to work with and more prone to errors.
The program is designed for Unix. No thought has been given to making
it run on the "other platform", though there have been reports of limited success getting it to work using Cygwin. (See for example CvstracOnWindows.)
*3.0 Code Generators And Preprocessors*
The programming language used to implement CVSTrac is C.
But most of the code that actually
reaches the C compiler is either automatically generated or preprocessed.
The source code that you, the programmer, look at in an editor is not
the same source code that the C compiler works with.
CVSTrac currently uses five different code generators and
preprocessors:
*: Most of the header files (the *.h files) are generated by
the {link: http://www.hwaci.com/sw/mkhdr/ makeheaders} program.
*: The C source files contain embedded HTML text. This text
is converted into special function calls using the
"*translate*" preprocessor.
*: Each CVSTrac webpage is handled by a different subroutine.
The page handler subroutines each have a special header comment
that identifies them as such. The *mkindex* program
scans the source files for these header comments and constructs
a table of webpages used by by the dispatcher.
*: The text of the initial wiki that are created when a new
project is initialized is contained in the "wikiinit.c"
source file. That source file is created by editing the wiki
in a working CVSTrac project, then running the "*makewikiinit*"
program over the project database.
*: The "main.mk" makefile is generated by a Tcl script
"makemake.tcl".
A few of these code generators and preprocessors are explained
in added detail by the following subheadings.
*3.1 Extracting embedded HTML using "translate"*
The CVSTrac program deals with a lot of text - mostly HTML but
also a fair amount of SQL. But large blocks of text (where large
means hundreds or thousands of characters or dozens of lines) are
difficult to deal with in C. All the text must be enclosed in
double-quotes and special characters, such as newlines and the
double-quote character itself, must be escaped by using a backslash.
The net result is that the text becomes difficult to read and edit.
The *translate* program tries to make the code more readable
by converting all lines that begin with a "*@*" character into code that
appends the text on that line to the HTML document being generated.
This makes the output text more readable by avoiding the
need to write "*\n*" and "*\"*". Furthermore, the
line of *@* characters at the left margin allows the eye to quickly see
what code is C executable and what is HTML text. Consider this
example (taken from {link: getfile?f=cvstrac/ticket.c ticket.c}):
@ Description:
@ (See formatting hints)
if( isPreview ){
@
output_formatted(aParm[10].zNew, zPage); @ |