Omnimark Preprocessor v1.0AuthorDoug Douglass ddouglass@jeppesen.comAuthors NoteI completely release the source code to the pre and postprocessors to anyonewho finds it useful in developing with Omnimark. I would like to be made awareof bugs and/or enhancements via email, though I cannot except anyresonsibility for performing such changes.The custom Omnimark preprocessor requires Omnimark V3 or later. The source for thepreprocessor is contained in the file xompre.xom, with shared functions in the filexomc.xin.Command LineThe command line for the custom Omnimark preprocessor is as follows: omnimark -load xompre.xap \ \ -of \ [-d I [:[=][:[=]]*]? \ -briefThe optional stream I can be defined to contain paths for finding files namedin Omnimark INCLUDE statements. Multiple paths can be added with each separated by a colon, as is standard for Unix paths. A trailing directory separator, / under Unix, is not required but can be present.The optional stream D can be defined to contain preprocessor constants. Eachconstant defined is separated by a semicolon. Each constant may additionallyhave a value assigned to it by following the constant name with an equal signand the value. No spaces can be present in the constant name, or around theequal sign. Spaces can be present in the value.Supported Preprocessor DirectivesThe custom Omnimark preprocessor was modeled after the standard Cpreprocessor. Preprocessor directives must appear on a line by themselves andas the first text on that line. Leading white-space is allowed.Followiing is a list of directives recognized by the preprocessor: (Note: thepreprocessor is case-sensitive)#if...#else...#endifThe #if...#else...#endif preprocessor directive allows the conditionalinclusion or exclusion of code within the directive based on the conditiontested. For example, consider the following code: #if defined(Debug) BLOCK 1 #else BLOCK 2 #endifIf the preprocessor constant Debug were defined, then BLOCK 1 would beincluded in the output of hte preprocessor, BLOCK 2 would not. #if defined(DebugLevel=3) BLOCK 1 #else BLOCK 2 #endifIf the preprocessor constant DebugLevel were defined and equal to 3, thenBLOCK 1 would be included in the output of hte preprocessor, BLOCK 2 wouldnot.#defineThe #define preprocessor directive allows placing preprocessor constantdefinitions within source files, as opposed to being defined on thepreprocessor command-line. #define WIN32 #define DebugLevel=3_FILE_The _FILE_ preprocessor directive is replaced during preprocessing with thefile name of the current file. This will change during preprocessing asINCLUDE statements are encountered and the included file is processed._LINE_The _LINE_ preprocessor directive is replaced during preprocessing with theline number of the current file. This will change during preprocessing asINCLUDE statements are encountered and the included file is processed.INCLUDEThe Omnimark keyword INCLUDE is treated as a preprocessor directive. The filenamed in the INCLUDE statement is searched for in the current directory andany directories given in the optional command-line stream I. If the named filecannot be found, an error is issued. If the named file is found, its contentis also run through the preprocessor.Preprocessed File FormatThe output of the preprocessor is very much like the input source code withthe following exceptions:A single source file is created.All user comments are removed.All preprocessor directives are removed.All code within failed preprocessor conditional blocks is removed.Preprocessor comments are placed on certain lines to reset the file and linenumber. These comments are used by the postprocessor to resolve error/warningfile and line numbers.The need for a PostprocessorThe output of the preprocessor is a single file. When this file isgiven to Omnimark to compile, error/warning messages will contain the nameand line number of this single input file, not the original file.Command Line omnimark | omle -s xompre.xom -of -briefA postprocessor was developed to resolve file names and line numbers inOmnimark messages. This postprocessor reads both the preprocessed source fileand the file containing the Omnimark messages. Special directives placed in thepreprocessed file are used to reconcile and output the Omnimark messages withcorrect file names and line numbers.A side effect of the postprocessing the Omnimark messages is they are outputin a one-line format suitable for use by many programmers editors.ComplexityThough the pre and postprocessors do prodive valuable additions to developingwith Omnimark, in practice they can prove overly complex to use. Whenpreviously compiling an Omnimark program was a simple one line command, nowthree are needed.As a means to both simplify the use of the pre and postprocessors, and toincorporate another standard developers tool into the Omnimark bag of tricks,I use a make utility. A makefile is supplied as an example of its use with thepre and postprocessors. The makefile was created for, and used with CygnusGNU32 make.IssuesSource files with line ending characters other than the system thepreprocessor is being executed on do not process correctly.Path and directory separators are hard coded.Postprocessor/preprocessor directive file names do not include paths.