.TH "icmake" "1" "1992\-2014" "icmake\&.7\&.21\&.01\&.tar\&.gz" "A program maintenance utility" .PP .SH "NAME" icmake \- A program maintenance (\fImake\fP) utility using a \fBC\fP\-like grammar .PP .SH "SYNOPSIS" \fBicmake\fP [options] \fIsource[\&.im] [dest[\&.bim]]\fP [\-\- [args]] .PP \fBicmun\fP \fIbimfile\fP .PP .SH "DESCRIPTION" .PP \fBIcmake\fP(1) can be used as an alternative to \fBmake\fP(1)\&. In its standard operation more, it calls the following programs: .IP o \fIicm\-pp\fP to preprocess the icmake file .IP o \fIicm\-comp\fP to byte\-code compile the \fBicmake\fP \fBs\fP .IP o \fIicm\-exec\fP to interpret the byte\-code file .PP \fBIcmake\fP allows the programmer to use a program language (closely resembling the well\-known \fBC\fP\-programming language) to define the actions involved in (complex) program maintenance\&. For this, \fBicmake\fP offers various special operators as well as a set of support functions that have proven to be useful in program maintenance\&. .PP The program \fBicmun\fP(1) may be used to disassemble the compiled byte\-code file\&. .PP Traditional make\-utilities recompile sources once header files are modified\&. In the context of \fBC++\fP program development this is often a bad idea, as adding a new member to a class does not normally require you to recompile the class\(cq\&s sources\&. To handle class dependencies in a more sensible way, \fBicmake\fP(1)\(cq\&s \fICLASSES\fP file may define dependencies among classes\&. By default, class\-dependencies are not interpreted\&. See the \fBicmconf\fP(7) man\-page for details\&. .PP .SH "ADDITONS SINCE VERSION 7\&.00" .PP .IP o Integral constants may be specified using hexadecimal notation (e\&.g\&., \fI0x12ab\fP); .IP o The \fIIM\fP environment variable may contain multiple directories, separated from each other by colons (\fI:\fP)\&. .IP o \fI#define\fP\-directives may refer to other macro definitions using the \fI${identifier}\fP format\&. .IP o \fI#ifdef\fP, \fI#ifndef\fP, \fI#else\fP and \fI#endif\fP directives can be nested\&. .IP o The `backtick\(cq\& operator is defined, executing a program in a shell and collecting its standard output in a list (see below)\&. .IP o The index operator (\fI[]\fP) is defined as an alternative to the pre\-defined function \fIelement()\fP, and can be used on lists and strings\&. .IP o The function \fIstring getenv(string envvar)\fP is predefined\&. If existing scripts already define a \fIgetenv()\fP function of their own, it it suggested to remove this function and use the new \fIgetenv()\fP function instead\&. Alternatively, rename the script\-defined function \fIgetenv()\fP and calls of this function to, e\&.g\&. \fImy_getenv()\fP\&. .IP o The function \fIint strstr(string haystack, string needle)\fP is renamed to \fIint strfind(string haystack, string needle)\fP\&. .IP \fBNOTE: this modification in version 7\&.00 could very well affect your earlier (6\&.xx) icmake scripts\&. Changing `strstr\(cq\& into `strfind\(cq\& should bring your older scripts up\-to\-date again\&.\fP .PP .SH "OPTIONS" .PP \fBIcmake\fP: .PP \fIsource\fP: \fBicmake\fP script source file (default extension: \fI\&.im\fP)\&. .PP \fIdest\fP: binary \fBicmake\fP script file (default: \fI`source\(cq\&\&.bim\fP)\&. .PP \fI\-\-\fP: \fBicmake\fP/\fBicmake\fP\-script arguments separator .PP \fIargs\fP: arguments following \fI\-\-\fP are entered into the \fBicmake\fP scipt \fImain()\fP function\(cq\&s \fIargv\fP\-list (see below at section \fBUSER DEFINED FUNCTIONS\fP)\&. .PP .IP o \fB\-a\fP .br information about \fBicmake\fP .IP o \fB\-b\fP .br blunt execution of the destinationfile .IP o \fB\-c\fP .br the destination file is only compiled .IP o \fB\-i\fP file .br \fIfile\fP: name of source\&. \fBIcmake\fP argument processing stops\&. .IP o \fB\-o\fP file .br all \fBicmake\fP output is written to \fIfile\fP (Not implemented on unix platforms) .IP o \fB\-p\fP .br only the preprocessor is activated .IP o \fB\-q\fP .br quiet mode: copyright banner not displayed .IP o \fB\-t\fP file .br \fIfile\fP is used as a temporary bim\-file, to be removed on exit\&. \fBIcmake\fP argument processing stops\&. .PP \fBIcmun\fP: .PP \fIbimfile\fP: binary \fBicmake\fP script file\&. .PP .SH "PREPROCESSOR DIRECTIVES" .PP The following preprocessor directives are available: .IP o comment: .br standard \fBC\fP comment (all between \fI/*\fP and \fI*/\fP) as well as comment\-to\-end\-of\-line (all line contents following \fI//\fP) are ignored\&. .IP o Shell startup: The first line of the \fBicmake\fP\-script may start with \fI#!path\fP, where \fIpath\fP defines the absolute location of the \fBicmake\fP program\&. By making the script executable, it can be called without explicitly calling \fBicmake\fP\&. .IP E\&.g\&., if the first line of an (executable) icmakefile \(cq\&icm\(cq\& (without extension) contains .nf #!/usr/bin/icmake \-qi .fi then \fIicm\fP may be given as a command, thus executing .nf /usr/bin/icmake \-qi icm \&.\&.\&. .fi Alternatively, .nf #! /usr/bin/icmake \-qt /tmp/icm .fi may be used, resulting in the execution of .nf #! /usr/bin/icmake \-qt /tmp/icm icm \&.\&.\&. .fi In this case the binary makefile is not kept, but a temporary file \fI/tmp/icm\&.PID\fP is used and removed on exit\&. The PID extension being the process\-id of the \fBicmake\fP program executing \fIicm\fP\&. .IP o \fI#include \(dq\&filename\(dq\&\fP .br The file \fIfilename\fP is included at the location of the directive .IP o \fI#include \fP .br The file \fIfilename\fP is included at the location of the \fI#include\fP directive; \fIfilename\fP is searched in the directories pointed to by the \fIIM\fP environment variable\&. .IP o \fI#define identifier definition\fP .br The text \fIidentifier\fP will be replaced by \fIdefinition\fP\&. The definition may contain references to already defined identifiers, using the \fI${identifier}\fP format\&. If the \fI${identifier}\fP hasn\(cq\&t been defined (yet), the text \fI${identifier}\fP is literally kept\&. At each \fI#define\fP at most 100 text\-replacements are performed, preventing infinite recursion\&. .IP o \fI#ifdef identifier\fP .br If the \fIidentifier\fP macro was defined the next block of code (until a matching \fI#else\fP or \fI#endif\fP directive was detected) is byte\-compiled\&. Otherwise, the block of code is ignored\&. .IP o \fI#ifndef identifier\fP .br If the \fIidentifier\fP macro was \fInot\fP defined the next block of code (until a matching \fI#else\fP or \fI#endif\fP directive was detected) is byte\-compiled\&. Otherwise, the block of code is ignored\&. .IP o \fI#else\fP .br Terminates a \fI#ifdef\fP and \fI#ifndef\fP directive, reversing the acceptance decision about the following code\&. .IP o \fI#endif\fP .br Terminates the preprocessor block starting at the matching \fI#ifdef\fP, \fI#ifndef\fP or \fI#else\fP directive\&. .IP o \fI#undef identifier\fP .br Remove \fIidentifier\fP from the set of defined symbols\&. This will not affect the specification of any previously defined symbols in which \fIidentifier\fP was used\&. .PP .SH "DATA TYPES" .PP The following data types are available: .IP o \fIint\fP .br Integral values, ranging from \fI\-0x8000\fP until \fI0x7fff\fP\&. \fIint\fP constants may be specified as decimal numbers, hexadecimal numbers or as \fIASCII\fP character constants (e\&.g\&., \fI\(cq\&x\(cq\&\fP)\&. .IP o \fIstring\fP .br Text variables\&. Text constants are delimited by double quotes\&. Multiple text constants may be concatenated, but a text constant may not extend over multiple lines\&. To indicate an end\-of\-line in a text constant use the \fI\en\fP escape sequence\&. The escape sequences \fI\ea \eb \ef \en \er\fP and \fI\et\fP are available\&. Otherwise, \fI\ex\fP is interpreted as a literal \fIx\fP\&. So, use \fI\e\e\fP to indicate \fI\e\fP within a text constant\&. .IP o \fIlist\fP .br A data structure containing a series of individually accessible \fIstring\fP values\&. When a list contains elements, its first element is indicated by index 0\&. .IP o \fIvoid\fP .br Used with function definitions to indicate that the function does not return a value\&. .PP Variables may be defined both at the global level as well as locally to functions\&. Variables are strongly typed\&. A variable cannot have the type \fIvoid\fP\&. .PP Variables may be initialized when they are defined\&. The initialization can use return values of functions, but cannot use variables\&. Consider initializations as being constructed from constant values\&. .PP .SH "PREDEFINED SYMBOLS" .PP The following symbols are predefined by \fBicmake\fP\&. All are constant \fIint\fP values: .TS tab(~); --- lll --- lll lll lll lll --- lll lll --- lll lll --- lll lll lll lll lll lll --- c. symbol~value~intended for O_ALL~8~makelist O_DIR~2~makelist O_FILE~1~makelist O_SUBDIR~4~makelist OFF~0~echo ON~1~echo P_CHECK~0~system calls P_NOCHECK~1~system calls S_IEXEC~32~stat S_IFCHR~1~stat S_IFDIR~2~stat S_IFREG~4~stat S_IREAD~8~stat S_IWRITE~16~stat .TE .PP The following symbols are available depending on the architecture: .TS tab(~); -- ll -- ll ll ll ll ll ll -- c. symbol~1 when defined on the platform, otherwise 0 MSDOS~MS\-DOS platform (with MSC 7\&.00 compiler) unix~Unix, usually with GNU\(cq\&s gcc compiler linux~x86 running Linux (usually with gcc) M_SYSV, M_UNIX~x86 running SCO/Unix (usually with) Microsoft C _POSIX~_SOURCE Unix with Posix complient compiler __hpux~HP\-UX, with the native HP compiler .TE .SH "OPERATORS" .PP All \fBC\fP operators, except for the ternary operator, are supported, operating like their \fBC\fP counterparts on \fIint\fP variables and/or values\&. .PP Additionally, for \fIstring\fP type variables and/or values the following operators are available: .IP o \fIa + b\fP: returns a new \fIstring\fP value containing the concatenation of \fIstring\fP values \fIa\fP and \fIb\fP\&. Note that \fIstring\fP constants may be concatetated without using the \fI+\fP operator, e\&.g\&., .nf \(dq\&hello \(dq\& \(dq\&world\(dq\& \(dq\&hello \(dq\& + \(dq\&world\(dq\& .fi .IP o \fIa += b\fP: \fIa\fP must be a \fIstring\fP variable, to which the \fIstring\fP variable or value \fIb\fP is appended\&. .IP o string comparisons: operators \fI== != <= >= < > !=\fP and \fI==\fP may be applied to \fIstring\fP values or variables, returning 1 if the comparison succeeds, otherwise 0\&. Comparison is case sensitively, and follows the \fIASCII\fP character set\&. .IP o \fI!a\fP: the boolean \fI!\fP operator returns 1 if the \fIstring a\fP is empty, otherwise 0 is returned\&. .IP o \fIa younger b, a newer b\fP: returns 1 if file \fIa\fP is more recent than file \fIb\fP\&. E\&.g\&., \fI\(dq\&source\&.cc\(dq\& newer \(dq\&source\&.o\(dq\&\fP\&. If \fIb\fP doesn\(cq\&t exist, 1 is returned; if \fIa\fP doesn\(cq\&t exist 0 is returned; if neither \fIa\fP nor \fIb\fP exists, 0 is returned; if they are of the same age, 0 is returned\&. Explicit tests for the existence of a file can be performed using the \fIexists()\fP predefined function (see below, section \fBPREDEFINED FUNCTIONS\fP)\&. .IP o \fIa older b\fP: turns 1 if file \fIa\fP is older than file \fIb\fP\&. E\&.g\&., \fI\(dq\&libprog\&.a\(dq\& older \(dq\&source\&.o\(dq\&\fP\&. If \fIa\fP doesn\(cq\&t exist, 1 is returned; if \fIb\fP doesn\(cq\&t exist 0 is returned; if neither \fIa\fP nor \fIb\fP exists, 0 is returned; if they are of the same age, 0 is returned\&. .IP o \fI[]\fP: the index operator is defined as an alternative to the built\-in function \fIelement\fP\&. It can only be applied (as holds true for \fIelement()\fP as well) as so\-called \fIrvalue\fP\&. Therefore, constructions like: .nf // assume str1 and str2 are strings str1 = str2[3] .fi will be accepted, but the following construction will not be accepted: .nf str2[3] = str; // won\(cq\&t compile .fi .PP For \fIlist\fP type variables and/or values the following operators are available: .IP o \fIa + b\fP: returns a new \fIlist\fP value containing the concatenation of \fIlist\fP values \fIa\fP and \fIb\fP\&. This is \fInot\fP a set operation: if an element appears both in \fIa\fP and in \fIb\fP, they will appear twice in the resulting list\&. .IP o \fIa \- b\fP: returns a new \fIlist\fP value containing the elements in \fIa\fP that are not present in \fIb\fP\&. This \fIis\fP a set operation\&. .IP o \fIa += b\fP: elements in \fIb\fP are added to the elements in \fIa\fP, which must be a \fIlist\fP variable\&. This is \fInot\fP a set operation\&. .IP o \fIa \-= b\fP: elements in \fIb\fP are removed from the elements in \fIa\fP, which must be a \fIlist\fP variable\&. This \fIis\fP a set operation\&. .IP o list equality comparisons: operators \fI!=\fP and \fI==\fP may be applied to \fIlist\fP values or variables\&. Operator \fI==\fP returns 1 if both lists have element\-by\-element identical elements, 0 otherwise\&. Operator \fI!=\fP reverses the result of \fI==\fP\&. .IP o \fI!a\fP: the boolean \fI!\fP operator returns 1 if the \fIlist a\fP is empty, otherwise 0 is returned\&. .IP o \fI[]\fP: the index operator is defined as an alternative to the built\-in function \fIelement\fP\&. It can only be applied (as holds true for \fIelement()\fP as well) as so\-called \fIrvalue\fP\&. Therefore, constructions like: .nf // assume lst is a list, str is a string str = lst[3] .fi will be accepted, but the following construction will not be accepted: .nf lst[3] = str; // won\(cq\&t compile .fi .PP Typecasts may be performed using the standard \fBC\fP cast\-operator to cast: .IP o Strings to ints and vice versa (\fI(int)\(dq\&123\(dq\&, (string)55\fP) .IP o Strings may be cast to lists (\fIlist lst = (list)\(dq\&hello\(dq\&\fP) .PP .SH "FLOW CONTROL" .PP \fBIcmake\fP offers the following subset of \fBC\fP\(cq\&s statement types\&. They can be used as in the \fBC\fP programming language\&. .IP o \fIexpression ;\fP .br The plain expression statement; .IP o The compound statement .br Different from \fBC\fP \fBicmake\fP does not support variable definitions inside a compound statement\&. All variables used locally by a function must be defined as either function parameters or as variables that are defined immediately at the beginning of a function\(cq\&s body\&. .IP o \fIif (condition) statement\fP .IP o \fIif (condition) statement else statement\fP .IP o \fIfor (init; condition; increment) statement\fP .br The variable(s) used in the initialization section must already have been defined\&. The \fIinit\fP, \fIcondition\fP and \fIincrement\fP sections may be left empty\&. The empty condition section is interpreted as `always \fItrue\fP\(cq\&\&. .IP o \fIwhile (condition) statement\fP .br The \fIdo \&.\&.\&. while()\fP statement is not implemented for \fBicmake\fP\&. .IP o \fIreturn\fP (for \fIvoid\fP functions) and \fIreturn expression\fP for other functions\&. .IP o \fIbreak\fP .br To leave \fIfor\fP and \fIwhile\fP statements, overruling the statement\(cq\&s condition\&. \fBC\fP\(cq\&s \fIcontinue\fP is not available\&. .IP o \fIexit(expression)\fP .br To terminate the \fBicmake\fP\-script\&. The \fIexpression\fP must evaluate to an \fIint\fP value, which becomes the script\(cq\&s exit value\&. .PP .SH "PREDEFINED FUNCTIONS" .PP \fBIcmake\fP offers the following predefined functions, which can be used immediately by \fBicmake\fP scripts\&. The function overview is ordered alphabetically by function name, but where appropriate short summary labels are provided: .PP Helper functions of \fIexec()\fP (see also below at \fIexec()\fP): .IP o \fIvoid arghead(string h)\fP .br Defines the `argument head\(cq\&, to be used with \fIexec()\fP\&. By default, the `argument head\(cq\& is an empty string\&. .IP o \fIvoid argtail (string t)\fP .br Defines the `argument tail\(cq\&, to be used with \fIexec()\fP\&. By default, the `argument tail\(cq\& is an empty string\&. .PP String\-to\-ascii converters: .IP o \fIint ascii(string s)\fP .br Returns the first character of \fIs\fP as an int; e\&.g\&., \fIascii(\(dq\&A\(dq\&)\fP returns 65; .IP o \fIstring ascii(int i)\fP .br Returns \fIi\fP as a string, e\&.g\&., \fIascii(65)\fP returns the string \fI\(dq\&A\(dq\&\fP; .PP System calls: .IP o The `backtick` operator (\fI`\fP) .br A string placed between two backticks is executed by the \fIpopen\fP(3) function\&. The standard output gererated by the command that is stored in the string argument is returned as a list\&. An empty list indicates that the command could not be executed\&. A command that could be executed but did not produce any output returns a list containing one empty element\&. The command\(cq\&s standard error stream output is not automatically collected\&. Standard shell redirection could be used to collect the standard error stream\(cq\&s output as well\&. Example: .nf string s = \(dq\&ls\(dq\&; printf(`s`); // prints the elements in the current // directory .fi .PP Filename modifiers: .IP o \fIstring change_base(string file, string newbase)\fP .br Changes the basename of \fIfile\fP, returns the changed name\&. E\&.g, \fIchange_base(\(dq\&/path/demo\&.im\(dq\&, \(dq\&out\(dq\&)\fP returns \fI\(dq\&/path/out\&.im\(dq\&\fP; .IP o \fIstring change_ext(string file, string newext)\fP .br Changes the extension of \fIfile\fP, returns the changed name\&. E\&.g, \fIchange_ext(\(dq\&source\&.cc\(dq\&, \(dq\&o\(dq\&)\fP returns \fI\(dq\&source\&.o\(dq\&\fP; .IP o \fIstring change_path(string file, string newpath)\fP .br Changes the path specification of \fIfile\fP, returns the changed name\&. E\&.g, \fIchange_path(\(dq\&tmp/binary\(dq\&, \(dq\&/usr/bin\(dq\&)\fP returns \fI\(dq\&/usr/bin/binary\(dq\&\fP\&. Note that the \fI/\fP\-separator is inserted if required\&. .PP System calls: .IP o \fIstring chdir(string newdir)\fP .br Changes the script\(cq\&s working directory, returns the previous dir as an absolute path\&. .br Use \fIchdir(\(dq\&\&.\(dq\&)\fP to get current working directory, \fIchdir(\(dq\&\(dq\&)\fP may be used to obtain the startup working directory (this functionality was broken in releases before than 7\&.00, but is now operational)\&. The function terminates the \fBicmake\fP\-script if the specified \fInewdir\fP does not exist\&. .IP o \fIstring chdir(int checking, string newdir)\fP .br Same functionality as the previous function, but by specifying \fIchecking\fP as \fIP_NOCHECK\fP the function won\(cq\&t terminate the script\&. Rather, it will return the script\(cq\&s current working directory\&. .PP Helper functions of \fIexec()\fP (see also below at \fIexec()\fP): .IP o \fIcmdhead(string h)\fP .br Defines a `command head\(cq\&, to be used with \fIexec()\fP\&. By default, the `command head\(cq\& is an empty string\&. .IP o \fIcmdtail(string t)\fP .br Defines a `command tail\(cq\&, to be used with \fIexec()\fP\&. By default, the `command tail\(cq\& is an empty string\&. .PP \fBIcmake\fP execution modifier: .IP o \fIecho(int opt)\fP .br Controls echoing of called programs (and their arguments), specify \fIOFF\fP if echoing is not requested\&. By default \fION\fP is active\&. .PP Functions returning elements of aggregates: .IP o \fIstring element(int index, list lst)\fP .br Returns string \fIindex\fP (0\-based) from \fIlst\fP\&. An empty string is returned if an unavailable index value is provided\&. See also the \fI[]\fP operator in the section \fBOPERATORS\fP\&. .IP o \fIstring element(int index, string str)\fP .br Returns character \fIindex\fP (0\-based) from \fIstr\fP\&. An empty string is returned if an unavailable index value is provided\&. See also the \fI[]\fP operator in the section \fBOPERATORS\fP\&. .PP System calls: .IP o \fIexec(string cmd, \&.\&.\&.)\fP .br Executes command with arguments\&. Each argument will be prefixed by \fIarghead()\fP\(cq\&s argument and postfixed by \fIargtail()\fP\(cq\&s argument\&. Note that no blanks are inserted between \fIarghead()\fP\(cq\&s contents, the argument proper, and \fIargtail()\fP\(cq\&s argument\&. All thus modified arguments are concatenated, this time separated by single blanks, and then \fIcmdhead()\fP\(cq\&s contents are inserted between the command and the first argument (on either side delimited by single blanks) and \fIcmdtail()\fP\(cq\&s contents are appended to the arguments (again, separated by a single blank)\&. \fIPATH\fP is searched to locate \fIcmd\fP\&. 0 is returned\&. .IP o \fIexec(int checkcmd, string cmd, \&.\&.\&.)\fP .br Same functionality as the previous function, but by specifying \fIchecking\fP as \fIP_NOCHECK\fP the function won\(cq\&t terminate the script\&. Rather, it will return the called command\(cq\&s exit status, or \fI0x7f00\fP if the command wasn\(cq\&t found\&. .IP o \fIexecute(string cmd, string cmdhd, string arghd, \&.\&.\&., string argtl, string cmdtl)\fP .br Same as \fIexec()\fP, but command head/tail and argument head/tail must be specified\&. The actually executed command starts with \fIcmd\fP, followed by \fIcmdhd\fP\&. Next is a series of arguments follows, each enclosed by \fIarghd\fP and \fIargtl\fP\&. The command terminates with \fIcmdtl\fP\&. 0 is returned .IP o \fIexecute(int checking, string cmd, string cmdhd, string arghd, \&.\&.\&., string argtl, string cmdtl)\fP .br Same functionality as the previous function, but by specifying \fIchecking\fP as \fIP_NOCHECK\fP the function won\(cq\&t terminate the script\&. Rather, it will return the called command\(cq\&s exit status, or \fI0x7f00\fP if the command wasn\(cq\&t found\&. ) .PP System interface: .IP o \fIint exists(string file)\fP .br Returns a non\-zero value if \fIfile\fP exists, otherwise 0 is returned\&. .PP Input interface: .IP o \fIlist fgets(string file, int offset)\fP .br The next line found at offet \fIoffset\fP is read from \fIfile\fP\&. It returns a list \fIretlist\fP containing two elements: .br \fIelement(0, retlist)\fP is the string that was read (including the \fI\en\fP, if found) .br \fIelement(1, retlist)\fP is the next offset to read\&. .br .IP An empty return list signifies \fIEOF\fP\&. Since an empty list\(cq\&s `first\(cq\& eement is an empty string, which is converted to the value 0, a file may be read and processed as follows: .nf list line; while (1) { line = fgets(\(dq\&filename\(dq\&, (int)line[1]); if (!line) break; process(line[0]); } .fi .PP Output interface: .IP o \fIint fprintf(string filename, \&.\&.\&.)\fP .br Appends all (comma separated) arguments to the file \fIfilename\fP\&. Returns the number of printed arguments\&. .PP Filename modifier: .IP o \fIstring get_base(string file)\fP .br Returns the base name of \fIfile\fP\&. The base name is the file without its path prefix and without its extension\&. The extension is all information starting at the final dot in the filename\&. If no final dot is found, the file name is the base name\&. Eg\&., the base name of \fIa\&.b\fP equals \fIa\fP, the base name of \fIa\&.b\&.c\fP equals \fIa\&.b\fP, the base name of \fIa/b/c\fP equals \fIc\fP\&. .PP System interface: .IP o \fIlist getenv(string envvar)\fP .br Returns the value of environment variable \fIenvvar\fP in a list containing two elements: .br the first element indicates whether the environment variable was defined (value \fI\(dq\&1\(dq\&\fP) or not (value \fI\(dq\&0\(dq\&\fP); .br the second element indicates the value of the environment variable\&. .IP Enivironment variables are of the form \fIvariable=value\fP, and if defined the list\(cq\&s second element contains \fIvalue\fP\&. If the value is empty, the variable is defined, but has no text associated with it\&. .PP Filename modifier: .IP o \fIstring get_ext(string file)\fP .br Returns the extension of \fIfile\fP, except for the separating dot\&. The extension is all information starting at the final dot in the filename\&. If no final dot is found, the extension is an empty string\&. .PP Input interface: .IP o \fIstring getch()\fP .br Returns the next pressed key as a string (no `Enter\(cq\& required for ms\-dos and unix (incl\&. linux) systems)\&. .PP Filename modifier: .IP o \fIstring get_path(string file)\fP .br Returns the path\-prefix of \fIfile\fP\&. The path prefix is all information up to (and including) the final directory separator (which is, depending on the operating system, a forward\- or backslash)\&. .IP If no path is found, an empty strring is returned\&. .PP System interface: .IP o \fIint getpid()\fP .br Returns the process\-id (UNIX) or PSP\-paragraph (DOS) of the icmake byte code interpreter \fBicm\-exec\fP\&. .PP Input interface: .IP o \fIstring gets()\fP .br Returns the next line read from the keyboard as a \fIstring\fP\&. The line entered on the keyboard must be terminated by an `Enter\(cq\& key, which is not stored in the returned string\&. .PP Functions creating lists of files: .IP o \fIlist makelist(string mask)\fP .br Returns a list of all files matching \fImask\fP\&. E\&.g\&., \fImakelist(\(dq\&*\&.c\(dq\&)\fP returns a list containing all files ending in \fI\&.c\fP\&. .IP o \fIlist makelist(type, string mask)\fP .br Same as the previous function, but the type of the directory elements may be specified as its first argument: .TS tab(~); ll ll ll ll ll c. symbol~meaning~ O_ALL~obtain all directory entries~ O_DIR~obtain all directories, including \&. and \&.\&.~ O_FILE~obtain a list of files~ O_SUBDIR~obtain all subdirectories~ .TE Note that the pattern \fI*\fP will not match hidden entries under Unix\-type operating systems\&. Use \fI\&.*\fP for that\&. .IP o \fIlist makelist(string mask, newer, string comparefile)\fP .br Returns list of all files matching mask which are newer than a provided comparefile\&. Operator \fIyounger\fP may be used instead of \fInewer\fP\&. Note that \fInewer\fP and \fIyounger\fP are operators, not strings\&. .IP o \fIlist makelist([int = O_FILE,] string mask, newer, string comparefile)\fP .br Same as the previous function, but \fItype\fP may be specified as in \fIlist makelist(type, string mask)\fP\&. .IP o \fImakelist(string mask, older, string comparefile)\fP .br See above; returns a list of files that are older than the comparefile\&. .IP o \fImakelist(type, string mask, older, string comparefile)\fP .br Same as the previous function, but \fItype\fP may be specified as in \fIlist makelist(type, string mask)\fP\&. .PP Output interface: .IP o \fIint printf(\&.\&.\&.)\fP .br Shows all (comma separated) arguments to screen (i\&.e\&., the standard output stream)\&. Returns the number of printed arguments\&. .PP System interface: .IP o \fIint putenv(string envvar)\fP .br Adds \fIenvvar\fP to the current (\fBicmake\fP) environment Use the format: \(dq\&VAR=value\(dq\&\&. Returns 0\&. .PP List information: .IP o \fIint sizeof(list l)\fP .br Returns the number of elements in \fIlist\fP .PP System information: .IP o \fIlist stat(string entry)\fP .br Returns \fBstat\fP(2) information of directory entry \fIentry\fP as a list\&. The returned list has two elements: element 0 is the \fIattribute value\fP, element 1 contains the size of the file\&. .IP Attributes are returned as bit\-flags, composed from the following predefined constants: .nf S_IFCHR S_IFDIR S_IFREG S_IREAD S_IWRITE S_IEXEC .fi See the \fBstat\fP(2) manual page for the meanings of these constants\&. .IP o \fIlist stat(checking, string entry)\fP .br Same as the previous function, but by specifying \fIchecking\fP as \fIP_NOCHECK\fP the function won\(cq\&t terminate the script\&. Rather, it will rturn \fBstat\fP(2)\(cq\&s return value\&. .PP String support: .IP o \fIint strlen(string s)\fP .br Returns the number of characters in \fIs\fP (not counting the final 0)\&. .IP o \fIint strfind(string haystack, string needle)\fP .br returns index in \fIhaystack\fP where \fIneedle\fP is found, or \-1 if \fIneedle\fP is not contained in \fIhaystack\fP\&. .br \fBThis function was called strstr() in versions before 7\&.00\fP\&. .IP o \fIstring strlwr(string s)\fP .br Returns a lower\-case duplicate of \fIs\fP\&. .IP o \fIlist strtok(string str, string separators)\fP .br Returns a list containing all substrings of \fIstr\fP separated by one or more (consecutive) characters in \fIseparators\fP\&. E\&.g\&., \fIstrtok(\(dq\&hello icmake\(cq\&s+world\(dq\&, \(dq\& +\(dq\&)\fP returns the list containing the three strings \fI\(dq\&hello\(dq\&\fP, \fI\(dq\&icmake\(cq\&s\(dq\&\fP, and \fI\(dq\&world\(dq\&\fP\&. .IP o \fIstring strupr(string s)\fP .br Returns an upper\-case duplicate of \fIs\fP\&. .IP o \fIstring substr(string text, int offset, int count)\fP .br Returns a substring of \fItext\fP, starting at \fIoffset\fP, consisting of \fIcount\fP characters\&. If \fIoffset\fP exceeds (or equals) the string\(cq\&s size or if \fIcount <= 0\fP, then an empty string is returned\&. If \fIoffset\fP is less than 0 then 0 is used\&. .PP System calls: .IP o \fIint system(string command)\fP .br Executes \fIcommand\fP\&. The return value indicates the executed command\(cq\&s exit value\&. The string \fIcommand\fP may contain redirection and/or piping characters\&. .IP o \fIint system(int checking, string command)\fP .br Same functionality as the previous function, but by specifying \fIchecking\fP as \fIP_NOCHECK\fP the function won\(cq\&t terminate the script\&. Rather, it will return the called command\(cq\&s exit status, or \fI0x7f00\fP if the command wasn\(cq\&t found\&. ) .PP .SH "USER DEFINED FUNCTIONS" .PP \fBIcmake\fP scripts may define functions, and a function \fImain()\fP \fImust\fP be defined\&. Functions must have the following elements: .IP o The function\(cq\&s return type\&. One of the available types must be used explicitly, e\&.g\&., \fIvoid\fP\&. There is no default type\&. .IP o The function\(cq\&s name, e\&.g\&., \fIcompile\fP\&. .IP o A parameter list, defining zero or more comma\-separated parameters\&. The parameters themselves consist of a type name followed by the parameter\(cq\&s identifier\&. E\&.g\&., \fI(string outfile, string source)\fP\&. .IP o A \fIbody\fP surrounded by a pair of curly braces (\fI{\fP and \fI}\fP)\&. .IP Function bodies may contain (optionally initialized) variable definitions\&. Variable definitions start with a type name, followed by one or more comma separated (optionally initialized) variable identifiers\&. If a variable is not explicitly initialized it is initialized by default\&. An \fIint\fP variable is initialized to 0, a \fIstring\fP is initialized to empty text (\fI\(dq\&\(dq\&\fP) and a \fIlist\fP is initialized to a list of zero elements\&. .IP Following variable definitions, bodies may contain zero or more statements (see below at section \fBFLOW CONTROL\fP for the various flow\-control statements)\&. Note that all local variables must be defined at the very beginning of function bodies\&. .PP User defined functions must be defined before they can be used, although they may be called recursively\&. Therefore, indirect recursion is not supported by \fBicmake\fP\&. .PP The user\-defined function \fImain()\fP has three optional arguments, which may be omitted from the last one (\fIenvp\fP) to the first (\fIargc\fP), as in \fBC\fP\&. Its full prototype is (note: \fBvoid\fP return type): .nf void main(int argc, list argv, list envp) .fi In \fImain()\fP, .IP o \fIargc\fP represents the number of elements in \fIargv\fP; .IP o \fIargv\fP contains the arguments, with element 0 the compiled \fBicmake\fP script (the `\fI\&.bim\fP\(cq\& file); .IP o \fIenvp\fP containts the `environment\(cq\& variables\&. The function \fIsizeof()\fP (see below) may be used to determine its elements\&. Elements in \fIenvp\fP have the form \fIvariable=value\fP\&. Alternatively, the function \fIgetenv()\fP (see below) can be used to retrieve a specific environment variable immediately\&. Example: .nf void main(int argc, list argv) { list toCompile; int idx; if (argc == 1) usage(element(0, argv)); if (toCompile = altered(\(dq\&*\&.cc\(dq\&)) { for (idx = sizeof(toCompile); idx\-\-; ) compile(element(idx, toCompile)); if (getenv(\(dq\&dryrun\(dq\&)[0] == \(dq\&0\(dq\&) linking(element(2, argv)); } exit (0); } .fi .PP .SH "FILES" .PP The mentioned paths are sugestive only and may be installation dependent: .IP o \fB/usr/bin/icmake\fP: the main \fBicmake\fP program; .IP o \fB/usr/bin/icmun\fP: the \fBicmake\fP unassembler; .IP o \fB/usr/lib/icm\-pp\fP: the preprocessor called by \fBicmake\fP; .IP o \fB/usr/lib/icm\-comp\fP: the compiler called by \fBicmake\fP; .IP o \fB/usr/lib/icm\-exec\fP: the byte\-code interpreter called by \fBicmake\fP; .PP .SH "EXAMPLES" .PP The distribution (usually in \fI/usr/share/doc/icmake\fP) contains a directory \fIexamples\fP containing various examples of \fBicmake\fP script\&. Note in particular the \fIexamples/icmbuild\fP subdirectory containing a general script for \fBC++\fP and \fBC\fP program maintenance\&. .PP .SH "SEE ALSO" \fBicmbuild\fP(1), \fBicmconf\fP(7), \fBicmstart\fP(1), \fBicmstart\&.rc\fP(7), \fBmake\fP(1) .PP .SH "BUGS" None reported .PP .SH "COPYRIGHT" This is free software, distributed under the terms of the GNU General Public License (GPL)\&. .PP .SH "AUTHOR" Frank B\&. Brokken (\fBf\&.b\&.brokken@rug\&.nl\fP)\&. .PP