In part 1, Brokken and Kubat explained where the ideas for icmake came from, the basics of the program and where you can get a copy. In Part 2 we cover the grammar of icmake source files. The final part of this article will appear next month and will show examples of the use of icmake.
4. The grammar of icmake source files

Icmake source files are written according to a well-defined syntax, closely resembling the syntax of the C programming language. This is no coincidence. Since the C programming language is so central in the Unix operating system, we assumed that many people using the Unix operating system are familiar with this language. Providing a new tool which is founded on this familiar programming language relieves everybody of the burden of learning yet another dialect, thus simplifying the use of the new system and allowing its new users to concentrate on its possibilities rather than on its grammatical form.

Considering icmake's specific function, we have incorporated a lot of familiar constructs from C into icmake: most C operators were implemented in icmake, as were some of the standard C runtime functions. In this respect icmake's grammar is a subset of the C programming language. However, we have taken the liberty of defining two datatypes not normally found in C. There is a datatype `string' (yes, its variables contain strings) and a datatype `list', containing lists of strings. We believe these extensions to the C programming language are so minor that just this paragraph would probably suffice for their definition. However, they will be described in somewhat greater detail in the following sections. Also, some elements of C++ are found in icmake's grammar: some icmake-functions have been overloaded; they do different but comparable tasks depending on the types of arguments they are called with. Again, we believe this to be a minor departure from the `pure C' grammar, and think this practice is very much in line with C++'s philosophy.

4.1. Comment and preprocessor directives.

One of the tasks of the preprocessor is to strip the makefile of comment. Icmake recognizes two types of comment: standard C-like comment and end-of-line comment, which is also recognized by the Gnu C compiler and by Microsoft's C compiler.

Standard comment must be preceded by /* and must be closed by */. This type of comment may stretch over more than one line. End-of-line comment is preceded by // and ends when a new line starts.

Lines which start with #! are skipped by the preprocessor. This feature is included to allow the use of executable makefiles. Apart from the #! directive, icmake recognizes two more preprocessor directives: #include and #define. All preprocessor directives start with a `#'-character which must be located at the first column of a line in the makefile.

4.1.1 The #include directive.

The #include directive must obey the following syntax:

#include "filename"


#include <filename>

When the preprocessor icm-pp encounters this directive, `filename' is read. The filename may include a path specification. When the filename is surrounded by double quotes, icm-pp attempts to access this file exactly as stated. When the filename is enclosed by < and >, icm-pp attempts to access this file relative to the directory pointed to by the environment variable IM. Using the #include directive, large icmake scripts may be modularized, or a set of standard icmake source scripts may be used to realize a particular icmake script.

4.1.2. The #define directive.

The #define directive is a means of incorporating constants in a makefile. The directive follows the following syntax:

#define identifier redefinition-of-identifier

The defined name (the name of the defined constant) must be an identifier according to the C programming language: the first character must be an underscore or a character of the alphabet; subsequent characters may be underscores or alphanumerics.

The redefinition part of the #define directive consists of spaces, numbers, or whatever is appropriate. The preprocessor simply replaces all occurrences of the defined constant following the #define directive by the redefinition part. Note that redefinition's are not further expanded; an already defined name which occurs in the redefinition part is not processed but is left as-is.

Also note that icm-pp considers the redefinition part to be all characters found on a line beyond the defined constant. This would also include comment, if found on the line. Consequently, it is normally not a good idea to use comment-to-end-of-line on lines containing #define directives.