| gclib 421 Communications API for Galil controllers and PLCs |

Program Preprocessor

gclib's program downloader provides a preprocessor for DMC code. The preprocessor modifies the program prior to download providing a number of language features not present in native DMC code.

The preprocessor is invoked in the following two ways.

1. With both GProgramDownload() and GProgramDownloadFile() via the `preprocessor` argument. Downloading code with null for the preprocessor argument uses defaults.
2. From within DMC code via in-band preprocessor directives.

## The `preprocessor` argument

GProgramDownload() and GProgramDownloadFile() can be called with a string passed to the `preprocessor` argument. The program will be modified based on this string prior to download. See Preprocessor Options below for syntax.

## In-band Operation

DMC code can be written with special markup to signal the preprocessor to take actions prior to download.

For example, the following program will invoke the in-band preprocessor. The specifics are described below.

## Author: Zaphod Beeblebrox
## Project: Total Perspective Vortex
//the above 4 hashmarks enable the preprocessor
##option "--min 4" //use a minimum of level four compression
REM REM-style comments are supported at all times
PRA=1000
BGA
AMA
EN

### The `REM` Comment

Lines beginning with the string `REM` are removed prior to download. `REM` comments are always removed regardless of whether the other preprocessor options are enabled or not.

### Double Hash

Most preprocessor statements begin with a double hash, `##`. When proceeded by a space, the double hash acts like a `REM` comment.

When proceeded by a character other than space, `##` is interpreted as a preprocessor directive. For example, see `##option` below.

Note
  Double hash lines are removed from the program only when the preprocessor is enabled with a quad hash.

### Quad Hash to enable

In order to enable the in-band preprocessor, the first two lines of the DMC program must start with a double hash. This syntax of using two lines with double hashmarks is called a quad hash.

Content may follow the hash marks. For example, a good code writing style is to use double hash comments as a comment header showing author, project name, etc.

### C-style comments

With the preprocessor enabled, C-style comments may be used with the `//` prefix. These comments are very similar to `REM` comments. The primary advantage of using this comment over `REM` is that `//` comments may occur anywhere in a line. This is helpful for line comments such as the following.

SIA= 1,25,25,0<4>1 //SSI 25 bits total, all single turn, no status

Strings containing `//` are not interpreted as comments.

Note
  `//` comments are removed from the program only when the preprocessor is enabled with a quad hash.

### Preprocessor Directives

Note
  Directives are only followed when the preprocessor is enabled with a quad hash.

#### `##option`

The `option` directive allows passing switches directly to the preprocessor with the same syntax as the `preprocessor` argument in GProgramDownload() and GProgramDownloadFile(). The syntax of the `option` directive is the following.

##option "{preprocessor switches}"

For example, the following line will disable compression in the program.

##option "--max 0"

See Preprocessor Options below for other switches.

#### `##include`

The `include` directive provides a way to include the contents of another DMC file in the current program. This is useful for reusing code such as automatic subroutines, homing operations, or controller initilization routines.

The contents of the file will be inserted in place of the `include` line. The insertion occurs prior to code compression.

The syntax of the `include` directive is the following.

##include "{filename}"

For example,

##include "c:\galil\initialize.dmc"
##include "homing.dmc"

To write more portable code, use the `include` directive with just the file name, no absolute path. The path to find the file on the system is set depending on usage.

1. In the Galil Design Kit, specify the include path in GDK's settings with the `--search` or `-I` switch as defined below.
2. When downloading code via GProgramDownload() or GProgramDownloadFile(), use the `--search` or `-I` switch in the `preprocessor` argument.
3. Finally, if the file is in the executable search path, the file will be found. However, one of the previous two options is more reliable.

### In-band Support

In addition to gclib, Galil Design Kit supports the preprocessor. Proper preprocessor usage will be colored in the Editor's syntax highlighter. If the quad hash is not present, preprocessor syntax will be colored differently to indicate improper usage.

The preprocessor is not supported in software prior to GDK/gclib. DMC code downloads using the in-band preprocessor in prior generation software (e.g. GalilTools or SmartTerm) will fail with a TC code of 61, Duplicate or bad label.

## Preprocessor Options

### Compression, `--min`, `--max`

- Default uses minimum compression needed to fit the program.
- `--max` n provides compression up to and including level n. Only the necessary compression will be performed up to level n.
- `--min` n will compress at least up to and including n. n defined as with `--max`.

#### Compression Levels, n

- Level 0 (mandatory)
  1. Remove lines beginning with `REM`.
  2. Remove trailing semicolons.
  3. Comment blank lines with '.
  4. Remove white space (space/tab) in front of # (label declarations).
  5. Remove white space after commands.
  6. Line ends changed to carriage return.
  7. Replace leading tabs with double space.
  8. Replace non-leading tabs with single space.
  9. A backslash (`\`) character on a line other than a preprocessor line will result in an error.
- Level 1
  1. Remove unnecessary spaces. Strings, comments ('), and no-ops (NO) are not changed.
- Level 2
  1. Remove comments (') but not no-ops (NO).
- Level 3
  1. Remove no-ops (NO).
- Level 4
  1. Break apart compound lines that are too long.
  2. Compact lines of code to maximize line usage.
  3. Use backtick to support long lines where applicable.

### Code insertion, `--insert`

- Default begins at line zero and overwrites anything present.
- `--insert` arg invokes the insert option of the firmware's DL command. arg can be one of the following.
  1. Line number, e.g. `100`. Program insertion will occur on the line after the line specified.
  2. Variable name, e.g. `myvar`. Program insertion will occur on the line after the line equal to the value of the variable.
  3. Label callout, e.g. `#mylabel`. Program insertion will occur on the line after the label.
  4. A lone `#` symbol. Program insertion will occur on the line after the last line in the program buffer.
- Compression directives `--max` and `--min` are followed.
- All original code following the point of insertion is cleared.
- Not all products support the `--insert` operation, e.g. DMC-30010. See the DL command for support.

Warning
  It is the user's responsibility to ensure that the code will fit in the inserted location. The preprocessor will not check line numbers when executing the `--insert` option.

### Include Search Paths, `--search`, `-I`

- The `##include` directive will attempt to open its string argument directly. The open will succeed if the argument is the absolute path, or if the argument is in the executable's path, e.g. in the same directory.
- `--search` path allows the user to specify a directory or directories to be searched for the `include` file in case the first open fails.
  - For historical reasons, `-I` is shorthand for `--search`.
- Multiple directories may be specified with multiple `-I` directives.
- For in-band code, `-I` must be specified prior to the include.
- A common use for `-I` is to specify only the filename in the DMC source code and use the `preprocessor` argument during download to specify the path to the files. This allows the files to be moved without a change to source code.
- Search order
  1. The `##include` argument is checked first as-is.
  2. Then each `-I` argument in the `preprocessor` argument, in the order specified.
  3. Then `##option` directives in the DMC file, in the order specified.
- If the search path contains spaces, enclose the path in double quotes, escaped with a backslash. See example below.

#### In-band Example

##option "-I /code/dmc/homing"
##option "-I \"/code/dmc/other code\""
##include "auto.dmc"
//executable's directory will be checked
//then c:\code\dmc\homing
//then c:\code\dmc\other code

### Macro Definition, `--define`, `-D`

- `--define` provides a way to substitute one token for another. This is useful for writing code that is generic until program download. Wherever the token is found in code, it is substituted by the replacement. The replacement occurs right before code compression.
- `-D` is shorthand for `--define`.
- The token should consist of a starting backslash character, followed by upper or lower case alphanumeric characters, underscores, and an ending backslash.
- The common usage for this feature is to write code with a token, and then call the program download with the `-D` switch.

In this example, an axis is defined at download time. Specifying the following for the preprocessor argument

--define \ax\:A

would cause the following code

SH\ax\
JG\ax\=1000
BG\ax\

to be downloaded as

SHA
JGA=1000
BGA

This causes the A axis to be addressed.

Note
  The macro `\pid\` is reserved for exclusive use by GDK.

### Conditional Directives, `--ifdef`, `--ifndef`

To specify a preprocessor directive should be executed only if a macro is defined, use `--ifdef`.

##option "--ifdef \minify\ --min 4" //maximally compress code if minify macro set

To specify a preprocessor directive should be executed only if a macro is NOT defined, use `--ifndef`.

##option "--ifndef \axis\ -D \axis\:A" //Default to axis A

## GDK Support

- See the `preprocessor` text box in the Editor settings page to set the desired preprocessor setting for developing in GDK's editor.