As the CDL has no built-in support for functions, conditionals, loops, and other programming constructs, it's suggested to use a preprocessor when writing a sophisticated model. In a case like the RiSE model, where there are six almost identical legs, it makes a lot of sense to reuse model code when writing a CDL file. Preprocessors can greatly aid the model developer here. I have documented two common preprocessors on this page.
The C Preprocessor
If you are a C programmer, you already know how to use the C Preprocessor. It's the unix command cpp, and it is used to process your source code before compilation. Calls like #include and #define are cpp commands. Since cpp is so easy, it's the fastest way to get up and running with macros in a CDL file.
So, how do you use it? From the command line, you simply make a call like cpp < infile.cdl > outfile.ocdl. The output file has a .ocdl filename extension, to differentiate the fact that the file has already been processed. If you fed the original file as a CDL model, it would not parse, thus the need for the processed file. For developing a model using cpp as your preprocessor, simply use it like you would when programming C or C++ code. Using #include to add secondary files to your model, and use #define to create macros for later reuse.
A few caveats with the cpp #define: You cannot have newline characters within a #define, so you must do things like
#define leg_segment \
Block(1.0,0.1,0.1), \
Translation(0.5,0,0),Rotation(0,1,0,pi/2),\
Translation(0.5,0,0),\
Block(1.0,0.1,0.1);
The backslash characters tell the preprocessor to continue reading on the next line. When this is written to an output file, all of those characters end up on one line, making them hard to read.
Also for this same reason, it's difficult to document #define's when using cpp. You must use C style comments.
The M4 Preprocessor
Given the shortcomings of cpp, it's desirable to have something less limited and much more powerful. m4 fills these needs very well. Unlike cpp, m4 contains logic to do much more advanced constructs. m4 has built-in support for macros, file inclusion, loops, conditionals, plus more. However, the syntax is unfamiliar and takes some getting use to.
Macros with M4
Similar to a cpp #define, M4 lets you make macros with or without arguments. The simplest macro would be something like, define(`mymacro',`expand this')
Note that a backtick (`) always starts a string, and a single quote closes it. Anytime the preprocessor find "mymacro" in the file, it will replace it with "expand this". Unlike cpp, you can have multi-line macros, meaning there are no backslashes, and you can use C++ style comments. If you are passing arguments to a macro, you can retrieve them with "$1" for the first argument, "$2" for the second argument, and so on. define(`macro_arguments',`
My first argument: $1.
My second argument: $2.'
macro_arguments(hello,world)
Complete documentation for M4 is available at the GNU website.
SimLib Reference Documentation