# dklibs 1.23.1

- Overview
- Download
- Installation
- Installation from source on Windows systems
- Usage
- FAQ
- Change log
- Other projects
- Tutorial
- Developer docu
- stc
- tracecc and trana
- tracecc GUI
- tracecc PDF man.
- API: sort and search
- API: Generic I/O
- Preferences
- File search
- Font configuration
- LaTeX encodings
- Security

## tracecc - C trace preprocessor

- Purpose of the program
- Example input file
- List of tracecc builtin functions
- Creating a debug version, debug output to stdout
- Debug output to file
- Generating non-debug output
- Tracecc options
- Beautifying debug output for inspection
- Inspecting debug output using Vim
- Integrate tracecc into MS Visual Studio .NET Prof.

### Purpose of the program

Tracecc is a debugging preprocessor for C, C++, Objective-C and Java. it processes .ctr, .cpt, .mtr and .jtr files to produce .c, .cpp, .m or .java files.
Input file may contain tracecc special instructions. Depending on the tracecc options and preferences the special instructions are converted into C code or skipped.
Debug special instructions are converted to C code writing debug messages if tracecc is run in debug mode.
The trana program can beautify the debug messages for an easier inspection.

### Example input file

    #include <stdio.h>
    $(trace-include)

    static void run_function(int arg)
    {
      int i;
      $? "+ run_function %d", arg
      for(i = 0; i < 10; i++) {
        $? ". in the loop, everything ok"
      }
      $? "- run_function"
    }

    int main(int argc, char *argv[])
    {
      int condition = 0;
      $(trace-init example.deb)
      for(i = 0; i < 5; i++) {
        run_function(i);
      }
      if(condition) {
        $? ". everything ok"
      } else {
        $? "! error: condition not set"
      }
      $(trace-end)
    }

Tracecc special instructions are started by a dollar sign ($). Several instruction types are possible:

$(fct-name argument(s)) $! fct-name argument(s) | Tracecc builtin function. Examples are: trace-include is converted to "#include <dktrace.h>" in debug mode, to an empty line otherwise. trace-init filename opens the trace output file and enables trace messages when in debug mode, does nothing otherwise. trace-end closes the trace output file and disables further trace messages when in debug mode, does nothing otherwise. There are more functions available, see below.
$? format arguments | Debug instruction. If tracecc is running in debug mode, this is converted into a printf/fprintf instruction. It is recommended to start debug messages for invoking a function by "+", for returning from a function by "-", for normal conditions by "." and for error conditions by "!".

### List of tracecc builtin functions

- trace-include
  is converted to "#include <dktrace.h>" in debug mode, to an empty line otherwise.
- trace-init filename
  opens the trace output file and enables trace messages when in debug mode, does nothing otherwise.
- trace-end
  closes the trace output file and disables further trace messages when in debug mode, does nothing otherwise.
- trace-off
  trace-on
  can be used to turn debug message output temporarily off and back on. These functions only have effect if tracecc is run in debug mode.
- timestamp-on
  timestamp-off
  enables/disables output of time stamps together with debug messages. These functions only have effect if tracecc is run in debug mode.
- lineno-on
  lineno-off
  turn output of line numbers together with debug messages on or off. These functions only have effect if tracecc is run in debug mode.
- string-file filename
  reads the specified text file line by line and converts it into an array of strings.
- byte-file filename
  reads the specified file and converts it into an array of bytes.
- pipe command
  | command
  executes the specified shell command and transfers the command's standard output into the destination C file.
- trace-code code
  ! code
  transfers the given C code into the C destination file only when tracecc is run in debug mode.

### Creating a debug version, debug output to stdout

By running

    tracecc -r -d -s x.ctr x.c

we create an output file like

    #include <stdio.h>
    #include <dktrace.h>

    static void run_function(int arg)
    {
      int i;
      /* TRACE BEGIN */
      { fputs("x.ctr:7: ", stdout); }
      {
      printf("+ run_function %d", arg);
      }
      { fputc('\n', stdout); }
      fflush(stdout);
      /* TRACE END */
      for(i = 0; i < 10; i++) {
        /* TRACE BEGIN */
        { fputs("x.ctr:9: ", stdout); }
        {
        printf(". in the loop, everything ok");
        }
        { fputc('\n', stdout); }
        fflush(stdout);
        /* TRACE END */
      }
      /* TRACE BEGIN */
      { fputs("x.ctr:11: ", stdout); }
      {
      printf("- run_function");
      }
      { fputc('\n', stdout); }
      fflush(stdout);
      /* TRACE END */
    }

    int main(int argc, char *argv[])
    {
      int condition = 0;

      for(i = 0; i < 5; i++) {
        run_function(i);
      }
      if(condition) {
        /* TRACE BEGIN */
        { fputs("x.ctr:22: ", stdout); }
        {
        printf(". everything ok");
        }
        { fputc('\n', stdout); }
        fflush(stdout);
        /* TRACE END */
      } else {
        /* TRACE BEGIN */
        { fputs("x.ctr:24: ", stdout); }
        {
        printf("! error: condition not set");
        }
        { fputc('\n', stdout); }
        fflush(stdout);
        /* TRACE END */
      }

    }

### Debug output to file

By running

    tracecc -r -d x.ctr x.c

we create an output file like

    #include <stdio.h>
    #include <dktrace.h>

    static void run_function(int arg)
    {
      int i;
      /* TRACE BEGIN */
      { if(dktrace_file()) { fputs("x.ctr:7: ", dktrace_file()); } }
      { if(dktrace_file()) {
      fprintf(dktrace_file(), "+ run_function %d", arg);
      } }
      { if(dktrace_file()) { fputc('\n', dktrace_file()); } }
      { if(dktrace_file()) { fflush(dktrace_file()); } }
      /* TRACE END */
      for(i = 0; i < 10; i++) {
        /* TRACE BEGIN */
        { if(dktrace_file()) { fputs("x.ctr:9: ", dktrace_file()); } }
        { if(dktrace_file()) {
        fprintf(dktrace_file(), ". in the loop, everything ok");
        } }
        { if(dktrace_file()) { fputc('\n', dktrace_file()); } }
        { if(dktrace_file()) { fflush(dktrace_file()); } }
        /* TRACE END */
      }
      /* TRACE BEGIN */
      { if(dktrace_file()) { fputs("x.ctr:11: ", dktrace_file()); } }
      { if(dktrace_file()) {
      fprintf(dktrace_file(), "- run_function");
      } }
      { if(dktrace_file()) { fputc('\n', dktrace_file()); } }
      { if(dktrace_file()) { fflush(dktrace_file()); } }
      /* TRACE END */
    }

    int main(int argc, char *argv[])
    {
      int condition = 0;
      dktrace_init("example.deb");
      for(i = 0; i < 5; i++) {
        run_function(i);
      }
      if(condition) {
        /* TRACE BEGIN */
        { if(dktrace_file()) { fputs("x.ctr:22: ", dktrace_file()); } }
        { if(dktrace_file()) {
        fprintf(dktrace_file(), ". everything ok");
        } }
        { if(dktrace_file()) { fputc('\n', dktrace_file()); } }
        { if(dktrace_file()) { fflush(dktrace_file()); } }
        /* TRACE END */
      } else {
        /* TRACE BEGIN */
        { if(dktrace_file()) { fputs("x.ctr:24: ", dktrace_file()); } }
        { if(dktrace_file()) {
        fprintf(dktrace_file(), "! error: condition not set");
        } }
        { if(dktrace_file()) { fputc('\n', dktrace_file()); } }
        { if(dktrace_file()) { fflush(dktrace_file()); } }
        /* TRACE END */
      }
      dktrace_end();
    }

The program uses dktrace_-functions, so we must use the dktrace library when linking the executable.

### Generating non-debug output

By running

    tracecc -r x.ctr x.c

we create an output file like

    #include <stdio.h>

    static void run_function(int arg)
    {
      int i;

      for(i = 0; i < 10; i++) {

      }

    }

    int main(int argc, char *argv[])
    {
      int condition = 0;

      for(i = 0; i < 5; i++) {
        run_function(i);
      }
      if(condition) {

      } else {

      }

    }

### Tracecc options

- -v, --version
  shows the program version.
- -h, --help
  shows a help text.
- -r, --reset
  ignores all permanent options temporarily (for this one program invokation).
- -u, --unconfigure
  removes all permanent options.
- -c <options>, --configure <options>
  configures permanent options.
- -C, --show-configuration
  shows the permanent options.
- -d, --debug-enable
  enables debug mode.
- -d-, --debug-enable=off
  disables debug mode.
- -s, --debug-stdout
  writes debug messages to standard output.
- -s-, --debug-stdout
  writes debug messages to the debug file.
- -t, --debug-timestamp
  adds a time stamp to debug messages.
- -t-, --debug-timestamp=off
  disables output of time stamps for debug messages.
- -l, --linenumbers
  adds "#line..." preprocessor directives to the C destination file.
- -l-, --linenumbers=off
  disables "#line..." preprocessor directives.
- -m, --make
  enables make-mode. When run on directories in this mode conversions are only run for those source files newer than their destination files.
- -m-, --make=off
  disables make mode.
- -p, --cpp-comments
  lets C++ comments pass through.
- -p-, --cpp-comments=off
  converts C++ comments to C comments.
- -k, --keyword
  adds the "trace" keyword to each debug output line.
- -k-, --keyword=off
  does not add the "trace" keyword.
- -b box-width
  sets the width of comment boxes.
  In the source file a comment box is written in special instructions like these:

      $*
      This is a comment describing a function. This comment
      is converted into a pretty box.
      $*

  The conversion result looks like this:

      /* ********************************************************************* */
      /* *                                                                   * */
      /* * This is a comment describing a funtion.                           * */
      /* * It is converted into a pretty box.                                * */
      /* *                                                                   * */
      /* ********************************************************************* */

### Beautifying debug output for inspection

The trana program modifies debug output to allow an easier inspection using editors capable of folding (i.e. Vim).
Folding in editors means that the editor does not show the complete text, parts of the text are hidden, a short summary line is printed instead. By typing special keys or choosing menu items the user can switch between full text and summary.
Folding can be based on insertion level or special text segments called "fold markers".
The trana program can either insert leading spaces or fold markers depending on the options specified on the command line.
The syntax to run trana is

    trana <options>
    trana <options> <input-file>
    trana <options> <input-file> <output-file>

If input-file or output-file are not specified, standard input is read, output goes to standard output. The options -c/--configure, -C/--show-configuration, -u/--unconfigure, -r/--reset, -h/--help and -v/--version work like described above for tracecc.
Additionally the following options are available:

- -m, --marker
  add fold markers to the output.
- -m-, --marker=off
  does not add fold markers to the output.
- -t, --trace-only
  write only lines containing the "trace" keyword to the output.
- -t-, --trace-only=off
  does not restrict output to lines containing the "trace" keyword.
- -n, --numeric
  print a numeric indent level at the beginning of each line.
- -n-, --numeric=off
  does not print a numeric indent level.
- -p, --position
  transfers the source location to the output (this is enabled by default).
- -p-, --position=off
  does not transfer source location to the output.

### Inspecting debug output using Vim

When inspecting trana output using Vim one should set up folding either by indent level:

    :setlocal sw=2
    :setlocal foldmethod=indent

or by markers:

    :setlocal foldmethod=marker

In on-text-mode (not command-mode) one can use the key sequences `zo` to open a fold, `zc` to close a fold. The sequence `zr` opens all folds one level, `zm` closes one fold level.

### Integrate tracecc into MS Visual Studio .NET Prof.

Visual Studio .NET Prof. 2003 was used while writing this text.

External programs can be integrated to MS Visual Studio using the "Extras / Externe Tools..." menu item in the german version. Possible translations to English: "Extras / External Tools..." or "Add-ons / External Tools...".
A list of integrated tools appears, press the button "Hinzufügen" (in English probably "Add entry" or "New entry").
In the "Titel" ("title") text field insert:

    Tracecc Compile Make

In the "Befehl" ("instruction"/"command") text field insert:

    tracecc.exe

In the "Argumente" ("arguments") text field type (all in one line, the line is shown broken here because it is too long):

    -r -l -m --/log/stderr/level=progress --/log/stderr/ide=msvc
    	--/log/stderr/codepage=- --/log/stdout/level=none
    	--/log/file/level=none $(ProjectDir)

In the "Ausgangsverzeichnis" ("current directory") insert:

    $(ProjectDir)

The "Ausgabefenster verwenden" ("use output window") option must be enabled.

Add further entries, replace the title and the `-r -l -m` part in the arguments as follows:

Title | Options
--- | ---
Tracecc Compile All | -r -l -m-
Tracecc Debug Make | -r -d -l -m
Tracecc Debug All | -r -d -l -m-