Menu

dkcpre manual

Dirk Krause
Attachments
tdkct.c (946 bytes)
tdkct.ctr (897 bytes)
← Previous ↑ Home → Next

dkcpre — Debugging and tracing preprocessor for C / C++

Synopsis

dkcpre [_options_] _file(s)_
dkcpre [_options_] _directory_

Description

The dkcpre program processes *.ctr, *.cpt, *.mtr and *.jtr input files and creates *.c, *.cpp, *.m (Objective C) and *.java files. It also writes *.h files if an appropriate section is found in the source file.

For *.wxc files the program produces *.cpp and *.h files, *.wxc files contain GUI descriptions for programs using the wxWidgets library set.

The program serves the following purposes:

Debugging and tracing
The sources can contain debug instructions in a special notation, i.e.

$? ". x=%d", x

The instructions are ignored when producing release output and converted to code writing debug/trace messages when producing debug output.

State machine code generation
A state machine can be specified as lookup table, this table is converted into C functions to reset the state machine and to process one input.

GUI layout code generation
*.wxc sources can contain a wx-gui section describing a GUI in a simple syntax. C++ source code using the wxWidgets library to build the GUI is generated.

The wxdkct program shows a GUI, the dkcpre program is a command line tool.


Options

Option Purpose
-R
--reset
Reset, skip all settings from configuration file.
-d
--debug
Debug output (default: release output).
-s
--debug‑stdout
Debug output going to standard output.
-t
--timestamp
Add timestamp to trace messages
-k
--trace‑keyword
Add "trace" keyword to each trace message
-w
--windows‑wide‑char
Prepare debug output to switch between normal and wide characters. Note: For trace messages containing %!xc or %!xs special placeholders this option produces 19 output lines instead of the usual 9 lines. You should use this option only if you plan to compile the sources on a Windows computer.
-p
--portable‑output
Portable code for writing debug message. Implies -w. Warning: For trace messages containing %!xc or %!xs special placeholders this option produces 69 output lines instead of the usual 9 lines. You should use this option only if you plan to run "dkcpre -d" on one computer but do the compilation on another computer.
-l
--line‑numbers
Write "#line …" directives in C output files.
-m
--make
Make mode: rebuild output files only if necessary.
-b width
--box‑width=width
Integer, box width for comment boxes.
-S
--splint
Splint annotation comment output, use the default "@" as comment char.
--splint‑comment‑char=char Splint annotation comment output, use the specified character as comment char.
--no‑modification‑warning Suppress warning at beginning of output files.
The warning advises users to modify the source files processed by dkcpre, not the output files produced by the program.
-h
--help
Show help text.
-v
--version
Show version information.
-L
--license‑terms
Show license information.

Exit status

0 on success, all other status codes indicate an error.


Input file syntax for *.ctr, *.cpt, *.mtr and *.jtr files

Sections

The input file may consist of several sections:

  • %% options
    Set up copyright owner, copyright time and license.
     
  • %% header
    Transferred to the *.h file.
     
  • %% module
    Transferred to the source code module (*.c, *.cpp, *.m, *.java).
     
  • %% state machine
    State machine description. Multiple state machine sections are allowed in a file.
     

The options section

The options section contains key/value pairs separated by "=". The following keys can be used:

Key Purpose
copyright owner Name of the copyright holder.
copyright year Year(s) for the copyright. Write either one year (4 digits) or a range of years (start and end year separated by a minus sign). If the end year is specified as "xxxx" the current year is used as end year.
license License type ("bsd", "gpl" or "lgpl").

All these settings are optional.

The header section

For *.ctr, *.cpt, *.mtr input files the contents of the header section is transferred into a *.h file.

A protection mechanism

#ifndef SHORTFILENAME_H_INCLUDED
#define SHORTFILENAME_H_INCLUDED 1
... header section contents ...
#endif

is generated automatically to avoid multiple inclusions.

If copyright owner, year or license type are specfied in the %%options section comments are generated automatically in the *.h output file.

The module section

The contents of the module section is transferred to the *.c, *.cpp, *.m or *.java.

If copyright owner, year or license type are specfied in the %%options section comments are generated automatically in the output file.

The following special dkcpre commands can be used in the module section:

Special command purpose
$!trace‑include Converted into "#include <dk3trace.h>" in debug mode or to an empty line in release mode.
$!trace‑init file Start debug output (opens the output file) in debug mode. Mostly used at the start of the main() function.
$!trace‑end End debug output (closes the output file) in debug mode. Mostly used at the end of the main() function immediately before exit().
$*
… contents …
$*
Comment box for the contents.
$? "formatstring", arguments Converted to trace output code in debug mode, ignored in release mode.
$!trace‑code arguments
$!! arguments
Add the C source code arguments to output file in debug mode.
$!pipe command
$!| command
Execute the specified command and add command output to the output file.
$!string‑table arguments Produce a string array in the output file and optionally a string table file. Finished by a $!end line. Lines started by "#" are comment lines. The arguments list is a comma-separated list of key=value pairs. The following key names are available:
  • file=filename
    Name of string table output file to produce.
  • prefix=prefix
    Prefix for string literals, a typical value is "L" to produce something like L"my text".
  • macro=macro
    Macro for string literals, typical values are "wxT" or "dkT" to produce something like wxT("my text") or dkT("my text").
$!string‑table‑file arguments Read string table file and produce string array. The arguments list is a comma-separated list of key=value pairs. The following key names are available:
  • file=filename
    Name of string table file to read, required.
  • prefix=prefix
    Prefix for string literals, a typical value is "L" to produce something like L"my text".
  • macro=macro
    Macro for string literals, typical values are "wxT" or "dkT" to produce something like wxT("my text") or dkT("my text").
$!text arguments Produce a string array in the output file and optionally a text file. Finished by a $!end line. Lines started by "#" are comment lines. The arguments list is a comma-separated list of key=value pairs. The following key names are available:
  • file=filename
    Name of string table output file to produce.
  • prefix=prefix
    Prefix for string literals, a typical value is "L" to produce something like L"my text".
  • macro=macro
    Macro for string literals, typical values are "wxT" or "dkT" to produce something like wxT("my text") or dkT("my text").
  • preprocessor
    Flag: Lines started by "#" in column 0 are preprocessor lines and must be transferred literally. Use a backslash to escape "#" when text lines started by "#" are needed.
    Without this flag lines started by "#" in column 0 are considered to be text lines.
$!string arguments Produce one long string consisting of several pieces. Finished by a $!end line. The arguments list is a comma-separated list of key=value pairs. The following key names are available:
  • newlines
    Add newline at the end of each text piece.
  • prefix=prefix
    Prefix for string literals, a typical value is "L" to produce something like L"my text".
  • macro=macro
    Macro for string literals, typical values are "wxT" or "dkT" to produce something like wxT("my text") or dkT("my text").
  • preprocessor
    Flag: Lines started by "#" in column 0 are preprocessor lines and must be transferred literally. Use a backslash to escape "#" when text lines started by "#" are needed.
    Without this flag lines started by "#" in column 0 are considered to be text lines.
$!binary‑file filename Insert file contents in decimal notation.

State machine sections

A state machine is defined by

  • options
    defined in an optional "[options]" subsection,
     
  • a set of states
    defined in a mandatory "[states]" subsection,
     
  • a set of inputs
    defined in a mandatory "[inputs]" subsection,
     
  • a set of outputs
    defined in a mandatory "[outputs]" subsection and
     
  • a set of rules
    defined in a mandatory "[rules]" subsection.

The [options] subsection consists of key=value pairs, the following pairs are allowed:

Key Value type Purpose
name Identifier Used as the start of function names. It must be a valid identifier in the C programming language.
write header Boolean Write definitions for states, inputs and outputs to the header file. By default these definitions are written at the start of the module.
use defines Boolean Use "#define…" instructions to define a state, input, or output. Enums are used by default.

The [states], [inputs] and [outputs] subsections define one state, input or output name per line.
Each line consists of a mandatory name (C identifier) for state, input or output, optionally followed by the integer value representing the state, input or output.
To add a comment, use the raute character "#". Comment text is finished at end of line.

The first state defined in the "[states]" section is the default state established by the xxx_reset() function.

The [rules] section defines transitions from state/input pairs to new state producing an output. Each line defines one rule and consists of four elements:

  • current state
  • input
  • new state
  • output

The wildcard "*" can be used for current state and/or input to define wildcard rules or a general rule. To resolve conflicts the rules have different priority:

  • Exact rules
    An exact rule does not contain wildcards. Exact rules have highest priority.
     
  • Wildcard rules
    A wildcard rules uses one "*" placeholder, either for the state or for the input. If a (state;input) combination matches multiple wilcard rules but no exact rule the first wildcard rule found is used.
     
  • General rule
    In the general rule the "*" placeholder is used for both current state and input. The general rule has lowest priority, it is used only for those (state;input) combinations not matching a wildcard rule or exact rule.
    If no general rule is written in the rules section an implicit general rule points to the first state defined in the states section as new state and the first output defined in the outputs section.

Input file syntax for *.wxc files

Overview

A *.wxc file contains the following sections:

  • %% options
  • %% wx-gui
  • %% header start
  • %% class start
  • %% class end
  • %% header end
  • %% module start
  • %% constructor start
  • %% constructor end
  • %% module end

The contents of these sections is used to create the *.h and *.cpp file as follows:

Sections of a wxc file

The contents of the "%% wx-gui" section is used twice:

  • Member variables for the GUI objects are placed in the class definition in the *.h file.
  • Code to initialize the generated member variables and to build the GUI is inserted into the constructor.

The wx-gui section

The wx-gui section is a list of paragraphs. Each paragraph describes either the top level window or one of the GUI elements.

Each paragraph — except the first one — is introduced by a header line consisting of a class and the member variable name.

A "[type name]" paragraph header will result in a

type *name;

member declaration in the class definition.

The first paragraph without a paragraph header describes the top level window.

The lines in the paragraph are attributes as key=value pairs.

Keys in alphabetical order

bitmap = wxBitmap:bitmap
Bitmap to show for wxStaticBitmap and wxBitmapButton.
 
bitmap button style =   [auto-draw]   [top | bottom]   [left | right]
Optional style for a wxBitmapButton.
 
Keywords for the bitmap button style attribute
KeywordMeaning
auto-draw Add a 3D border, use main bitmap only.
Without this option all specified bitmaps (selected, disabled, focus, hover) are used, no border is drawn. Default: auto-draw on.
left
top
right
bottom
Alignment of the bitmap in the button area. Default: Centered.

 
bitmap disabled = wxBitmap:bitmap
Optional bitmap to show when a wxBitmapButton is disabled.
 
bitmap focus = wxBitmap:bitmap
Optional bitmap to show when a wxBitmapButton has focus.
 
bitmap hover = wxBitmap:bitmap
Optional bitmap to show when the mouse is moved over a wxBitmapButton.
 
bitmap selected = wxBitmap:bitmap
Optional bitmap to show when a wxBitmapButton is pushed.
 
border = integer   [all  |  ( [top] [bottom] [left] [right] ) ]
Optional border (additional space) around an object, number of pixels. Optionally followed by the names of the borders where to apply additional space:
 
Border keywords
KeywordMeaning
left
top
right
bottom
Specify one border.
all Apply additional space to all borders (default).

 
button style =   [fit]   [noborder]   [top | bottom]   [left | right]
Optional style for wxButton objects.
The list can contain the following keywords:
 
Keywords for button style
KeywordMeaning
fit Use just the space needed instead of the default size.
no-border Don't draw the usual button border.
left
top
right
bottom
Alignment of the label in the button area. Default: Centered.

 
cell data = int:row   int:column   wxString:string
Data for the grid cell in the specified row and column.
 
choices = int:size   wxString[]:choices
choices = wxArrayString:choices
Choices for wxChoice, wxComboBox, wxListBox, and wxCheckListBox.
The number of choices must be specified and a C expression evaluating to const wxString[].
Alternatively a wxArrayString expression can be used without a number specification.
 
column head = wxString:text
Column head for a wxGrid column. Multiple column head settings can be used for multiple columns in a wxGrid.
 
columns = int:number
Number of columns in a wxRadioBox or wxGrid.
For each wxRadioBox you must specify either the maximum number of rows or columns.
For a wxGrid we must either specify a table object or the number of rows and columns.
 
complete constructor specified = boolean:complete
Boolean flag to specify whether the constructor attribute contains all constructor arguments.
If this attribute is set to false, the parent window and the window id (default: wxID_ANY) are inserted before the other arguments.
 
constructor = list
List of arguments to be used as constructor arguments for an object.
Note: If the "complete constructor specified" option above is not used, the parent wxWindow and the window ID are inserted before the arguments specified here.
 
contents = object:obj   int:row   int:col   int:rows   int:columns   [top | centered-y | bottom]   [left | centered-x | right]
contents = object:obj   [top | centered-y | bottom]   [left | centered-x | right]
Object to add into a container object.
The first version is used to add objects to a wxGridBagSizer, the second version for all other sizers.
The placement for wxGridBagSizer objects consists of four numbers: start row, start column, row span, and column span.
The alignment list can contain the following keywords:
 
Contents keywords
KeywordMeaning
left
top
right
bottom
centered-x
centered-y
Alignment of the object within the available space. Default: Centered.

 
Note: The alignment specified here decides about the alignment of the object in the available space.
Use "text style =" to specify the alignment of the label text in the space occupied by a wxStaticText or wxTextCtrl object.
 
direction = horizontal | vertical
Direction for a wxBoxSizer, wxGauge, and wxSlider:
 
Direction for wxBoxSizer
KeywordMeaning
horizontal Horizontal box.
vertical Vertical box.

 
expand = boolean:expand
Optional flag whether the object should expand when the container expands.
 
gauge style = smooth
Optional style for a gauge:
 
Gauge style keywords
KeywordMeaning
smooth Bar increases pixel by pixel.

 
grid = int:ygap   int:xgap
grid = int:rows   int:columns   int:ygap   int:xgap
Grid settings for a wxGridBagSizer (first version: y gap and x gap) or wxGridSizer and wxFlexGridSizer (second version: number of rows, number of columns, y gap, x gap).
 
grid style = [autosize-data]   [autosize-labels | autosize-labels-rows | autosize-labels-columns]
Style settings for a wxGrid:
 
Style keywords for a wxGrid
KeywordMeaning
autosize-data Automatically size data cells.
autosize-labels Combination of autosize-labels-rows and autosize-labels-columns (see below).
autosize-labels-rows Automatically size row labels.
autosize-labels-columns Automatically size column labels.

 
grow = boolean:expand
Equivalent to expand=.
 
growable column = int:index
Insert a growable column before the column specified by index in a wxGridBagSizer. Multiple occurances are allowed.
 
growable row = int:index
Insert a growable row before the row specified by index in a wxGridBagSizer. Multiplice occurances are allowed.
 
icon = wxIcon:expression
Icon for top level windows.
 
id = int:id
Window ID for object. This attribute should be set for all objects triggering events.
 
keys = boolean:showkeys
Flag to indicate whether the keyboard can be used to modify a wxSpinButton or wxSpinControl.
 
menu bar = wxMenuBar:mb
Optional menu bar object for a top level window.
 
menu item style = normal | check | radio | separator
Optional style for a wxMenuItem:
 
Menu item style
KeywordMeaning
normal Normal menu item (default).
check Checkbox menu item.
radio Radio button menu item.
separator Separator in a menu.

 
minimum pane size = int:size
Optional minimum pane size of a pane in a wxSplitterWindow.
 
minimum size = int:width   int:height
Minimum size (width and height).
 
notebook style = [fixed-width]   [multiline]   [no-theme]   [flat]   [top | bottom]   [left | right]
Optional style for wxNoteBook:
 
Notebook style keywords
KeywordMeaning
fixed-width All buttons have the same width (Windows only).
multiline Multiple lines allowed for buttons (Windows only).
no-theme Display solid background instead of a gradient (Windows only).
flat Tabs are shown in a flat style (Windows CE only).
top
left
right
bottom
Position of the tabs relative to contents, choose one.

 
proportion = int:factor
Optional proportion for the element to grow when the container grows. The additional space available when growing the container is distributed to container content elements proportionally to the value specified here.
 
range = int:min   int:max
range = int:max
Range for wxSpinButton, wxSpinControl, wxSlider (first version: minimum and maximum) and wxGauge (second version: maximum, minimum is 0).
 
row head = wxString:text
Row head specification for a wxGrid row. Multiple row head entries can occur for a wxGrid.
 
rows = int:numrows
Maximum number of rows in a wxRadioBox or wxGrid.
For each wxRadioBox you must specify either the maximum number of rows or columns.
For a wxGrid you must either specify a table object or the number of rows and columns. If the number of rows or columns is missing the number of column or row heads is used.
 
sash = int:size
Size of wxSplitterWindow children. Positive values are the size of the first (upper or left) child, negative values specify the size of the second (lower or right) child. The default 0 assigns equal size two both children.
 
selection = single | multiple | extended
Selection style for wxListBox and wxCheckListBox:
 
Selection style for list box and check list box
KeywordMeaning
single Select one single item.
multiple Select multiple items.
extended Select multiple items, use shift key and mouse or special keys.

 
size = int:width   int:height
Default size for an object, width and height.
 
slider style = [ticks]   [labels]   [range]   [inverse]   [top | bottom]   [left | right]
Style for a wxSlider:
 
Slider style keywords
KeywordMeaning
ticks Display tick marks.
labels Show minimum, maximum, and current value.
range Allow selection of a range (Windows only).
inverse Inverse minimum and maximum endpoint. Incompatible with "range".
left
top
right
bottom
Label placement beside the slider (choose one).

 
splitter window style = [3d | 3d-sash | 3d-border]   [border | no-border]   [no-xp-theme]   [permit-unsplit]   [live-update]
Optional style for a wxSplitterWindow:
 
Splitter window style keywords
KeywordMeaning
3d 3D effect for border and sash.
3d-sash 3D effect for sash.
3d-border 3D effect for border.
border Standard border.
no-border No border.
no-xp-theme Do not use a Windows XP theme.
permit-unsplit Permit to unsplit the window.
live-update On dragging sash immediately update the window and the children instead of showing a rubber band.

 
start group = boolean:start
Flag to indicate that a wxRadioButton is the start of a new radio button group. Default: no.
 
states = int:states   [checked | unchecked | undetermined]
The number of states (2 or 3) and the initial state for a wxCheckBox:
 
Checkbox states
KeywordMeaning
checked Checkbox activated.
unchecked Checkbox deactivated.
undetermined Option can not be set at this time due to settings made somewhere else. Only for 3-state checkboxes.

 
status bar =int:parts   [wxString:text]
Optional status bar for top level windows. The number of status bar parts is specified here and the text for the first status bar part.
 
status text = wxString:text
Optional status text for top level windows.
 
table = object:obj   [boolean:owner]
Table object for a wxGrid. The optional boolean specifies whether the wxGrid will become the owner of the table object (Default: no).
 
text = wxString:text
Text for various elements. For top level windows this is the title text for other elements the text to show.
 
text style = [multiline]   [enter]   [tab]   [multiline]   [password]   [rich | rich2]   [url]   [selection]   [left | centered | right]   [no-wrap | char-wrap | word-wrap | best-wrap]   [capitalize]   [no-autoresize]
Style for a wxTextCtrl, wxStaticText, or wxGrid object:
 
Text style keywords
KeywordMeaning
readonly Text can not be edited.
enter Pressing enter key adds a linebreak. Without this option the enter key is used for navigation (text input completed).
For wxTextCtrl only.
tab Pressing the tabulator key adds a tabulator. Without this option the tabulator key is used for navigation (go to next control).
For wxTextCtrl only.
multiline Text can consist of multiple lines.
For wxTextCtrl only.
password Text control is used to enter a password, show asterisks as keyboard echo.
For wxTextCtrl only.
rich
rich2
Use rich text control on Windows, rich2 uses a newer version.
For wxTextCtrl only.
url Highlight URLs (only in rich text controls on Windows and in wxGTK multiline controls).
For wxTextCtrl only.
selection Show selection even if the text control does not have the focus.
For wxTextCtrl only.
left
centered
right
Text justification, choose one.
no-wrap Do not wrap long lines, show a scrollbar instead.
For wxTextCtrl only.
char-wrap Wrap long lines at any position.
For wxTextCtrl only.
word-wrap Wrap long lines at word boundaries.
For wxTextCtrl only.
best-wrap Find best position for line wrapping.
For wxTextCtrl only.
capitalize Capitalize first letter, only PocketPC and Smartphone.
For wxTextCtrl only.
no-autoresize Do not automatically resize object.
For wxStaticText only.

 
For wxGrid object only the readonly setting can be used.
 
Note: The aligment specified here is the alignment of the text label in the space occupied by the object.
To specify the alignment of the object in the available space use alignment keywords in the "contents =" attribute.

 
tip = wxString:text
Tip text, either shown as tool tip or in the status line (for menu items and tool bar elements).
 
tool bar = wxToolbar:tb
Optional tool bar object for a top level window.
 
toolbar button style = normal | check | radio | separator
Optional style for a toolbar button:
 
Toolbar button style
KeywordMeaning
normal Normal button (default).
check Checkbox.
radio Radio button.
separator Separator.

 
toolbar style = [flat]   [dockable]   [text]   [no-icons]   [no-divider]   [horizontal-layout]   [no-tooltips]   [right]   [bottom]
Optional style for wxToolBar:
 
Tool bar style keywords
KeywordMeaning
flat Flat look for toolbar (Windows and GTK).
dockable Toolbar floatable and dockable (GTK only).
text Show button text (by default only icons are shown).
no-icons Do not show icons.
no-divider No divider (border) around toolbar.
horizontal-layout Text is shown beside the image on Windows and GTK2, must be used together with "text").
no-tooltips Do not show tool tips.
right
bottom
Border where to place the tool bar (choose one).

 
tooltip flag = boolean:show
Boolean expression to control whether or not to show tool tips. Can be used on individual GUI elements or on an entire frame or dialog box.
 
type = frame | dialog
Type of top level window:
 
Top level windows types
KeywordMeaning
dialog Top level window is derived from wxDialog. No wxPanel for contents is needed.
frame Top level window is not derived from wxDialog. A wxPanel object is needed.

 
validator = wxValidator:obj
Optional validator object for control. Validator objects can be used for event validation and for data exchange between GUI component and class member variable.
 
value = int:value
Initial value for wxSpinButton, wxSpinControl, wxSlider and wxGauge.
 
wrap = boolean:wrap
Flag to allow wxSpinButton and wxSpinControl to wrap.
 

Depending on the object class there are required, recommended, and optional attributes for each object:

 
wxFrame
type = frame Top level window type.
contents Window contents.
For top level windows it is recommended to have one sizer object as contents.
icon Icon, a wxIcon object.
menu bar Menu bar object.
text Title text.
tool bar Tool bar object.
status bar Status bar for top level windows.
status text Initial text for status bar.
id Window ID, should be set for all objects triggering events.
status bar Status bar object.
status text Initial text for status bar.
tooltip flag Flag to allow or deny tooltips.
size Size (width and height).
 
wxDialog
type = dialog Top level window type.
contents Window contents.
For top level windows it is recommended to have one sizer object as contents.
text Title text.
id Window ID, should be set for all objects triggering events.
icon Icon, a wxIcon object.
status bar Status bar for top level windows.
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxMDIParentFrame
type = frame Top level window type.
contents Window contents, the wxMDIChildFrame objects.
menu bar Menu bar object.
tool bar Tool bar object.
status bar Status bar for top level windows.
text Title text.
icon Icon, a wxIcon object.
id Window ID, should be set for all objects triggering events.
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxMDIChildFrame
type = frame Top level window type.
contents Window contents.
For top level windows it is recommended to have one sizer object as contents.
text Title text.
id Window ID, should be set for all objects triggering events.
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxPopupWindow
contents Window contents.
For top level windows it is recommended to have one sizer object as contents.
text Title text.
id Window ID, should be set for all objects triggering events.
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxBoxSizer
direction Direction in which to align objects.
contents Window contents.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
 
wxFlexGridSizer
grid Number of rows, number of columns, row gap, column gap.
contents Window contents.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
 
wxGridBagSizer
contents Window contents.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
grid Row gap, column gap.
border Additional border (number of pixels).
growable column Index of a growable column, may occur multiple times.
growable row Index of a growable row, may occur multiple times.
 
wxGridSizer
grid Number of rows, number of columns, row gap, column gap.
contents Window contents.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
 
wxStaticBoxSizer
direction Direction in which to align objects.
contents Window contents.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
 
wxStdDialogButtonSizer
contents Window contents, wxButton objects with standard IDs only.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
 
wxPanel
contents Window contents.
For top level windows it is recommended to have one sizer object as contents.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
size Size (width and height).
 
wxNotebook
contents The wxPanel objects for the notebook.
notebook style Style information specific for a wxNotebook.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
size Size (width and height).
 
wxScrolledWindow
contents A wxPanel object.
direction Directions for scrollbars.
size Size (width and height).
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
 
wxSplitterWindow
contents The wxPanel objects for the 2 subwindows.
splitter window style Style information specific to splitter windows.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
sash Initial size of the sub panels.
border Additional border (number of pixels).
minimum pane size Minimum pane size for sub panels.
id Window ID, should be set for all objects triggering events.
size Size (width and height).
 
wxButton
text Text label for button.
id Window ID, should be set for all objects triggering events.
tip Tool tip text.
button style Style for button.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxBitmapButton
text Text label for button.
id Window ID, should be set for all objects triggering events.
bitmap Bitmap for button.
tip Tool tip text.
bitmap selected Bitmap to use if button is pushed (mouse button is pressed down).
bitmap disabled Bitmap to use if button is disabled.
bitmap focus Bitmap to use if button gets focus.
bitmap hover Bitmap to use if mouse is moved over button.
bitmap button style Style for bitmap button.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxChoice
choices Texts to show in choice list.
tip Tool tip text.
id Window ID, should be set for all objects triggering events.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxComboBox
choices Texts to show in choice list.
tip Tool tip text.
id Window ID, should be set for all objects triggering events.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxCheckBox
text Text label for checkbox.
tip Tool tip text.
states Number of states for the checkbox. May be 2 (on/off) or 3 (on/off/undetermined).
id Window ID, should be set for all objects triggering events.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxListBox
choices Texts to show in choice list.
tip Tool tip text.
size Size (width and height).
id Window ID, should be set for all objects triggering events.
range Selection style (single/multiple/extended)
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
tooltip flag Flag to allow or deny tooltips.
 
wxCheckListBox
choices Texts to show in choice list.
tip Tool tip text.
size Size (width and height).
id Window ID, should be set for all objects triggering events.
range Selection style (single/multiple/extended)
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
tooltip flag Flag to allow or deny tooltips.
 
wxRadioBox
columns Maximum number of columns to organize the radio buttons.
rows Maximum number of rows to organize the radio buttons.
For each radio button box we must specify either columns or rows.
tip Tool tip text.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
size Size (width and height).
 
wxRadioButton
text Text label for button.
id Window ID, should be set for all objects triggering events.
start group Mark a radio button starting a new radio button group.
tip Tool tip text.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxScrollBar
id Window ID, should be set for all objects triggering events.
direction Direction, either "horizontal" or "vertical".
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tip Tool tip text.
 
wxSpinButton
text Text label for button.
range Numeric range for spin button.
value Initial value.
direction Horizontal or vertical spin button.
keys Allow or deny keyboard use for this widget.
tip Tool tip text.
wrap Enable/disable wrapping.
id Window ID, should be set for all objects triggering events.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
 
wxSpinCtrl
text Text label.
range Numeric range for spin control.
value Initial value.
direction Vertical or horizontal spin control.
keys Allow or deny keyboard use for this widget.
tip Tool tip text.
wrap Enable/disable wrapping.
id Window ID, should be set for all objects triggering events.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxSlider
text Text label.
range Numeric range for slider.
value Initial value.
tip Tool tip text.
id Window ID, should be set for all objects triggering events.
slider style Style information specific to sliders.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxTextCtrl
text Initial text.
text style Text style and alignment.
tip Tool tip text.
size Size (width and height).
Setting the size is especially recommended for multiline text controls and for single line controls without initial text.
id Window ID, should be set for all objects triggering events.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
tooltip flag Flag to allow or deny tooltips.
 
wxGrid
table Table object for the wxGrid.
rows
columns
Number of rows and columns. Specify either a table object or the number of rows and columns.
row head
column head
Headers for rows and columns of the wxGrid.
cell data Data for a grid cell.
grid style Grid style
text style Text style (only the readonly setting).
 
wxToggleButton
text Text label for button.
tip Tool tip text.
id Window ID, should be set for all objects triggering events.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
tooltip flag Flag to allow or deny tooltips.
 
wxGauge
range Maximum of gauge range (minimum is always 0).
value Initial value.
direction Horizontal or vertical gauge.
text Text label.
tip Tool tip text.
id Window ID, should be set for all objects triggering events.
gauge style Style information specific for a gauge.
validator Validator object.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
size Size (width and height).
 
wxStaticText
text Text label.
text style Text style and alignment.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
size Size (width and height).
tip Tool tip text.
 
wxStaticBitmap
bitmap Bitmap to show.
bitmap button style Style for bitmap button.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
size Size (width and height).
tip Tool tip text.
 
wxStaticLine
direction Horizontal or vertical line.
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
size Size (width and height).
tip Tool tip text.
 
wxStaticBox
grow Allow object to grow when container grows.
proportion If a container grows, the additional space is assigned to children proportional to the value specified here.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
size Size (width and height).
tip Tool tip text.
 
wxMenuBar
contents The wxMenu objects used in the menu bar.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
tip Tool tip text.
 
wxMenu
text Menu name.
contents The wxMenuItem and wxMenu objects used in the menu.
tip Help text shown in the status bar.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
 
wxMenuItem
text Text label for menu item.
id Window ID, should be set for all objects triggering events.
tip Help text shown in the status bar.
bitmap Bitmap for menu item.
menu item style Style information specific for menu item or toolbar buttons.
border Additional border (number of pixels).
 
wxToolBar
contents The wxToolBarToolBase objects for the buttons.
tool bar style Style information specific for tool bars.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
tip Tool tip text.
 
wxStatusBar
contents Contents of the status bar.
border Additional border (number of pixels).
id Window ID, should be set for all objects triggering events.
tip Tool tip text.
 
wxToolBarToolBase
id Window ID, should be set for all objects triggering events.
bitmap Toolbar button icon.
tip Tool tip text.
bitmap disabled Bitmap to use if button is disabled.
bitmap button style Style for bitmap button.
toolbar button style Style information specific for menu item or toolbar buttons.
border Additional border (number of pixels).
 
any class not listed above (including self-made canvas classes)
id Window ID, should be set for all objects triggering events.
text Label text.
size Size (width and height).
minimum size Minimum size (width and height).
tip Tool tip text.

Pseudo objects

The following pseudo objects can be used:

Name Purpose
$space(width[,height]) Placeholder for space between elements, can be added to sizers. If the height is not specified, the same value as for width is used.
$stretch(width[,height]) Placeholder for space between elements, can be added to sizers. If the height is not specified, the same value as for width is used.
Stretchers grow when enlarging the frame/dialog/sizer, spaces don't.
$separator Separator between menu items.

Create your own controls

A control is used for customized drawing. Typically these classes respond to paint events and input events.

Class declaration

Derive your class from either wxControl

class MyCanvasClass : public wxControl
{
  /* ... other stuff ... */

  public:
    myCanvasClass(
      wxWindow          *parent,
      wxWindowID         wid        = wxID_ANY,
      const wxPoint &    pos        = wxDefaultPosition,
      const wxSize &     size       = wxDefaultSize,
      long               style      = 0L
    );
};

or DkWxBufferedControl

class MyCanvasClass : public DkWxBufferedControl
{
  /* ... other stuff ... */

  public
    MyCanvasClass(
      wxWindow          *parent,
      wxWindowID         wid        = wxID_ANY,
      const wxPoint &    pos        = wxDefaultPosition,
      const wxSize &     size       = wxDefaultSize,
      long               style      = 0L
    );
};

In both cases the parent argument is required in the constructor.

Class implementation

Depending on the base class use either

static wxChar const MyCanvasClass_name[] = { wxT("MyCanvasClass") };

MyCanvasClass::MyCanvasClass(
  wxWindow            *parent,
  wxWindowID           wid,
  const wxPoint &      pos,
  const wxSize &       size,
  long                 style
) : wxControl(parent, wid, pos, size, style, MyCanvasClass_name)
{
  /* ... other setup ... */
}

or

static wxChar const MyCanvasClass_name[] = { wxT("MyCanvasClass") };

MyCanvasClass::MyCanvasClass(
  wxWindow            *parent,
  wxWindowID           wid,
  const wxPoint &      pos,
  const wxSize &       size,
  long                 style
) : DkWxBufferedControl(parent, wid, pos, size, style, MyCanvasClass_name)
{
  /* ... other setup ... */
}

Use control features in the implementation

As /SHC2006/ recommends, you should use DECLARE_DYNAMIC_CLASS in the class declaration, IMPLEMENT_DYNAMIC_CLASS in the implementation file. The class should have a default constructor (without any arguments) and a Create() function. Optionally you can provide a DoGetBestSize() method, this is recommended if you don't specify a size or minimum size in the wx-gui section.

Class usage in wx-gui section

[MyCanvasClass myObj]
id              =       wxID_ANY

Notes

This program uses DK libraries version 3.


FAQ

How do I add trace messages?

#include <stdio.h>
#include <stdlib.h>

$!trace-include

double
square_area(double sidelength)
{
  double    result;
  $? "+ square_area %lg", sidelength
  result = sidelength * sidelength;
  $? "- square_area %lg", result
  return result;
}


static const double sidelengths[] = {
  1.0, 2.3, 4.5, 6.7
};


static const
size_t  sz_sidelengths = sizeof(sidelengths)/sizeof(double);

int main(int argc, char *argv[])
{
  char      *language   = NULL;
  int        exitcode   = 1;
  size_t     i;

  $!trace-init tdkct.deb
  $? "+ main"
  language = getenv("LANG");    /* May be NULL! */
  $? ". languange = \"%!8s\"", TR_8STR(language)
  for (i = 0; i < sz_sidelengths; i++) {
    $? ". i = %u", (unsigned)i
    $? ". s = %lg", sidelengths[i]
    printf(
      "Length: %lg   Area: %lg\n",
      sidelengths[i],
      square_area(sidelengths[i])
    );
  }
  $? "- main %d", exitcode
  $!trace-end
  exit(exitcode);
}
  • Use
    $!trace-include
    
    after all other include files.
     
  • Use
    $!trace-init filename
    
    at the start of the main program.
    This instruction starts tracing. For tracing to file you can specify the file name here.
     
  • Use
    $!trace-end
    
    at the end of the main program.
    This instruction stops tracing and closes the output file.
     
  • Use
    $? formatstring arguments
    
    to produce a trace message. Format string and arguments are passed to a fprintf() or printf() call.
    Trace messages for entering a function should have a ``+'' as first character, trace messages for returning from a function should have ``-'' as first character.
    Normal trace messages should have ``.'' as first character. Errors and warnings should have ``!'' as first character.
     
  • Use the following special placeholders in $? format strings:
     
    Placeholder Purpose
    %!8c Single char character
    %!8s String pointer (char string)
    %!dc Single dkChar character
    %!ds String pointer (dkChar string)
    %!wc Single wxChar
    %!ws String pointer (wxChar string)

     
    For wchar_t characters and strings use %lc and %ls as usual.
     
  • Use the following macros for string pointers to prevent NULL pointer access:
     
    Macro Pointer type
    TR_8STR() char
    TR_LSTR() wchar_t
    TR_DKSTR() dkChar
    TR_WXSTR() wxChar

     
  • Use either the libdk4c.so (libdk4c.a) library or the libdk3trace.so (libdk3trace.a) library.

How do I build a release version without trace messages?

Run

dkcpre -l tdkct.ctr

to create tdkct.c for a release.

To create *.c files for a release from all *.ctr files in the current directory:

dkcpre -l

How do I build a debug version showing trace messages?

For one file:

dkcpre -l -d tdkct.ctr

For all *.ctr files in the current directory:

dkcpre -l -d

How do I build a debug version for Windows?

For one file:

dkcpre -l -d -w tdkct.ctr

For all *.ctr files in the current directory:

dkcpre -l -d -w

How can I prepare a debug version I want to compile on another computer?

For one file:

dkcpre -l -d -p tdkct.ctr

For all *.ctr files in the current directory:

dkcpre -l -d -p

Can I use tracing in multithreaded programs?

No, tracing uses FILE * operations which are not thread-safe. You have two choices:

  • Do not use any trace instruction in code executed in parallel.
    You can use trace instructions before spawning the worker threads and after waiting for thread execution.
  • Use trace instructions in all your code. You must avoid multithreaded execution, see next question how to do so.

How do I avoid multithreaded code when tracing?

Use a code structure like this:

size_t           maxthreads;
dk3_app_t       *app;
int              threadnumbersource = 0;

...


/*
        Find number of threads to run, i.e. by using
        the dk3cores_max_threads() function or any other
        method you like.
*/
/* ... initialize app ... */
maxthreads = dk3cores_max_threads(app, &threadnumbersource);

/*
        Portable code should be prepared for both Windows systems
        and systems providing the POSIX threads mechanism and probably
        other thread libraries.
        If you want to use multiple threads (maxthreads > 1)
        you have to check that TRACE_DEBUG is not active as the
        trace functions use FILE * I/O operations which are not 
        thread-safe.
*/
if(maxthreads > 1) {
#if     (!TRACE_DEBUG) && DK3_ON_WINDOWS
  /*
        Windows threads.
  */
#elif   (!TRACE_DEBUG) && DK3_HAVE_PTHREAD_H
  /*
        Run with POSIX threads.
  */
#else
  /*
        Run without threads.
  */
#endif
} else {
  /*
        Run without threads.
  */
}

How do I use dkChar or wxChar in trace output?

Use the special placeholders (only allowed in $? trace messages):

Placeholder Purpose
%!8c 8 bit character
%!dc dkChar character
%!wc wxChar character
%!8s 8 bit string
%!ds dkChar string
%!ws wxChar string

Example:

char          *c8ptr;
dkChar        *dkptr;
wxChar        *wxptr;
... set the pointers ...
$? ". c8 string = \"%!8s\"", c8ptr
$? ". dk string = \"%!ds\"", dkptr
$? ". wx string = \"%!ws\"", wxptr

or better (checking for NULL pointers):

char          *c8ptr;
dkChar        *dkptr;
wxChar        *wxptr;
... set the pointers ...
$? ". c8 string = \"%!8s\"", TR_8STR(c8ptr)
$? ". dk string = \"%!ds\"", TR_STR(dkptr)
$? ". wx string = \"%!ws\"", TR_WXSTR(wxptr)

How do I create string table and help text file templates

If you use the dk4app module in your own programs you will grant the users to localize the software to other languages. So users have to create new *.str string table files and *.txt help files.
If you provide english versions of these files this process becomes easier. You can use the string table syntax in $!string-table…$!end environments and write text directly in $!text…$!end environments.

Instead of code like

static dkChar const * const mytexts[] = {
dkT("Hello world"),
dkT("Goodbye world"),
dkT("This is a"),
dkT(" simple message consisting"),
dkT(" of multiple parts"),
NULL
};

you should better write a *.ctr file and use code like this:

static dkChar const * const mytexts[] = {
$!string-table file=myprog.str,macro=dkT
#
#  0: Greeting text to say hello
#
Hello world
#
#  1: Greeting text to say goodbye
#
Goodbye world
#
#  2/3/4: Multipart message for demonstration
#
This is a
 simple message consisting
 of multiple parts
$!end
};

In the comments (started by '#') you should show the index number(s) and the purpose of each text.

For a help text you can use $!text…$!end:

/**     Help text shown if no help file is found.
*/
static dkChar const * const bmeps3_default_help_text[] = {
$!text  file=myprog.txt,macro=dkT

myprog - My hot program to do this and that
===========================================

Usage
-----
myprog <option> <arguments>

To do this and that with the arguments, run the program as
shown above. There are some options available.
...
$!end
};

You can use preprocessor directives in help texts, they are transferred to the C source code literally. In the $!text line, specify the "preprocessor" argument. Unfortunately you should not provide a file=… argument in such cases:

/**     Help text shown if no help file is found.
*/
static dkChar const * const bmeps3_default_help_text[] = {
$!text  macro=dkT,preprocessor

myprog - My hot program to do this and that
===========================================

Usage
-----
myprog <option> <arguments>

To do this and that with the arguments, run the program as
shown above. There are some options available.
...
#if HAVE_HOT_FEATURE
The hot feature is available here, enjoy to use it.
#else
This version of the program was compiled without the hot feature.
#endif
$!end
};

If you need a text line started by "#", escape the "#" in column 0 with a backslash:

/**     Help text shown if no help file is found.
*/
static dkChar const * const bmeps3_default_help_text[] = {
$!text  macro=dkT,preprocessor

myprog - My hot program to do this and that
===========================================

Usage
-----
myprog <option> <arguments>

To do this and that with the arguments, run the program as
shown above. There are some options available.
...
We need a line started by a # character:
\# This line was started by #.
#if HAVE_HOT_FEATURE
The hot feature is available here, enjoy to use it.
#else
This version of the program was compiled without the hot feature.
#endif
$!end
};

How do I create a state machine?

In the example we want to write a program to test all input lines whether the text in the line is a valid identifier (variable or function name) for the C programming language.
This means the text consists of a starting underscore or character and an optional sequence of underscores, digits, and characters.

General program structure

The main() function reads input line by line and calls the test_identifier() function to check if the line text is an identifier.

The test_identifier() function uses a state machine. First each input char is classified resulting in one of the following constants:

Input name Indicates
I_CHAR Character "a" to "z" or "A" to "Z"
I_DIGIT Digit "0" to "9"
I_UNDER Underscore "_"
I_END End of input
I_ANY Any other input byte

The state machine has three states:

State name Indicates
S_START No input yet
S_OK Input already received is an identifier
S_ERROR Input already received is not an identifier

When processing an input the state machine searches all rules for the matching (state;input) combination to find the next state and an output.
The following outputs can occur:

Output name Indicates
O_OK The input processed (including the current character) is a C identifier.
O_ERROR Not an identifier.

State machine to recognize identifier

From the S_START state we go to the S_OK state if an underscore or character is found. We stay in the S_OK state as long as the input is an underscore, character or digit.
If end of input is found while we are in state S_OK we go back to S_START and produce output O_OK.
For all other states we go to S_START and produce output O_ERROR if end of input is found.
For all (state;input) combinations not covered by the rules above we go to state S_ERROR and produce output O_ERROR.

The test-ident.ctr file

%%      options

copyright owner =       Dirk Krause
copyright year  =       2011-2015
license         =       bsd



%%      header

$*
Function prototypes
$*


#ifdef __cplusplus
extern "C" {
#endif

/**     Test whether a string is an identifier.
        @param  test    String to check.
        @return 1 on success (string is identifier), 0 on error.
*/
int test_identifier(char const *text);

#ifdef __cplusplus
}
#endif



%%      module

/*  This program uses functions from the dk4str8.o module.
    So you should use -ldk4base when linking.
*/

#include <dk4conf.h>
#include <dk4types.h>
#include <stdio.h>
#include <stdlib.h>
#if DK3_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <dk4str8.h>

$!trace-include

/**     Help text, never used, just for demonstration.
*/
static char const * const help_text1[] = {
$!text preprocessor
This help text is never shown, it is here just to demonstrate the
use of the build-in $!text function.
#ifdef _WIN32
We are on a Windows system.
#else
We are not on a Windows system.
#endif
$!end
};

/**     Help text, never used, just for demonstration.
*/
static char const * const help_text2[] = {
$!text
This help text is never shown, it is here just to demonstrate the
use of the build-in $!text function.
#Lines with raute are converted to text when the preprocessor
option was not used.
$!end
};

/**     Help text, never used, just for demonstration.
*/
static dkChar const * const help_text3[] = {
$!text macro=dkT
This help text is never shown, it is here just to demonstrate the
use of the macro functionality in the build-in $!text function.
$!end
};

/**     Help text, never used, just for demonstration.
*/
static wchar_t const * const help_text4[] = {
$!text prefix=L
This help text is never shown, it is here just to demonstrate the
use of the prefix functionality in the build-in $!text function.
$!end
};

/**     Find start of text (first non-whitespace).
        @param  t       String to test.
        @return Pointer to start of text or NULL.
*/
static
char *
str_start(char *t)
{
  char *back = NULL;
  char *ptr;
  ptr = t;
  while((*ptr) && (back == NULL)) {
    if(*ptr != ' ') {
      if(*ptr != '\t') {
        back = ptr;
      }
    }
    ptr++;
  }
  return back;
}

/**     Remove trailing newline.
        @param  t       String to modify.
*/
static
void
str_delnl(char *t)
{
  char *ptr;
  ptr = t;
  while(*ptr) {
    if(*ptr == '\r') *ptr = '\0';
    if(*ptr == '\n') *ptr = '\0';
    ptr++;
  }
}

int test_identifier(char const *text)
{
  int back = 0;
  char const    *ptr;
  int           state;
  int           i;
  $? "+ test_identifier \"%s\"", TR_STR(text)
  idtest_reset(&state);
  ptr = text;
  while(*ptr) {         $? ". processing character %c", *ptr
    if((*ptr >= 'A') && (*ptr <= 'Z')) {
      i = I_CHAR;
    } else {
      if((*ptr >= 'a') && (*ptr <= 'z')) {
        i = I_CHAR;
      } else {
        if((*ptr >= '0') && (*ptr <= '9')) {
          i = I_DIGIT;
        } else {
          if(*ptr == '_') {
            i = I_UNDER;
          } else {
            i = I_ANY;
          }
        }
      }
    }
    (void)idtest_step(&state, i);
    ptr++;
  }
  if(idtest_step(&state, I_END) == O_OK) {
    back = 1;
  } $? "- test_identifier %d", back
  return back;
}

/**     Main function.
        @param  argc    Number of command line arguments.
        @param  argv    Command line arguments array.
*/
int main(int argc, char *argv[])
{
  char  buffer[1024];
  char  *p1;
  int   cc;

  /* Debug output goes to test-ident.deb in the current directory */
  $!trace-init test-ident.deb
  /* We are entering the main function */
  $? "+ main"
  do {          $? ". start of loop"
    cc = 0;
    if(fgets(buffer, sizeof(buffer), stdin)) {
      p1 = dk4str8_start(buffer, NULL);
      if(p1) {  $? ". text found \"%s\"", p1
        cc = 1;
        dk4str_delnl(p1);
        printf("%s %d\n", p1, test_identifier(p1));
      }
    }
  } while(cc);
  /* We are about to leave the main function */
  $? "- main"
  /* Close debug output file */
  $!trace-end
  exit(0); return 0;
}



%%      state machine

[options]
name            =       idtest
write header    =       no

[states]
S_START         # No character found yet.
S_OK            # Everything ok so far.
S_ERROR         # An error occured.

[inputs]
I_CHAR          # Character.
I_UNDER         # Underscore.
I_DIGIT         # Digit.
I_ANY           # Any other input character.
I_END           # End of input.

[outputs]
O_ERROR         # Error occured.
O_OK            # Everything ok so far.

[rules]
*               *               S_ERROR         O_ERROR
*               I_END           S_START         O_ERROR
S_START         I_CHAR          S_OK            O_OK
S_START         I_UNDER         S_OK            O_OK
S_OK            I_CHAR          S_OK            O_OK
S_OK            I_UNDER         S_OK            O_OK
S_OK            I_DIGIT         S_OK            O_OK
S_OK            I_END           S_START         O_OK
  • In the options section the name of the copyright owner, the copyright years and the license is set.
     
  • The header section is not necessary here, I just added it to show how a resulting *.h file looks like.
     
  • In the header file we want a comment box for the text "Function prototypes" and the prototype for the test_identifier(char const *text); function. In the module section we have the main() function. Here we use "$!trace-init test-ident.deb" to set up debug output going to the "test-ident.deb" file. Before the program exits we use "$!trace-end" to end debugging.
     
  • For function invokations we use $? "+ function… to have function name and optionally function arguments in debug output. Before returning from functions we use $? "- function… to write the function return value to debug output.
     
  • In the test_identifier() function we have to decide about the text argument whether it is an identifier or not. First we reset the state machine using the idtest_reset() function. Later after classifying each input character we use idtest_step() to process one input token. Both functions are neither declared nor defined in the module. The "idtest" part of the name matches the "name=idtest" setting of the state machine section. Code for the two functions is generated automatically.
     
  • The "write header = no" setting for the state machine writes the constants for states, inputs and outputs the the module file instead of the header file.

Makefile rule

TESTIDENTOBJ=   test-ident.o dk3trace.o

test-ident:     $(TESTIDENTOBJ)
        $(LD) $(CFLAGS) $(LDFLAGS) -o test-ident $(TESTIDENTOBJ) -lm
        chmod 755 test-ident

Build and test the program (release mode)

dkcpre -l test-ident.ctr
make test-ident
./test-ident

Type some lines containing text to check.
For each text line you will see a response ending on 1 or 0 indicating whether or not the text is a valid C identifier.
The test-ident.c file looks like this:

/*
    WARNING: This file was generated by dkcpre.
    Changes you make here will be lost if dkcpre is run again!
    You should modify the original source and run dkcpre on it.
    Original source: test-ident.ctr
*/

/*
Copyright (C) 2011-2015, Dirk Krause

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above opyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used
  to endorse or promote products derived from this software without specific
  prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/** @file test-ident.c The test-ident module.
*/

/** @defgroup dkct_state_machine_idtest The idtest state machine. */
/**@{*/

#ifndef S_ERROR
/** State: An error occured. */
#line 209 "test-ident.ctr"
#define S_ERROR 0
#else
#line 209 "test-ident.ctr"
#error "Redefinition of S_ERROR"
#endif

#ifndef S_OK
/** State: Everything ok so far. */
#line 208 "test-ident.ctr"
#define S_OK 1
#else
#line 208 "test-ident.ctr"
#error "Redefinition of S_OK"
#endif

#ifndef S_START
/** State: No character found yet. */
#line 207 "test-ident.ctr"
#define S_START 2
#else
#line 207 "test-ident.ctr"
#error "Redefinition of S_START"
#endif

#ifndef I_ANY
/** State machine input: Any other input character. */
#line 215 "test-ident.ctr"
#define I_ANY 0
#else
#line 215 "test-ident.ctr"
#error "Redefinition of I_ANY"
#endif

#ifndef I_CHAR
/** State machine input: Character. */
#line 212 "test-ident.ctr"
#define I_CHAR 1
#else
#line 212 "test-ident.ctr"
#error "Redefinition of I_CHAR"
#endif

#ifndef I_DIGIT
/** State machine input: Digit. */
#line 214 "test-ident.ctr"
#define I_DIGIT 2
#else
#line 214 "test-ident.ctr"
#error "Redefinition of I_DIGIT"
#endif

#ifndef I_END
/** State machine input: End of input. */
#line 216 "test-ident.ctr"
#define I_END 3
#else
#line 216 "test-ident.ctr"
#error "Redefinition of I_END"
#endif

#ifndef I_UNDER
/** State machine input: Underscore. */
#line 213 "test-ident.ctr"
#define I_UNDER 4
#else
#line 213 "test-ident.ctr"
#error "Redefinition of I_UNDER"
#endif

#ifndef O_ERROR
/** State machine output: Error occured. */
#line 219 "test-ident.ctr"
#define O_ERROR 0
#else
#line 219 "test-ident.ctr"
#error "Redefinition of O_ERROR"
#endif

#ifndef O_OK
/** State machine output: Everything ok so far. */
#line 220 "test-ident.ctr"
#define O_OK 1
#else
#line 220 "test-ident.ctr"
#error "Redefinition of O_OK"
#endif

/**@}*/

/** Reset idtest state machine.
    @param  st  Pointer to state variable.
*/
static
void
idtest_reset(int *st)
{
  if(st) { *st = S_START; }
}

/** State machine idtest step.
    @param  st  Pointer to state variable.
    @param  in  Input.
    @return Transition output.
*/
static
int
idtest_step(int *st, int in)
{
  int back = O_ERROR;
  if(st) {
    int os;
    int nf = 1;
    int ns = S_ERROR;
    os = *st;
    switch(os) {
      case S_OK: {
        switch(in) {
          case I_CHAR: {
            ns = S_OK; back = O_OK; nf = 0;
          } break;
          case I_DIGIT: {
            ns = S_OK; back = O_OK; nf = 0;
          } break;
          case I_END: {
            ns = S_START; back = O_OK; nf = 0;
          } break;
          case I_UNDER: {
            ns = S_OK; back = O_OK; nf = 0;
          } break;
        }
      } break;
      case S_START: {
        switch(in) {
          case I_CHAR: {
            ns = S_OK; back = O_OK; nf = 0;
          } break;
          case I_UNDER: {
            ns = S_OK; back = O_OK; nf = 0;
          } break;
        }
      } break;
    }
    if(nf) {
      if(in == I_END) {
      ns = S_START; back = O_ERROR;
      } else {
      }
    }
    *st = ns;
  } else {
  }
  return back;
}


#line 33 "test-ident.ctr"

/*  This program uses functions from the dk4str8.o module.
    So you should use -ldk4base when linking.
*/

#include <dk4conf.h>
#include <dk4types.h>
#include <stdio.h>
#include <stdlib.h>
#if DK3_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <dk4str8.h>



#line 48 "test-ident.ctr"

/**     Help text, never used, just for demonstration.
*/
static char const * const help_text1[] = {
"This help text is never shown, it is here just to demonstrate the",
"use of the build-in $!text function.",
#ifdef _WIN32
"We are on a Windows system.",
#else
"We are not on a Windows system.",
#endif
NULL


#line 61 "test-ident.ctr"
};

/**     Help text, never used, just for demonstration.
*/
static char const * const help_text2[] = {
"This help text is never shown, it is here just to demonstrate the",
"use of the build-in $!text function.",
"#Lines with raute are converted to text when the preprocessor",
"option was not used.",
NULL


#line 72 "test-ident.ctr"
};

/**     Help text, never used, just for demonstration.
*/
static dkChar const * const help_text3[] = {
dkT("This help text is never shown, it is here just to demonstrate the"),
dkT("use of the macro functionality in the build-in $!text function."),
NULL


#line 81 "test-ident.ctr"
};

/**     Help text, never used, just for demonstration.
*/
static wchar_t const * const help_text4[] = {
L"This help text is never shown, it is here just to demonstrate the",
L"use of the prefix functionality in the build-in $!text function.",
NULL


#line 90 "test-ident.ctr"
};

/**     Find start of text (first non-whitespace).
        @param  t       String to test.
        @return Pointer to start of text or NULL.
*/
static
char *
str_start(char *t)
{
  char *back = NULL;
  char *ptr;
  ptr = t;
  while((*ptr) && (back == NULL)) {
    if(*ptr != ' ') {
      if(*ptr != '\t') {
        back = ptr;
      }
    }
    ptr++;
  }
  return back;
}

/**     Remove trailing newline.
        @param  t       String to modify.
*/
static
void
str_delnl(char *t)
{
  char *ptr;
  ptr = t;
  while(*ptr) {
    if(*ptr == '\r') *ptr = '\0';
    if(*ptr == '\n') *ptr = '\0';
    ptr++;
  }
}

int test_identifier(char const *text)
{
  int back = 0;
  char const    *ptr;
  int           state;
  int           i;


#line 137 "test-ident.ctr"
  idtest_reset(&state);
  ptr = text;
  while(*ptr) {         

#line 140 "test-ident.ctr"
    if((*ptr >= 'A') && (*ptr <= 'Z')) {
      i = I_CHAR;
    } else {
      if((*ptr >= 'a') && (*ptr <= 'z')) {
        i = I_CHAR;
      } else {
        if((*ptr >= '0') && (*ptr <= '9')) {
          i = I_DIGIT;
        } else {
          if(*ptr == '_') {
            i = I_UNDER;
          } else {
            i = I_ANY;
          }
        }
      }
    }
    (void)idtest_step(&state, i);
    ptr++;
  }
  if(idtest_step(&state, I_END) == O_OK) {
    back = 1;
  } 

#line 163 "test-ident.ctr"
  return back;
}

/**     Main function.
        @param  argc    Number of command line arguments.
        @param  argv    Command line arguments array.
*/
int main(int argc, char *argv[])
{
  char  buffer[1024];
  char  *p1;
  int   cc;

  /* Debug output goes to test-ident.deb in the current directory */


#line 178 "test-ident.ctr"
  /* We are entering the main function */


#line 180 "test-ident.ctr"
  do {          

#line 181 "test-ident.ctr"
    cc = 0;
    if(fgets(buffer, sizeof(buffer), stdin)) {
      p1 = dk4str8_start(buffer, NULL);
      if(p1) {  

#line 185 "test-ident.ctr"
        cc = 1;
        dk4str_delnl(p1);
        printf("%s %d\n", p1, test_identifier(p1));
      }
    }
  } while(cc);
  /* We are about to leave the main function */


#line 193 "test-ident.ctr"
  /* Close debug output file */


#line 195 "test-ident.ctr"
  exit(0); return 0;
}

Build and test the program (debug mode)

dkcpre -l -d test-ident.ctr
make test-ident
./test-ident

After testing with some input inspect the file "test-ident.deb" it contains information about source lines passed, variable values…

How do I create a GUI using the wxWidgets libraries?

You have probably seen wxWidgets example code like this one from /SHC2006/:

MyFrame::MyFrame(const wxString & title)
: wxFrame(NULL, wxID_ANY, title)
{
  // Set the frame icon
  SetIcon(wxIcon(mondrian_xpm));

  // Create a menu bar
  wxMenu *fileMenu = new wxMenu;

  // The "About" item should be in the help menu
  wxMenu *helpMenu = new wxMenu;
  helpMenu->Append(wxID_ABOUT, wxT("&About...\tF1"),
                   wxT("Show about dialog"));

  fileMenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"),
                   wxT("Quit this program"));

  // Now append the freshly created menu to the menu bar...
  wxMenuBar *menuBar = new wxMenuBar();
  menuBar->Append(fileMenu, wxT("&File"));
  menuBar->Append(helpMenu, wxT("&Help"));

  // ... and attach this menu bar to the frame
  SetMenuBar(menuBar);

  // Create a status bar just for fun
  CreateStatusBar(2);
  SetStatusText(wxT("Welcome to wxWidgets!"));
}

Wouldn't it be easier to maintain code like this:

icon            =       wxIcon(mondrian_xpm)
menu bar        =       menuBar
status bar      =       2 wxT("Welcome to wxWidgets!")

[wxMenuBar menuBar]
contents        =       fileMenu
contents        =       helpMenu

[wxMenu fileMenu]
text            =       wxT("&File")
contents        =       fileQuit

[wxMenuItem fileQuit]
text            =       wxT("&Exit")
tip             =       wxT("Quit this program")
id              =       wxID_EXIT

[wxMenu helpMenu]
text            =       wxT("&Help)
contents        =       helpAbout

[wxMenuItem helpAbout]
text            =       wxT("&About")
tip             =       wxT("Show about dialog")
id              =       wxID_ABOUT

The purpose of a %% wx-gui section is to read a GUI description looking like the second code snippet and to generate code like the first one and the class member declaration in the header file.


See also

/SHC2006/ Julian Smart and Kevin Hock with Stefan Csomor:
Cross-Platform GUI Programming with wxWidgets
Prentice Hall 2006
ISBN: 0131473816

← Previous ↑ Home → Next

Related

Wiki: dkcpre