User Tools

Site Tools


CIGAL Reference Manual, Chapter 1 (Topics): variables

Variables -- Introduction to CIGAL variables

All data in CIGAL are stored and manipulated in variables. A variable can be a:

         number       - single number
         array        - one dimensional set of numbers
         matrix       - two dimensional set of numbers
         image        - special class of matrix
         solid        - three dimensional set of numbers
         string       - sequence of text characters
         string list  - table of strings
         vector       - three dimensional drawing instruction
         vector list  - array of vectors
         pointer      - pseudo-variable, can point to any variable

Variables fall into several broad classes depending on where their data are stored. The classes of storage locations are:

         stack        - CIGAL's dynamic data memory
         hstack       - high memory stack (used for most user-defined variables)
         internal     - CIGAL's internal control values and tables
         device       - memory in external devices (eg. video memory)
         core         - variables can access anywhere in core memory
         file         - data stored in disk files

Predefined Variables

The INTERNAL and DEVICE classes of variables are predefined within CIGAL itself, whereas the rest are defined dynamically by the user. The predefined variables generally refer to internal control flags and tables, or hardware memory, whose values have special meaning. Changing values in one of these variables automatically changes whatever property the variable controls (see INTERNALS(2)).

User-defined Variables

The different classes of user defined variables are designed to provide broad flexibility in letting you access data from different places. STACK and CORE variables are both created by using the DECLARE command (see DECLARE(2)). FILE variables can be declared if the files don't already exist but usually you don't need to. Data can be accessed from a file as a variable simply by using the appropriate naming syntax (see Variable Names below).

Stack Variables

The most useful class of user defined variables are the STACK variables. A stack variable is stored as part of CIGAL's large internal data memory (see STACK(4)). Depending on how you declare the variable, it can either be allocated a fixed part of the stack, or its allocation can be dynamic, changing automatically as the length of the variable changes. CIGAL takes care of allocating memory space within the stack as it is needed, so you don't need to worry about details of where particular variables are stored.

If your computer has expanded memory, then CIGAL can make use of that memory as an extended stack. The part of the stack in expanded memory is referred to as the “high” stack. You tell CIGAL how much expanded memory you have by setting the internal variables EMEMBASE and EMEMSIZE (see EMEMBASE(4) and ENEMSIZE(4)). Then CIGAL automatically allocates data storage space for large variables in the high stack if space is available. Stack variables have some advantages over the other classes of data variables. Most importantly, stack variables are located within the computer's main memory and are therefore available for immediate access. This provides a distinct improvement in performance compared to accessing data in device or file variables. Second, you can declare different stack variables to share the same memory storage (see DECLARE(2)). This is analogous to a UNION declaration in C or an EQUIVALENCE statement in FORTRAN, and can be very useful for some kinds of data handling problems. The major drawback of stack variables is that the amount of storage space available on the stack is limited by the amount of random access memory (RAM) your system has. With expanded memory stack space can be very large, but it is still limited. For data sets that are too large to fit within the available stack space you should use file variables, which are limited only by the amount of disk space you have.

Core Variables

This type of variable is not available on Windows computers.

A CORE variable is declared similar to a STACK variable except that instead of referring to data stored in the stack memory, a core variable points explicitly to some part of the computer's physical memory. This feature lets you create windows anywhere you like into the computer's memory and access that data as a standard CIGAL variable (see DECLARE(2)). For example, core variables can be created for the video display memory or the computer's internal font tables. Writing to such variables immediately changes the display on the terminal's screen. If you are more ambitious you can also create core variables that point to the computer's control registers and thereby directly read or modify any of the system's control parameters.

File Variables

Data can be accessed directly from a disk file as a FILE variable. Basically, any unrecognized variable name is assumed to be the name of a disk file (see Variable Names below). CIGAL opens the file if it exists and reads the beginning of it to see what kind of file it is. If it is an ASCII text file, then the whole file is read into the stack to create a temporary stack file. This must be done in order to determine how large the variable is. However, if the beginning of the file indicates that the file is a binary data file, then it is treated as a random access file and data blocks are read or written only as they are needed. In this way file variables provide you with virtually unlimited data space. You can have as many variables as you have disk files, and their size is limited only by the amount of space you have on the disk drives.

Data Buffering

Except for STACK and CORE variables, which are always immediately accessible, data from most other variable classes are transferred in and out of CIGAL via data buffers. This means that a block of data is copied at a time. The data within the buffer are then accessed as rapidly as for stack variables. To optimize data transfer efficiency CIGAL maintains three buffers for each variable. Data buffering is completely transparent to the user.

Variable Size

There are two aspects determining the size of an individual variable: the size of each element and the number of elements. For the numerical variables (NUMBER, ARRAY, MATRIX, IMAGE, and SOLID) the size of each element can be declared to be any one of seven formats (see DECLARE(2)):

         bit          - 1 bit unsigned integer
         crumb        - 2 bit unsigned integer
         nibble       - 4 bit unsigned integer
         byte         - 8 bit unsigned integer
         integer      - 16 bit signed integer
         long         - 32 bit signed integer
         real         - 32 bit signed floating point

A NUMBER can contain only 1 element, but ARRAY, MATRIX, IMAGE, and SOLID variables can contain as many elements as your storage space allows (the maximum 'legal' length for each dimension is over 2 billion).

String Variables

For STRING variables, each element is a character which is treated the same as an 8 bit BYTE. The length of a single STRING is limited to 512 characters. A STRING LIST variable is an unusual variable type in that each element is a character string, and these strings can all have different lengths. For this reason subscripts to string lists are also unusual (see SUBSCRIPTS(1)). A string list's length is the number of strings in the list (although each string is limited to 512 characters, the total length of a string list has no limit).

Vector Variables

For VECTOR variables, each element is 64 bits long and is made up of 6 different values:

         xvalue       - 16 bit signed integer
         yvalue       - 16 bit signed integer
         zvalue       - 16 bit signed integer
         key          - 4 bit unsigned integer
         width        - 4 bit unsigned integer
         intensity    - 8 bit unsigned integer

VECTOR LIST variables are arrays of VECTOR variables and can be of any length.


A POINTER is a special kind of variable. By itself it has neither type nor class and contains no data. However, when a pointer is assigned to another variable the pointer takes on the properties of the variable to which it points. Pointers are useful as a way of assigning a whole variable to serve a particular task (see for example ZIMAGE(4)) or as a way of selecting a subset of a larger variable. In the latter case the pointer provides a window within the original variable. Once a pointer is assigned to a variable, then it can be used just as the original variable is used. Pointers are particularly useful for manipulating different subsets of a variable independently. See POINTERS(3) for more on pointers.

Variable Names

The general form for identifying CIGAL variables is:


The <Symbol> indicates the type of variable as:

           #          - number
           ^          - array
           ^^         - matrix
           @          - image
           @@         - solid
           ~          - string
           ~~         - string list
           %          - vector
           %%         - vector list

Most of the time these symbols are unnecessary because the variable's name already identifies the type. For example, if you create an array as:

            declare integer array lengths(100)

then you can refer to this array as either ^LENGTHS or LENGTHS, because the program knows that LENGTHS is an array. However, for FILE or DEVICE variables or for using indirect variable names (see below) the symbol is required, so don't forget about them completely.

The NAME of a variable can be a character string, a number, or another variable. For STACK, INTERNAL, and CORE variables the names are always character strings of up to 12 characters. The first character must be a letter and the rest can be either letters or numbers. The name is assigned when the variable is created and must not match any other CIGAL reserved words (see NAMES(1)).

For DEVICE variables the name is always a number (that is why the type symbol is required). For example, the computer's video display memory is referred to as image variable @0 (or @1, @2, etc. in modes that support multiple screen memories). Similarly, the memory planes in an image processor are referred to as variables: @10, @11, @12, etc. The red, green, and blue lookup tables are referred to as ^10, ^11, ^12. For these numbered variables, a second variable can be used to specify the number. For example if you have a number variable called A assigned a value of 1, then variable @#a is the same as variable @1. Note: in this case the second variable must be preceded by its symbol in order to distinguish this from an image variable called @a, which you might also have. See INTERNALS(1) for more details on the meanings of the device variables.

The names of FILE variables have a slightly different format from the other variable classes. File variables almost always require the symbol identifier, so that the parser knows it is a variable. If the name after the symbol is not recognized as a previously defined variable name, then it is assumed to be a file name. This is also true if the name is in quotation marks, or if the name is specified by a second character string variable. For example, these are all valid file variable names:

           ^'myfile.dat'       ; quotes are needed because of '.'
           @~str               ; assuming STR is a string variable
                                    containing the filename

File variables can also be identified by numbers. Doing so can be very useful for applications that generate many different files in sequence. To use numbered file variables you must first set the internal variable DATADIR to indicate which directory is used to store the data files. The file variable is then specified by number within the symbols '<>'. In this case, the filename is constructed by appending the number to the DATADIR string and adding an appropriate suffix. (Suffixes are '.img' for IMAGE and SOLID, '.vec' for VECTOR LISTS, and '.dat' for all other data types.)

For example, if DATADIR contains \MYDIR\FILE then

                       @<23>      is the file   \MYDIR\FILE23.IMG
                       ^<81>      is the file   \MYDIR\FILE81.DAT

and if #A is 16, %%<a> is the file \MYDIR\FILE16.VEC Note: In the command READ, WRITE, and DELETE files can be specified by number alone, without the normal SYMBOL<#> construction, because these commands already expect the argument to be a filename.

The other way in which file variable names differ from other variables is that a file may contain more than one variable, in which case the name can specify which of the file's variables is being used. This is done by indicating the variable number within '{}' after the rest of the name. Variable numbers, like subscripts, begin with 0, which is easy to remember if you think of how many you need to skip to get the one you want. If you omit the {} specifier, {0} is assumed so that the first set of values in the file is used. Examples:

          ^^junk{3}    is the fourth matrix in file JUNK (i.e., skip 3)
          @<2>{a}      is the 17th image in file \MYDIR\FILE2.IMG
                       (assuming the same values as in the example above)


Each value within a variable, or any subset of a variable, can be accessed directly using subscripts. See SUBSCRIPTS(1) for how to use subscripts.

Local versus Global Variables

User-defined variables (i.e., created using the DECLARE command) that are created within CIGAL macro (.IMP) programs can either be declared locally or globally. A local variable is only defined for as long as the current macro is active and is automatically deleted when the macro terminates. A local variable can be used by the macro in which it is declared, and by any other macro that the first macro calls. A locally declared variable will override any other variable declared with the same name. In this way macros don't have to worry about always coming up with unique variable names, provided they don't care if the variable is temporary.

All variables declared at the interactive level are automatically global. Variables declared within macro programs are local by default, but can be global if declared as such in the DECLARE command. Global variables will remain declared even after the macro terminates. Global variables can be used by all commands, regardless whether they are in macros, menus, or entered interactively. Because of this, each globally declared variable must have a unique name. An attempt to re-declare a global variable as something different will generate an error.

Register variables

There is a special group of number variables that are always defined and yet always function as local variables. These are the 10 number 'registers' r0, r1, … r9. Of these, r1 through r9 are designed for use in macro programs so that you always have some number variables available for counters, etc. The main advantage of these registers is that their contents are saved whenever you call another macro, and are then restored when you return from the macro. This means that if a sub-macro changes the value of r1, for example, it won't affect the contents of r1 in the calling macro. This is not the case for any other variables. If a macro changes a variable that was declared at a higher level (i.e., in a calling macro or globally) then it will keep the new value when the macro terminates. This can be a useful way of passing values from one level to another, but it can also be a nuisance if you don't want a variable's value to be changed by a sub-macro. Using the number registers avoids this problem.

The number register r0 is unusual in that many CIGAL commands use it to return an exit status. For example, the READ, WRITE, INPUT, and OUTPUT commands return in r0 how many records were successfully transferred. In addition, the RETURN command in a macro program can be used to return a status value to the calling program so that this value is returned in the r0 register. It is left up to the macro to test r0 if it cares about the termination status of any particular command.

See Also:
CIGAL Home, CIGAL Manual, Topics List, Manual Help

jvs/cigal/manual/chapter1/variables.txt · Last modified: 2023/02/23 18:43 (external edit)