gclib  437
Communications API for Galil controllers and PLCs
preprocessor.md
1 # Program Preprocessor {#preprocessor}
2 
3 gclib's program downloader provides a preprocessor for DMC code. The
4 preprocessor modifies the program prior to download providing a number of
5 language features not present in native DMC code.
6 
7 The preprocessor is invoked in the following two ways.
8 
9  -# With both GProgramDownload() and GProgramDownloadFile() via the
10  `preprocessor` argument. Downloading code with null for the preprocessor
11  argument uses defaults.
12  -# From within DMC code via in-band preprocessor directives.
13 
14 
15 --------------------------------------------------------------------------------
16 
17 ##The `preprocessor` argument
18 
19 GProgramDownload() and GProgramDownloadFile() can be called with a string passed
20 to the `preprocessor` argument. The program will be modified based on this
21 string prior to download. See *Preprocessor Options* below for syntax.
22 
23 --------------------------------------------------------------------------------
24 
25 ##In-band Operation
26 
27 DMC code can be written with special markup to signal the preprocessor to take
28 actions prior to download.
29 
30 For example, the following program will invoke the in-band preprocessor. The
31 specifics are described below.
32 
33 \code
34 ## Author: Zaphod Beeblebrox
35 ## Project: Total Perspective Vortex
36 //the above 4 hashmarks enable the preprocessor
37 ##option "--min 4" //use a minimum of level four compression
38 REM REM-style comments are supported at all times
39 PRA=1000
40 BGA
41 AMA
42 EN
43 \endcode
44 
45 ###The `REM` Comment
46 
47 Lines beginning with the string `REM` are removed prior to download. `REM`
48 comments are always removed regardless of whether the other preprocessor options
49 are enabled or not.
50 
51 ###Double Hash
52 
53 Most preprocessor statements begin with a double hash, `##`. When proceeded by
54 a space, the double hash acts like a `REM` comment.
55 
56 When proceeded by a character other than space, `##` is interpreted as a
57 preprocessor directive. For example, see `##option` below.
58 
59 \note Double hash lines are removed from the program only when the
60 preprocessor is enabled with a quad hash.
61 
62 ###Quad Hash to enable
63 
64 In order to enable the in-band preprocessor, the first two lines of the DMC
65 program must start with a double hash. This syntax of using two lines with
66 double hashmarks is called a *quad hash*.
67 
68 Content may follow the hash marks. For example, a good code writing style is to
69 use double hash comments as a comment header showing author, project name, etc.
70 
71 ###C-style comments
72 
73 With the preprocessor enabled, C-style comments may be used with the `//` prefix.
74 These comments are very similar to `REM` comments. The primary advantage of
75 using this comment over `REM` is that `//` comments may occur anywhere in a
76 line. This is helpful for line comments such as the following.
77 
78 \code
79 SIA= 1,25,25,0<4>1 //SSI 25 bits total, all single turn, no status
80 \endcode
81 
82 Strings containing `//` are not interpreted as comments.
83 
84 \note `//` comments are removed from the program only when the preprocessor
85  is enabled with a quad hash.
86 
87 ### Preprocessor Directives
88 
89 \note Directives are only followed when the preprocessor is enabled with a
90 quad hash.
91 
92 #### `##option`
93 
94 The `option` directive allows passing switches directly to the preprocessor with
95 the same syntax as the `preprocessor` argument in GProgramDownload() and
96 GProgramDownloadFile(). The syntax of the `option` directive is the following.
97 
98 \code
99 ##option "{preprocessor switches}"
100 \endcode
101 
102 For example, the following line will disable compression in the program.
103 
104 \code
105 ##option "--max 0"
106 \endcode
107 
108 See *Preprocessor Options* below for other switches.
109 
110 #### `##include`
111 
112 The `include` directive provides a way to include the contents of another DMC
113 file in the current program. This is useful for reusing code such as automatic
114 subroutines, homing operations, or controller initilization routines.
115 
116 The contents of the file will be inserted in place of the `include` line. The
117 insertion occurs prior to code compression.
118 
119 The syntax of the `include` directive is the following.
120 
121 \code
122 ##include "{filename}"
123 \endcode
124 
125 For example,
126 
127 \code
128 ##include "c:\galil\initialize.dmc"
129 ##include "homing.dmc"
130 \endcode
131 
132 To write more portable code, use the `include` directive with just the
133 file name, no absolute path. The path to find the file on the system is set
134 depending on usage.
135  1. In the <a href="http://galil.com/downloads/software/gdk">Galil Design Kit</a>,
136  specify the include path in GDK's
137  <a href="http://galil.com/sw/pub/all/doc/gdk/man/settings.html">settings</a>
138  with the `--search` or `-I` switch as defined below.
139  2. When downloading code via GProgramDownload() or GProgramDownloadFile(), use
140  the `--search` or `-I` switch in the `preprocessor` argument.
141  3. Finally, if the file is in the executable search path, the file
142  will be found. However, one of the previous two options is more reliable.
143 
144 #### `##gclib`
145 <a href="http://galil.com/downloads/software/gdk">Galil Design Kit</a> uses
146 the `##gclib` directive in
147 <a href="http://galil.com/sw/pub/all/doc/gdk/man/macros.html">GDK Macros</a>.
148 gclib ignores this directive.
149 
150 ### In-band Support
151 
152 In addition to gclib,
153 <a href="http://galil.com/downloads/software/gdk">Galil Design Kit</a> supports
154 the preprocessor. Proper preprocessor usage will be colored in the Editor's
155 syntax highlighter. If the quad hash is not present, preprocessor syntax will be
156 colored differently to indicate improper usage.
157 
158 The preprocessor is not supported in software prior to GDK/gclib. DMC code
159 downloads using the in-band preprocessor in prior generation software (e.g.
160 GalilTools or SmartTerm) will fail with a TC code of 61, <em>Duplicate or bad label</em>.
161 
162 --------------------------------------------------------------------------------
163 
164 ##Preprocessor Options
165 
166 ###Compression, `--min`, `--max`
167 
168  * Default uses minimum compression needed to fit the program.
169  * `--max` *n* provides compression up to and including level *n*.
170  Only the necessary compression will be performed up to level *n*.
171  * `--min` *n* will compress at least up to and including *n*. *n* defined as with `--max`.
172 
173 ####Compression Levels, *n*
174 
175  * Level 0 (mandatory)
176  -# Remove lines beginning with `REM`.
177  -# Remove trailing semicolons.
178  -# Comment blank lines with '.
179  -# Remove white space (space/tab) in front of # (label declarations).
180  -# Remove white space after commands.
181  -# Line ends changed to carriage return.
182  -# Replace leading tabs with double space.
183  -# Replace non-leading tabs with single space.
184  -# A backslash (`\`) character on a line other than a preprocessor line will result in an error.
185  * Level 1
186  -# Remove unnecessary spaces. Strings, comments ('), and no-ops (NO) are not changed.
187  * Level 2
188  -# Remove comments (') but not no-ops (NO).
189  * Level 3
190  -# Remove no-ops (NO).
191  * Level 4
192  -# Break apart compound lines that are too long.
193  -# Compact lines of code to maximize line usage.
194  -# Use backtick to support long lines where applicable.
195 
196 ###Code insertion, `--insert`
197  * Default begins at line zero and overwrites anything present.
198  * `--insert` *arg* invokes the insert option of the firmware's *DL* command. *arg* can be one of the following.
199  -# Line number, e.g. `100`. Program insertion will occur on the line after the line specified.
200  -# Variable name, e.g. `myvar`. Program insertion will occur on the line after the line equal to the value of the variable.
201  -# Label callout, e.g. `#mylabel`. Program insertion will occur on the line after the label.
202  -# A lone `#` symbol. Program insertion will occur on the line after the last line in the program buffer.
203  * Compression directives `--max` and `--min` are followed.
204  * All original code following the point of insertion is cleared.
205  * Not all products support the `--insert` operation, e.g. DMC-30010.
206  See the <a href="http://www.galil.com/download/comref/comall/index.html#download.html">DL</a> command for support.
207 
208 
209 \warning It is the user's responsibility to ensure that the code
210 will fit in the inserted location. The preprocessor will not check line numbers
211 when executing the `--insert` option.
212 
213 ### Include Search Paths, `--search`, `-I`
214  * The `##include` directive will attempt to open its string argument
215  directly. The open will succeed if the argument is the absolute path, or if
216  the argument is in the executable's path, e.g. in the same directory.
217  * `--search` *path* allows the user to specify a directory or directories
218  to be searched for the `include` file in case the first open fails.
219  * For historical reasons, `-I` is shorthand for `--search`.
220  * Multiple directories may be specified with multiple `-I` directives.
221  * For in-band code, `-I` must be specified prior to the include.
222  * A common use for `-I` is to specify only the filename in the DMC source code
223  and use the `preprocessor` argument during download to specify the path to the
224  files. This allows the files to be moved without a change to source code.
225  * Search order
226  -# The `##include` argument is checked first as-is.
227  -# Then each `-I` argument in the `preprocessor` argument, in the order specified.
228  -# Then `##option` directives in the DMC file, in the order specified.
229  * If the search path contains spaces, enclose the path in double quotes, escaped with a backslash. See example below.
230 
231 ####In-band Example
232 
233 \code
234 ##option "-I /code/dmc/homing"
235 ##option "-I \"/code/dmc/other code\""
236 ##include "auto.dmc"
237 //executable's directory will be checked
238 //then c:\code\dmc\homing
239 //then c:\code\dmc\other code
240 \endcode
241 
242 ### Macro Definition, `--define`, `-D`
243  * `--define` provides a way to substitute one token for another. This
244  is useful for writing code that is generic until program download. Wherever
245  the token is found in code, it is substituted by the replacement. The replacement
246  occurs right before code compression.
247  * `-D` is shorthand for `--define`.
248  * The token should consist of a starting backslash character, followed by upper
249  or lower case alphanumeric characters, underscores, and an ending backslash.
250  * The common usage for this feature is to write code with a token, and then call the
251  program download with the `-D` switch.
252 
253 In this example, an axis is defined at download time. Specifying the
254 following for the preprocessor argument
255 
256 \code
257 --define \ax\:A
258 \endcode
259 
260 would cause the following code
261 
262 \code
263 SH\ax\
264 JG\ax\=1000
265 BG\ax\
266 \endcode
267 
268 to be downloaded as
269 
270 \code
271 SHA
272 JGA=1000
273 BGA
274 \endcode
275 
276 This causes the *A* axis to be addressed.
277 
278 \note The macro `\pid\` is reserved for exclusive use by GDK.
279 
280 ### Conditional Directives, `--ifdef`, `--ifndef`
281 
282 To specify a preprocessor directive should be executed only if a macro is
283 defined, use `--ifdef`.
284 
285 \code
286 ##option "--ifdef \minify\ --min 4" //maximally compress code if minify macro set
287 \endcode
288 
289 To specify a preprocessor directive should be executed only if a macro is NOT
290 defined, use `--ifndef`.
291 
292 \code
293 ##option "--ifndef \axis\ -D \axis\:A" //Default to axis A
294 \endcode
295 
296 
297 
298 ##GDK Support
299  * See the `preprocessor` text box in the *Editor* settings page to set the
300  desired preprocessor setting for developing in GDK's editor.