icmake-9.02.06/bootstrap/0000755000175000017500000000000013176557635014144 5ustar frankfrankicmake-9.02.06/bootstrap/flags0000644000175000017500000000045613176557635015170 0ustar frankfrank# sourced by the various bootstrap functions if [ ! -e ../tmp/INSTALL.sh ] ; then echo ../tmp/INSTALL.sh does not exist. Try running the icm_prepare script exit 1 fi . ../tmp/INSTALL.sh if [ "${CFLAGS}" == "" ] ; then CFLAGS="-Wall -O2" fi if [ "${CC}" == "" ] ; then CC="gcc" fi icmake-9.02.06/bootstrap/functions0000644000175000017500000000133613176557635016102 0ustar frankfrank# sourced by the various icm_bootstrap shell scripts try() { # echo $* $* || exit 1 } build() { program=$1 shift rm -f *.o */*.o NR=1 for x in $* ; do try cd $x echo -n . try ${CC} ${CFLAGS} -c *.c for file in *.o do try mv $file ${NR}$file done try cd .. let NR=${NR}+1 done echo -n . try ${CC} ${CFLAGS} -c *.c echo -n . try ar crs ../tmp/lib${program}.a */*.o echo -n . try ${CC} -o ../tmp/${LIBDIR}/${program} *.o -l${program} -licrss \ -L../tmp ${LDFLAGS} echo -n . rm *.o */*.o ../tmp/lib${program}.a echo . } icmake-9.02.06/build0000755000175000017500000000132613176557635013156 0ustar frankfrank#!/bin/bash action=$1 if [ "$action" == "distclean" ] ; then echo rm -rf tmp rm -rf tmp action=clean fi if [ "$action" == "clean" ] ; then for dir in rss comp exec pp dep un icmake icmbuild do cd $dir echo -n "cd $dir; " build clean cd .. done exit 0 fi if [ ! -e tmp/INSTALL.im ] ; then if [ "$action" == "" ] ; then echo " First run ./icm_prepare, specifying a base directory for icmake (e.g. /), or restart $0, and specify a base directory as its first command-line argument " exit 1; fi ./icm_prepare $action fi for dir in rss comp exec pp dep un icmake icmbuild do cd $dir echo $dir build || exit 1 cd .. done icmake-9.02.06/changelog0000644000175000017500000006775613237047074014013 0ustar frankfrankicmake (9.02.06) * Fixed icmbuild's install command wrt installing libraries -- Frank B. Brokken Wed, 31 Jan 2018 16:17:49 +0100 icmake (9.02.05) * Removed an error (#-lines are comment) in the icmconf(7) man-page -- Frank B. Brokken Thu, 25 Jan 2018 09:05:47 +0100 icmake (9.02.04) * DEFCOM lines are not anymore appended to existing 'icmconf' files if its Replace request is answered by k or N. -- Frank B. Brokken Sun, 10 Dec 2017 09:17:54 +0100 icmake (9.02.03) * stdarg.h is needed in rss.h: inclusion moved from rss.ih to rss.h * updated the usr/share/icmake/icmconf file -- Frank B. Brokken Thu, 02 Nov 2017 09:18:16 +0100 icmake (9.02.02) * Fixed an annoying typo in [/usr/lib/icmake/]icmbuild. Do not use 9.02.01 -- Frank B. Brokken Tue, 01 Nov 2016 13:40:42 +0100 icmake (9.02.01) * Fixed a flaw in [/usr/lib/icmake/]icmbuild: when DEFCOM "library" was defined in icmconf, and precompiled headers were requested, then MAIN had to be defined as well. This is not required anymore. -- Frank B. Brokken Tue, 01 Nov 2016 09:54:11 +0100 icmake (9.02.00) * icmbuild now is a small program, providing help or starting the icmbuild script in LIBDIR (cf. INSTALL) * Man-pages were updated * Cosmetic changes to icmake --help's output * The name of the optional configuration file YEAR was changed to YEARS (as it defines YEARS, not YEAR) * `icmconf' was added to /etc/icmake/icmstart.rc * As mentioned in icmake's man-page the program `icmun' is mainly used in some specific situations. In icmake's daily practice it isn't used. Therefore it was moved from the standard binary programs directory to icmake's LIB directory (commonly /usr/lib/icmake). * The file /etc/icmake/icmake.rc was nowhere used and was removed. -- Frank B. Brokken Sun, 25 Sep 2016 12:36:07 +0200 icmake (9.01.00) * Man-pages weren't properly updated at 9.00.00. This was fixed in this release. -- Frank B. Brokken Sat, 03 Sep 2016 15:10:43 +0200 icmake (9.00.00) * Added support program icm-dep computing dependencies for USE_ALL classes and precompiled headers, called from /usr/bin/icmbuild, or directly using icmake's option --icm-dep (-d) * Icmake supports several long options in addition to the standard short options. See icmake(1) for details. * Changed references to IS_* into O_* in icmake(1)'s man-page. The IS_ entries were already unavailable, but the man-page still referred to them. Now fixed. * Contents of lines in CLASSES beyond the first word are no longer interpreted. * Added new option NO_PRECOMP_WARNING to icmconf * Option -b was removed from icmake. * The built-in function makelist(mask, [younger,older], referencefile) is now operational (was mentioned in icmake's man-page, but wasn't implemented before). * Repaired a bug in substr that could segfault. * Man-pages updated. Icmbuild(1) contains a description of the icm-dep program. -- Frank B. Brokken Sat, 23 Jul 2016 20:55:33 +0200 icmake (8.01.00) * Added builtin functions 'strchr', 'listfind', and 'listunion'. See 'man icmake' for details. * Fixed a bug in icmake's option handling due to which options could not be forwarded to called scripts. * Fixed a bug in the compilation of ternary expressions: the condition wasn't explicitly converted to bool, causing constructions like 'ret = fun() ? ...' to fail. * The 'icmstart' script was modified, improving control over which files should initially be installed (see 'man icmstart' and 'man icmstart.rc' for details. * Icmake's predefined function stat(P_NOCHECK, entry) returns, if `entry' does not exist, a list having two elements: list[0] == 0, list[1] == -1. * The builtin function 'getch()' now prints one newline character when the user presses 'Enter' (previously 2 newlines were printed). * The main() function must have return type 'void' (this was already required in earlier versions, but is now enforced). * When defining executable icmake scripts using #!/usr/bin/icmake -t -t. indicates that the temporary .bim file must be defined in icmake's temporary directory, using icmake's pid and the .bim suffix as its filename. * When PARSER-related specifications are not used, they can all be removed from 'icmconf' files. * When SCANNER-related specifications are not used, they can all be removed from 'icmconf' files. * Support for using 'grambuild' (superfluous since 2008) was removed from 'icmbuild' * Updated the manpages and examples (examples now use -t. rather than -qt /tmp/...) -- Frank B. Brokken Sat, 13 Feb 2016 13:40:10 +0100 icmake (8.00.05) * Fixed typo in the icmconf manpage: #define PRECOMP "-x c++-headers" must be #define PRECOMP "-x c++-header" * Fixed a bug in the implementation of the '#undef IDENTIFIER' preprocessor directive causing intermittend errors on amd64 architectures: instead of removing the entry from the table of defined identifiers the id of the item to undefine is simply changed into an empty string. A bit of a kludge, but it solves the problem. -- Frank B. Brokken Mon, 21 Dec 2015 14:12:03 +0100 icmake (8.00.04) * Fixed handling of line continuation backslashes (\$) in icm-pp -- Frank B. Brokken Fri, 11 Dec 2015 22:01:51 +0100 icmake (8.00.03) * Fixed an erroneously placed variable definition in icmbuild.in * Fixed too late assignment of a function's address into its symtab record due to which functions could not recursively be called. icmake (8.00.02) * Fixed a leftover size_t / unsigned mismatch on amd64 architectures. -- Frank B. Brokken Tue, 08 Dec 2015 19:23:40 +0100 icmake (8.00.01) * Fixed size_t / unsigned mismatches on amd64 architectures. * Applied patches provided by Tony Mancill. Thanks, Tony :-) -- Frank B. Brokken Tue, 08 Dec 2015 10:55:36 +0100 icmake (8.00.00) * This release adds several new builtin functions, which required a redefinition of the builtin function codes. Because of this existing .bim files must be recompiled from their .im source files. * Martin Dorwig suggested several additions to icmake's run-time support functions. In particular facilities for formatted string construction and formatted printf functions. Many of his suggestions were implemented in version 8.00.00, which now offers several new built-in functions (get_dext, length, resize, strformat, trim, trimleft, trimright (see icmake(1) for details)). * The functions fprintf and printf now support a format string as their first argument, in which %-notations refer to subsequent argument numbers (see icmake(1) for details). * The 16 bit offset limit was removed from fgets. Also, fgets's signature changed. See icmake(1) for details. * Added the 'continue' statement/keyword to the flow constrol statements. It can be used inside while and for statements. * Added the ternary operator (?:) to the set of supported operators. * Global variable initialization can now use expression statements, not just constant expressions. * Local variables can be defined and immediately initialized anywhere inside functions. Multiple local variables (of the same type) can be defined in the initialization section of a for-statement, A single variable can be defined in the condition clause of if- and while-statements. If not explicitly initialized such variables represent a `false' condition. * Character constants are supported and are converted to single-character string constants. Conversely, single-character string constants can be used in int-expressions. In that case their values are equal to the int-values of their (first) characters. * The main() functions in icmake scripts now by default return 0. * Fixed a bug in the printf family of functions: these functions now return the number of printed arguments (as documented in icmake(1)'s man-page). * Fixed a bug in handling decrement and increment operators: previously their resulting wasn't pushed on the stack when used in return statements, causing a stack underflow. * Fixed a bug in the icm-pp precompiler: multiple #defines of the same identifier are not accepted anymore. Multple #undefines are OK, but an #undefine generates a warning if it doesn't refer to a currently #defined identifier. * Drive specifiers are not supported anymore * The function glob() is now assumed available. * The internal code organization in the rss, icm-pp, icm-comp, and icm-exec directories was significantly changed. Code belonging together is now collected in its own subdirectory, where the subdir-name is used as first part of the name of `public' functions (but their source names do not start with the subdir name. E.g. symtab_push is found in symtab/push.c). Support functions inside a directories start with an abbreviated subdir-name, both in their names and in their source filenames (e.g., st_addVar is found in symtab/staddvar.c). Also, within subdirectories 'dirname.ih' files contain all declarations that are required only by the sources in that directory, while 'dirname.h' files contain all declarations required by other parts of icmake programs that use the subdirectory's `public' functions. Because of this reorganization several old files (like rss/ic*h files) became obsolete and were removed. * The -q and -b options are not supported anymore. * The -e option replaces the previously defined -b option. * The -v option shows icmake's version to the standard output stream (terminating icmake). * The -F flag shows which files, and flags are used by icmake, and which actions are going to be performed. * The -T flag can be used to specify a non-default destination directory for temporary files (by default /tmp or (if not available) $HOME is used). -- Frank B. Brokken Sun, 29 Nov 2015 18:35:22 +0100 icmake (7.23.02) * Wow! After > 20 years being used, Martin Dorwig found a bug in icm_pp's getident() function: it didn't accept digits in identifiers. It's fixed in this release, now implementing the standard definition of an identifier. -- Frank B. Brokken Fri, 16 Oct 2015 14:46:41 +0200 icmake (7.23.01) * Overlooked checking for PRECOMP in icmbuild's precompile() function. Now fixed. -- Frank B. Brokken Thu, 15 Oct 2015 16:45:39 +0200 icmake (7.23.00) * Updated CXXFLAGS in generated icmconf files to contain --std=c++14 * Added the define //#define PRECOMP "-x c++-header" to icmconf files. When activated, internal header files are precompiled when they are more recent than their precompiled versions. * Added the define #define IH ".ih" to icmconf files, specifying the extension of internal header files. It is used by PRECOMP. * Reorganized the #defines in the icmconf mold file so that related #defines are easily recognized. -- Frank B. Brokken Thu, 15 Oct 2015 14:52:21 +0200 icmake (7.22.01) * The `ar' program in binutils >= 2.25.7 generates a warning when the u modifier is used in combination with the r option. Icmake's icmbuild script previously used 'ar cru'. To prevent the warning, 'ar cr' is now used. -- Frank B. Brokken Sat, 16 May 2015 20:35:40 +0200 icmake (7.22.00) * `icmstart dir library' uncomments the library construction spec. and comments out the main.cc spec. in icmconf * `icmstart -b ...' (basic installation), won't install the default VERSION, usage.cc and version.cc files * `icmstart -b ...' and `icmstart ... library comments out the line #define USE_LIBRARY in icmconf. * The default g++ compiler flags now specify c++14 * Added the file 'required' summarizing the software which was used for building icmake. * The entry //#define EXTENSION ".exe" was removed from INSTALL.im as it's apparently no longer required for systems like cygwin. In cases the .exe extension is needed, rename the binaries accordingly after building them. * Removed -D__STDC_VERSION__=199901L from the flex call in ./comp/build -- Frank B. Brokken Tue, 20 Jan 2015 15:53:40 +0100 icmake (7.21.01) * By default, ./icm_bootstrap no longer specifies -g when compiling icmake's sources. If you *want* to use the -g flag, define an environment variable CFLAGS. E.g., CFLAGS="-Wall -O2 -g". * Applied Colin Herbert's patches (to see Colin's patches use the prefix https://gist.github.com/ColinHebert/): Removed the redundant definition of __STDC_VERSION__ from lexer.c: 1377507/raw/545a60cb39105c80d97e543dc77e00ab7ecbb5ff/lexer.c.diff Removed the hard coded path to CONFDIR: 1377533/raw/c7cb3f768deafa8c2e393bed1f5d4acd42edc7bd/icm_install.diff * The above changes were suggested by Florian Franzen. Thanks! -- Frank B. Brokken Mon, 20 Jan 2014 11:00:27 +0100 icmake (7.21.00) * Repaired segfaults found in icmake, icm-exec, and icmun by Alexandre Reber. -- Frank B. Brokken Tue, 30 Jul 2013 16:49:58 +0200 icmake (7.20.00) * added missing '\n' to the strtok call in icmbuild's 'dependenciesOf' function * line continuation in CLASSES results in one line being counted in the icmbuild script. * Added suggestions by Johann 'Myrkraverk' Oskarsson about compiling icmake on solaris (in ./contributions/solaris) -- Frank B. Brokken Sat, 09 Mar 2013 14:48:45 +0100 icmake (7.19.00) * build scripts for constructing icmake now support the CC environment flags as well. CC defines the C-compiler to use. * icmbuild script's COMPILER and COMPILER_OPTIONS variables should be considered obsolete, and are overruled by CXX and CXXFLAGS, defining the C++ compiler and flags or CC and CFLAGS, defining the C compiler and flags in that order. -- Frank B. Brokken Mon, 16 Jul 2012 15:39:52 +0200 icmake (7.18.00) * Fine-tuned icmbuild so that only used USE_ALL files are removed instead of all files named so * The initial program files installed by default by icmstart assume that the flexc++ scanner generator (0.93.00) and the bisonc++ parser generator (>= 3.00.00) is available. * The documentation about class dependency handling was improved -- Frank B. Brokken Wed, 22 Feb 2012 14:06:48 +0100 icmake (7.17.00) * Changed (mproved/repaired) the directory dependencies handling (as defined in CLASSES) by icmbuild.in; improved the readability of icmbuild's output. * Updated YEAR(S) information in VERSION and ./usr/share/icmake/version.cc to 2012. -- Frank B. Brokken Tue, 03 Jan 2012 17:39:28 +0100 icmake (7.16.01) * Removed erroneous -o from '-fPIC -o' in icmbuild at line 450 in icmbuild.in -- Frank B. Brokken Wed, 28 Sep 2011 20:41:33 +0200 icmake (7.16.00) * `icm_bootstrap' script now recognizes CFLAGS and LDFLAGS environment variables for, resp. gcc and ld flags. * icmbuild script now correctly interprets class dependencies defined in CLASSES and correctly interprets USE_ALL (see `man icmconf') * `icmbuild' script now recognizes (configurable) CXXFLAGS and LDFLAGS for, resp. g++ and ld flags. Default values are defined in the program's 'icmconf' file. * By default the COMPILER setting now includes --std=c++0x and -Wall, preventing accidental omission by CXXFLAGS. * The default file name suggested for USE_ALL is 'a' (e.g., class/a) * Documentation was updated (in particular the `icmconf' man-page) -- Frank B. Brokken Fri, 24 Jun 2011 20:29:38 +0200 icmake (7.15.00) * AUTHOR, VERSION and YEAR removed from /etc/icmake, see icmstart(1) * Double installation of changelog.gz prevented * /usr/share/doc/icmake/mail.frank removed from the installation * icmstart.rc supports optional P and L flags for program and library only icmake project installations. See icmstart.rc(7) * Using standard x.yy.zz version number format -- Frank B. Brokken Mon, 14 Feb 2011 20:56:28 +0100 icmake (7.14.1) * Added test for defined SHAREDREQ to icmbuild -- Frank B. Brokken Mon, 17 Jan 2011 20:29:51 +0100 icmake (7.14.0) * Repaired segfault error caused by calling an underfined function (comp/callfun.c) * Removed compiler warning about dangerous casts from comp/outcode.c and comp/patchup.c by defining a union for char[2] and int16_t, rather than casting the char[2] to int16_t. * Defined icm_prepare, called from icm_bootstrap and rss/build to prepare the tmp/ directory * The separate 'build' icmake scripts were still expecting librss.a. Changed to the proper library name: libicrss.a * Modified the shared library construction function to use the linker flag --as-needed, repaired the 'defs' flag spelling (was: def), added the icmconf entry SHAREDREQ to contain the names and paths of libraries required by the shared library, and the shared library construction is now using COMPILER (rather than gcc) to construct the shared library with. * added the `ALL' facility to icmbuild, allowing the specification of a class dependency graph in the CLASSES file. * Added the icmconf(7) man page -- Frank B. Brokken Fri, 14 Jan 2011 13:19:59 +0100 icmake (7.13.1) * Manpages in release 7.13.0 were not refreshed. Now repaired. -- Frank B. Brokken Sun, 03 Oct 2010 14:42:48 +0200 icmake (7.13.0) * the icmconf file has a (default not active) #define REFRESH that may be activated when a binary program is created. When active a new binary is always created even if no source was compiled. This may be useful when the program uses a library that is actively under development and is frequently changed. * the icmbuild script offers the option -c doing a 'tput clear' (clear screen) just before starting the build process. The icmconf #define CLS, by default not active, accomplishes the same. * /etc/icmake/VERSION contains 2010 -- Frank B. Brokken Sat, 02 Oct 2010 15:52:09 +0200 icmake (7.12.5) * added missing test for modified SCANSPEC (lexer) file in scripts/icmbuild. -- Frank B. Brokken Wed, 23 Dec 2009 10:44:30 +0100 icmake (7.12.4) * repaired lacking directory recognition in scripts/icmstart.im * removed `return 0;' from usr/share/icmake/main.cc as 0 is returned by default * replaced endl by `\n' in usr/share/icmake/usage.cc * changed the location of the main repository in make/about.c -- Frank B. Brokken Tue, 22 Dec 2009 14:53:53 +0100 icmake (7.12.3) * applied the patch given in Debian bug report #537574 -- Frank B. Brokken Wed, 29 Jul 2009 13:22:13 +0200 icmake (7.12.2) * icmbuild touches 'version.cc' only if it exists. * The built-in function 'gets()' will now remove a trailing \n as per the icmake man-page -- Frank B. Brokken Fri, 17 Jul 2009 13:20:33 +0200 icmake (7.12.1) * icm-pp supports the #undef directive * updated icmake's release year to 1992-2009. * library construction contains code to create a shared library as a new option that can be specified in icmconf * the top-level directory has been reorganized. See INSTALL and QUICKINSTALL for details. Icmake's initial construction uses `icm_bootstrap' and prepares an icmake installation under ./tmp/ * installation of (parts of) icmake constructed by `icm_bootstrap' is done using `icm_install'. * added `where-is-what' giving an overview of what the various top-level files and directories are for. * configuration files for icmstart are found in the following locations (in order, accepting the first file(s) found: (1) determined by -c (2) in $HOME/.icmake (3) found in /etc/default/icmake. * the previously used `def/destinations' file is not used anymore. * the file `icmconf' has been modified (see icmbuild(1)), allowing, e.g., multiple lexical scanner specification files. * documentation adapted. * new man-page: icmstart.rc(7). -- Frank B. Brokken Tue, 14 Apr 2009 13:00:51 +0200 icmake (7.11.1) * Introduced a three-digit version number: major, minor and subreleases. * Updated icmbuild sources to 2008. * The Gnu g++ flags for the upcoming c++0x standard are now mentioned in icmconf. icmake (7.11) * Fixed missing dead[0] initialization in comp/icm-comp.c Fixed handling of C and C++ comment in strings in icm-pp: The preprocessor now keeps C/C++ comment in string/character constants in #defines allowing for constructions like #define PAT "dir/*" which in earlier versions resulted in an unterminated C comment error. The icmstart and icmbuild scripts are now bisonc++ >= 2.0.0 aware, and grambuild is now effectively superfluous (but still available) Added #define EXTENSION to def/destinations to allow easy compilation in cygwin environments The script icmscripts.sh can be used to recreate the icm-scripts in the bin/ subdirectory. Primarily useful for maintenance. The 'unix' script no longer by default constructs stripped versions of the binary programs, the install.sh by default installs unstripped binaries. The argument 'strip' may be provided to strip the binaries. icmake (7.10) * Removed Superfluous #defines from icm.h #define values may extend over multiple lines, using the \ character as the last character on the line to indicate line-continuation. Applied size_t where applicable, using unsigned otherwise to prevent problematic behavior on some 64 bit architectures. Changed many old-style classic C parameter lists into ANSI C style parameter lists Minor textual repairs to the manual pages. Added the option to compile with extensive compiler flags in the top-level build script. MSDOS is no longer suported by specific code. icmake (7.02) * Repaired a misconfiguration in the bootstrap.sh and install.sh scripts due to which the icmstart and icmbuild scripts weren't properly installed. -- Frank B. Brokken Wed, 21 Feb 2007 14:49:23 +0100 icmake (7.01) * The INSTALL file was updated. So were the scripts bootstrap (now named bootstrap.sh) and unix. Compilation warnings appearing on Mac OS-X were as good as possible removed, some old files and directories were removed or placed in a directory of their own. -- Frank B. Brokken Wed, 07 Feb 2007 15:50:33 +0100 icmake (7.00) * The subdirectory examples is renamed to templates [Above change: Mon, 05 Feb 2007 16:09:46 +0100] Defines (#define) may use other #defined variables to determine their value. icmake's sources may use hexadecimal constants (0xdead) global and local variables may be immediately initialized by constants and/or available functions. Variables cannot be used for the initialization. execute() function repaired: it never succeeded due to invalid return value initial source may or may not have .im extension, as suggested in the general usage info provided by icmake itself. If the specified initial source does not exist, an .im extension is attempted. The IM environment variable may contain several, `:'-delimited paths getenv() implemented: returns list: [0]: ok (or not), [1]: value of the environment variable strlen/strupr/strlwr now defined as rss-functions, no longer as macros strstr renamed to strfind. substr() added, returning a substring from an existing string. (f)printf() now have int-return values (instead of undefined) icmake manual page rewritten added icmbuild script for general program maintenance added icmbuild manual page added icmstart script to start an icmake maintenance project using icmbuild added icmstart manual page the `unix' script will regenerate the parser and the lexical scanner if their specification files have changed. [Above changes: Tue, 21 Sep 2006 14:31:43 +0200] icmcomp uses a resizing rather than a fixed sized buffer to store strings found in an icmake script (used to be a fixed-sized buffer of 100 chars, causing icmcomp to segfault with, e.g., long option lists) -- Frank B. Brokken Sat, 18 Nov 2006 10:34:13 +0100 The type `unsigned' was changed to `size_t' where appropriate Fixed some flaws in the `unix' script, and (??) added icm-exec.c to my local icmake svn repository Added icmstart script to start an icmake project in some subdir Global strings weren't initialized to empty strings. Now they are. -- Frank B. Brokken Sat, 04 Nov 2006 17:41:32 +0100 icmake (6.30) Debian patches up to 6.22-7 processed; more in general: the sources now compile free of warnings chdir("") now returns initial working directory Execution error on the powerpc repaired. Caused by strcmp() sometimes returning a non-zero value having its lowest 16 bits equal to zero. Since icmake internally uses 16-bits int values, this results in a zero value following an int to int16 assignment. See, e.g., exec/string/compare.c During the process of repairing the above error, Icm-exec was completely rewritten. Lintian warning about an error in the icmake.1 manual page repaired Lindian warning about the inappropriate executable mode of examples/defines.im repaired. Newer versions of icmake programs operate fine on existing (older) binary scripts as long as icmake's major version isn't upgraded. Newer versions of binary icmake files remain to be inexecutable with older icmake versions. PRE-ANNOUNCING VERSION 7.00: A major upgrade (to version 7.00) will be released soon. As a prelude: it will define new built-in functions: getenv() and substr() will be completely new, and strstr() will be replaced by the new function strfind(). Existing scripts defining getenv(), substr() and/or strfind() should rename these functions to, e.g., my_getenv() (and comparable) or (possibly) remove these definitions and use the new built-in functions. The distiction between distribution version and program version (see below) is removed. All programs will have the same version as the distribution. NOTE: The version referred to here is the version of the distribution, not of the icmake programs. 6.22 Compiler warnings and the use of gets() removed from the sources All programs now use the same version, which is defined in version.c, which is defined in the rss. Standard manpage (icmake.1) included in the distribution. 6.21 Elf binaries for unix 6.20 Unix-icmake accepts the -t flag, to specify a temporary binary- icmake file. Allowing in unix-environments the riddance of the permanent bim-file. The temporary binary makefile will --in this case-- get the process-id for its extension. 6.18 - 6.19: Not distributed. 6.17b DOS-distribution only: Dependencies on icce.h and sicce.lib removed from the distribution. Programs are *not* affected by this distribution. 6.17 Comment accepted in #define directives, Trailing info on #include lines ignored, Minor changes to documentation files. 6.17 This is as far as our memory reaches: the log of changes before this distribution are lost to future generations... This release never made sunsite or tsx-11. Only ftp.icce.rug.nl got it, and two sub-releases beyond. icmake-9.02.06/comp/0000755000175000017500000000000013232314221013034 5ustar frankfrankicmake-9.02.06/comp/updatescanner0000755000175000017500000000013313176557635015644 0ustar frankfrank#!/bin/bash cd scanner flex -o lexer.c lexer || exit 1 echo generated new scanner icmake-9.02.06/comp/symtab/0000755000175000017500000000000013232314221014333 5ustar frankfrankicmake-9.02.06/comp/symtab/setfunparams.c0000644000175000017500000000116213176557635017240 0ustar frankfrank /* #define msg */ #include "symtab.ih" /* local vars so far are parameters. */ void symtab_setFunParams() { FunInfo *info = st_lastFunInfo(); /* set the fun's # params */ info->nParams = gs_vars.nParams = gs_vars.varTab[1].nVars; /* room for the parameter types */ info->paramType = rss_realloc(NULL, gs_vars.nParams * sizeof(ExprType)); /* assign the parameter types */ for (unsigned idx = 0; idx != gs_vars.nParams; ++idx) info->paramType[idx] = st_paramType(idx); } icmake-9.02.06/comp/symtab/stdeletevars.c0000644000175000017500000000034113176557635017233 0ustar frankfrank#include "symtab.ih" void st_deleteVars(VarTab *varTab) { for (VarInfo *info = varTab->info; varTab->nVars--; ++info) free(info->name); varTab->nVars = 0; /* 0 variables left at variable table *varTab */ } icmake-9.02.06/comp/symtab/symtab.ih0000644000175000017500000000726413176557635016216 0ustar frankfrank#include "symtab.h" #include #include #include #include "../global.h" #include "../util/util.h" enum { capacityInc = 10 }; typedef struct { char *name; uint16_t address; unsigned nParams; ExprType *paramType; /* nParams elements */ ExprType returnType; } FunInfo; typedef struct { FunInfo *info; unsigned nFunctions; unsigned capacity; } FunInfoTab; extern FunInfoTab gs_functions; /* symbol table for functions */ int st_findFun(void const *key, void const *funInfo); typedef struct { char *name; uint16_t value; ExprType type; } VarInfo; typedef struct { VarInfo *info; unsigned nVars; unsigned capacity; } VarTab; typedef struct { unsigned *index; unsigned nVars; unsigned capacity; } VarIndices; typedef struct { VarTab *varTab; /* points to global [0] or local [1] vars */ unsigned nParams; /* the number of parameters of the function currently being defined */ VarIndices *varIndices; /* level 0 holds indices of global vars */ unsigned nLevels; /* at least 1: the global level */ unsigned capacity; } VarRef; extern VarTab *gs_compareTable; /* set by st_findVar for st_compareVars to gs_global or gs_local */ extern VarRef gs_vars; /* OLD: VarRef objects per nesting level. At each nesting level a new VarRef is used allowing access to the VarInfo records of variables that are defined at that level. At the end of a function gs_level is reset, and gs_local contains the info of all variables that are locally defined, allowing the frame to be constructed */ unsigned st_nextFunIdx(void); /* idx of an uninitialized record of a function */ FunInfo *st_lastFunInfo(); /* ptr to the last FunInfo record */ unsigned st_nestingOffset(void); VarIndices *st_topLevel(void); VarTab *st_varTab(unsigned nesting); /* vartab to use, given nestinglevel */ int st_compareVars(void const *key, void const *idxPtr); /* compare key to entry in gs_compareTable */ int st_findVar(unsigned nesting); /* find util_string() in vars indexed at gs_vars.indices[nesting]. return idx in VarTab.info or -1 */ VarIndex st_addVar(ExprType type); /* add variable to the topmost symbol table */ unsigned st_nextVarIdx(VarInfo **vi); /* return idx of next variable, and set a ptr to its record using RBA */ ExprType st_paramType(unsigned idx); /* returns type of parameter idx */ unsigned *st_newIdxPtr(void); /* pointer to the next available index[] */ unsigned st_newVarIdx(void); /* idx of an uninitialized record of a new variable */ VarTab *st_varTab(unsigned nesting); /* return the variable table matching the currrent nesting level (global or local) */ void st_deleteVars(VarTab *varTab); /* delete all info allocated by VarInfo objects */ icmake-9.02.06/comp/symtab/stcomparevars.c0000644000175000017500000000030513176557635017417 0ustar frankfrank#include "symtab.ih" int st_compareVars(void const *key, void const *idxPtr) { return strcmp((char const *)key, gs_compareTable->info[*(unsigned const *)idxPtr].name); } icmake-9.02.06/comp/symtab/writeglobals.c0000644000175000017500000000064513176557635017233 0ustar frankfrank#include "symtab.ih" /* Global variables are written like this: 1st byte: their type */ void symtab_writeGlobals(FILE *bin) { for (VarInfo *begin = gs_vars.varTab->info, *end = begin + gs_vars.varTab->nVars; begin != end; ++begin) { char type = (char)begin->type & ~e_var; util_out(bin, &type, sizeof(char)); } } icmake-9.02.06/comp/symtab/findvar.c0000644000175000017500000000073313176557635016164 0ustar frankfrank#include "symtab.ih" VarIndex symtab_findVar() /* util_string() holds the name of an existing */ { /* variable, returns -1 if not found */ VarIndex ret; for (unsigned nesting = gs_vars.nLevels; nesting--; ) { int idx = st_findVar(nesting); if (idx != -1) { ret.idx = idx; ret.type = nesting > 0; return ret; } } ret.idx = -1; return ret; } icmake-9.02.06/comp/symtab/funnparams.c0000644000175000017500000000016513176557635016704 0ustar frankfrank#include "symtab.ih" unsigned symtab_fun_nParams(unsigned funIdx) { return gs_functions.info[funIdx].nParams; } icmake-9.02.06/comp/symtab/push.c0000644000175000017500000000063513176557635015513 0ustar frankfrank/*#define msg */ #include "symtab.ih" void symtab_push() { msg("next symtab offset: %u", gs_vars.nLevels); if (gs_vars.nLevels == gs_vars.capacity) gs_vars.varIndices = rss_realloc(gs_vars.varIndices, (gs_vars.capacity += capacityInc) * sizeof(VarIndices)); memset(gs_vars.varIndices + gs_vars.nLevels++, 0, sizeof(VarIndices)); } icmake-9.02.06/comp/symtab/stparamtype.c0000644000175000017500000000017013176557635017077 0ustar frankfrank#include "symtab.ih" ExprType st_paramType(unsigned idx) { return gs_vars.varTab[1].info[idx].type & e_typeMask; } icmake-9.02.06/comp/symtab/findfun.c0000644000175000017500000000066313176557635016166 0ustar frankfrank#include "symtab.ih" int symtab_findFun() /* util_string() holds the name of an existing */ { /* function, returns -1 if not */ size_t nmemb = gs_functions.nFunctions; void *ret = lfind(util_string(), gs_functions.info, &nmemb, sizeof(FunInfo), st_findFun); return ret == NULL ? -1 : (FunInfo *)ret - gs_functions.info; } icmake-9.02.06/comp/symtab/funname.c0000644000175000017500000000016113176557635016157 0ustar frankfrank#include "symtab.ih" char const *symtab_funName(unsigned funIdx) { return gs_functions.info[funIdx].name; } icmake-9.02.06/comp/symtab/stnewvaridx.c0000644000175000017500000000053113176557635017105 0ustar frankfrank#include "symtab.ih" unsigned st_newVarIdx() /* return the index of a (unitialized) var. record */ { VarTab *vt = st_varTab(st_nestingOffset()); if (vt->nVars == vt->capacity) vt->info = rss_realloc(vt->info, (vt->capacity += capacityInc) * sizeof(VarInfo)); return vt->nVars++; } icmake-9.02.06/comp/symtab/stfindvar.c0000644000175000017500000000136613176557635016536 0ustar frankfrank /* #define msg */ #include "symtab.ih" int st_findVar(unsigned nesting) /* find util_string() via gs_vars[nesting] */ { /* variable table to use when looking for util_string() */ gs_compareTable = st_varTab(nesting); VarIndices *indices = gs_vars.varIndices + nesting; /* Select the correct index vector */ /* find the var's index */ size_t nmemb = indices->nVars; void *unsignedPtr = lfind(util_string(), indices->index, &nmemb, sizeof(unsigned), st_compareVars); return unsignedPtr == NULL ? -1 : *(int *)unsignedPtr; } icmake-9.02.06/comp/symtab/funparametertype.c0000644000175000017500000000036013176557635020122 0ustar frankfrank#include "symtab.ih" ExprType symtab_funParameterType(unsigned funIdx, unsigned paramIdx) { /* &typeMask removes e_reg */ return gs_functions.info[funIdx].paramType[paramIdx] & e_typeMask; } icmake-9.02.06/comp/symtab/stlastfuninfo.c0000644000175000017500000000016013176557635017424 0ustar frankfrank#include "symtab.ih" FunInfo *st_lastFunInfo() { return gs_functions.info + gs_functions.nFunctions - 1; } icmake-9.02.06/comp/symtab/nparams.c0000644000175000017500000000012013176557635016162 0ustar frankfrank#include "symtab.ih" unsigned symtab_nParams() { return gs_vars.nParams; } icmake-9.02.06/comp/symtab/definevar.c0000644000175000017500000000106613176557635016476 0ustar frankfrank /* #define msg */ #include "symtab.ih" VarIndex symtab_defineVar(ExprType type) { VarIndex ret; int idx = st_findVar(st_nestingOffset()); /* see if the var. exists at the current nesting level */ if (idx == -1) /* if not, then add it */ ret = st_addVar(type); /* add a new variable */ else ret.idx = -1; /* already defined */ return ret; } icmake-9.02.06/comp/symtab/newparam.c0000644000175000017500000000022013176557635016334 0ustar frankfrank//#include "symtab.ih" // //void symtab_newParam() //{ // ++gs_vars.nParams; //fprintf(stderr, "inc. nParams to %u\n", gs_vars.nParams); //} icmake-9.02.06/comp/symtab/localtype.c0000644000175000017500000000021613176557635016523 0ustar frankfrank#include "symtab.ih" ExprType symtab_localType(unsigned idx) { return gs_vars.varTab[1].info[idx + gs_vars.nParams].type & e_typeMask; } icmake-9.02.06/comp/symtab/stnextfunidx.c0000644000175000017500000000067213176557635017300 0ustar frankfrank#include "symtab.ih" unsigned st_nextFunIdx() /* idx of an uninitialized record of a */ { /* function */ if (gs_functions.nFunctions == gs_functions.capacity) gs_functions.info = rss_realloc(gs_functions.info, (gs_functions.capacity += capacityInc) * sizeof(FunInfo)); return gs_functions.nFunctions++; } icmake-9.02.06/comp/symtab/sttoplevel.c0000644000175000017500000000015113176557635016726 0ustar frankfrank#include "symtab.ih" VarIndices *st_topLevel() { return gs_vars.varIndices + gs_vars.nLevels - 1; } icmake-9.02.06/comp/symtab/pop.c0000644000175000017500000000026213176557635015326 0ustar frankfrank/*#define msg */ #include "symtab.ih" void symtab_pop() { free(gs_vars.varIndices[--gs_vars.nLevels].index); msg("returning to symtab offset: %u", gs_vars.nLevels); } icmake-9.02.06/comp/symtab/funaddress.c0000644000175000017500000000016413176557635016667 0ustar frankfrank#include "symtab.ih" uint16_t symtab_funAddress(unsigned funIdx) { return gs_functions.info[funIdx].address; } icmake-9.02.06/comp/symtab/writefunaddress.c0000644000175000017500000000023313176557635017737 0ustar frankfrank#include "symtab.ih" void symtab_writeFunAddress(FILE *bin, unsigned funIdx) { util_out(bin, &gs_functions.info[funIdx].address, sizeof(uint16_t)); } icmake-9.02.06/comp/symtab/stnextvaridx.c0000644000175000017500000000112213176557635017267 0ustar frankfrank#include "symtab.ih" unsigned st_nextVarIdx(VarInfo **vi) /* idx of an uninitialized record of a */ { /* variable */ unsigned idx = st_newVarIdx(); /* new variable in local or global tab */ /* RBA a pointer to the next VarInfo */ *vi = st_varTab(st_nestingOffset())->info + idx; *st_newIdxPtr() = idx; /* create room in the nesting-level index vector, assign the idx */ return idx; /* return the index of the next var. */ } icmake-9.02.06/comp/symtab/stvartab.c0000644000175000017500000000015113176557635016353 0ustar frankfrank#include "symtab.ih" VarTab *st_varTab(unsigned nesting) { return gs_vars.varTab + (nesting > 0); } icmake-9.02.06/comp/symtab/setlastfunction.c0000644000175000017500000000146613176557635017764 0ustar frankfrank#include "symtab.ih" //unsigned symtab_setLastFunction(unsigned nParams) //{ // if (gs_functions->nSymbols == 0) // return 0; // // /* addr. of last function info */ // Symbol *last = gs_functions[gs_functions->nSymbols - 1].symbol; // // /* set offset of 1st byte */ // last->var.text->address = (unsigned)ftell(gp_bin); // // last->var.text->list.element = /* room for type-bytes */ // rss_realloc(NULL, nParams * sizeof(char)); // // last->var.text->list.size = nParams; /* store # of params */ // // st_setParamTypes(last, nParams); /* assign param. types */ // // return symtab_nLocalVariables(); /* return # of local variables */ //} icmake-9.02.06/comp/symtab/vartype.c0000644000175000017500000000016513176557635016224 0ustar frankfrank#include "symtab.ih" ExprType symtab_varType(VarIndex vt) { return gs_vars.varTab[vt.type].info[vt.idx].type; } icmake-9.02.06/comp/symtab/addfunction.c0000644000175000017500000000127613176557635017034 0ustar frankfrank/*#define msg */ #include "symtab.ih" int symtab_addFunction(ExprType type, /* 0: function added, */ long offset) /* -1: already def'd */ { if (symtab_findFun() != -1) return -1; /* already defined */ unsigned idx = st_nextFunIdx(); FunInfo *next = gs_functions.info + idx; memset(next, 0, sizeof(FunInfo)); next->name = rss_strdup(util_string()); next->returnType = type | e_reg; next->address = offset; if (strcmp("main", next->name) == 0 && (type & e_typeMask)) util_semantic("`main(...)' must have 'void' return type"); msg("gs_vars.nParams is %u", gs_vars.nParams); return 0; } icmake-9.02.06/comp/symtab/data.c0000644000175000017500000000026313176557635015442 0ustar frankfrank#include "symtab.ih" FunInfoTab gs_functions; /* symbol table for functions */ VarTab *gs_compareTable; /* set by st_findVar for st_compareVars */ VarRef gs_vars; icmake-9.02.06/comp/symtab/staddvar.c0000644000175000017500000000056013176557635016341 0ustar frankfrank /* #define msg */ #include "symtab.ih" VarIndex st_addVar(ExprType type) { VarInfo *vi; unsigned idx = st_nextVarIdx(&vi); vi->name = rss_strdup(util_string()); /* set the name of the var */ vi->type = type | e_var; /* set the type of the var */ vi->value = 0; VarIndex ret = {idx, st_nestingOffset() > 0}; return ret; } icmake-9.02.06/comp/symtab/stnewidxptr.c0000644000175000017500000000076213176557635017130 0ustar frankfrank#include "symtab.ih" unsigned *st_newIdxPtr() /* pointer to the next available index[] */ { /* element at the current nestinglevel */ VarIndices *indices = st_topLevel(); if (indices->nVars == indices->capacity) indices->index = rss_realloc(indices->index, (indices->capacity += capacityInc) * sizeof(unsigned)); return indices->index + indices->nVars++; } icmake-9.02.06/comp/symtab/cleanup.c0000644000175000017500000000105113176557635016154 0ustar frankfrank#include "symtab.ih" void symtab_cleanup() { symtab_pop(); /* remove the local symtab */ if ( gs_vars.nLevels != 1 /* only the global symtab should be left */ && rss_nErrors() == 0 /* and there were no errors */ ) rss_fatal(0, 0, "INTERNAL icm-comp ERROR: > 1 symbol table remains at " "end of function"); /* remove all local variables */ st_deleteVars(gs_vars.varTab + 1); } icmake-9.02.06/comp/symtab/nlocals.c0000644000175000017500000000015213176557635016161 0ustar frankfrank#include "symtab.ih" unsigned symtab_nLocals() { return gs_vars.varTab[1].nVars - gs_vars.nParams; } icmake-9.02.06/comp/symtab/stnestingoffset.c0000644000175000017500000000012613176557635017754 0ustar frankfrank#include "symtab.ih" unsigned st_nestingOffset() { return gs_vars.nLevels - 1; } icmake-9.02.06/comp/symtab/symtab.c0000644000175000017500000000115013176557635016024 0ustar frankfrank#include "symtab.ih" /* Initializes the symbol table structure. Call only once. */ void symtab() { gs_vars.varTab = rss_realloc(NULL, 2 * sizeof(VarTab)); memset(gs_vars.varTab, 0, sizeof(VarTab)); /* the global table */ memset(gs_vars.varTab + 1, 0, sizeof(VarTab)); /* the local tab. */ gs_vars.nLevels = 1; gs_vars.capacity = capacityInc; gs_vars.varIndices = rss_realloc(NULL, sizeof(VarIndices) * capacityInc); memset(gs_vars.varIndices, 0, sizeof(VarIndices)); /* var indices in the global table */ } icmake-9.02.06/comp/symtab/symtab.h0000644000175000017500000000513413176557635016037 0ustar frankfrank#ifndef INCLUDED_SYMTAB_H_ #define INCLUDED_SYMTAB_H_ #include #include "../../rss/rss.h" typedef enum { st_global = 0, /* indices of gs_vars */ st_local, /* all larger values indicate a local var or param */ } VarType; typedef struct { short idx; /* if -1 variable does not exist */ VarType type; } VarIndex; void symtab(void); /* initializes the symbol table data structure. call only once (not checked) */ /* 0: function added, -1: already def'd */ int symtab_addFunction(ExprType type, long offset); int symtab_findFun(void); /* util_string() holds the name of a function returns its idx or -1 if not found */ unsigned symtab_fun_nParams(unsigned funIdx); void symtab_newParam(); /* counts the number of params so far */ char const *symtab_funName(unsigned funIdx); uint16_t symtab_funAddress(unsigned funIdx); ExprType symtab_funType(unsigned funIdx); ExprType symtab_funParameterType(unsigned funIdx, unsigned paramIdx); void symtab_writeFunAddress(FILE *bin, unsigned funidx); unsigned symtab_lastFunction(void); /* index of last defined function */ void symtab_setFunParams(); /* set nparams & types of the function that's currently being defined */ VarIndex symtab_findVar(void); /* idx and type of var. g_lextring, or -1 */ VarIndex symtab_defineVar(ExprType type); /* Define a var. at the topmost symbol table (.idx == -1 if already def'd) */ ExprType symtab_varType(VarIndex vi); /* type of variable vi */ unsigned symtab_nGlobals(void); /* the number of global variables defined so far */ unsigned symtab_nLocals(void); /* the number of local variables of the function currently being defined */ ExprType symtab_localType(unsigned idx); /* type of local variable idx, 1st local var has idx 0 */ void symtab_writeGlobals(FILE *bin); void symtab_setNparams(void); unsigned symtab_nParams(); void symtab_cleanup(void); /* pop all local variables */ void symtab_pop(void); /* remove the topmost local symtab */ void symtab_push(void); /* add a new nesting level */ #endif icmake-9.02.06/comp/symtab/funtype.c0000644000175000017500000000016413176557635016223 0ustar frankfrank#include "symtab.ih" ExprType symtab_funType(unsigned funIdx) { return gs_functions.info[funIdx].returnType; } icmake-9.02.06/comp/symtab/stfindfun.c0000644000175000017500000000022113176557635016523 0ustar frankfrank#include "symtab.ih" int st_findFun(void const *key, void const *funInfo) { return strcmp((char const *)key, ((FunInfo *)funInfo)->name); } icmake-9.02.06/comp/symtab/frame0000644000175000017500000000006513176557635015402 0ustar frankfrank/* #define msg */ #include "symtab.ih" void st_ { } icmake-9.02.06/comp/symtab/lastfunction.c0000644000175000017500000000021213176557635017234 0ustar frankfrank#include "symtab.ih" unsigned symtab_lastFunction() /* idx of last defined function */ { return gs_functions.nFunctions - 1; } icmake-9.02.06/comp/symtab/nglobals.c0000644000175000017500000000012713176557635016331 0ustar frankfrank#include "symtab.ih" unsigned symtab_nGlobals() { return gs_vars.varTab->nVars; } icmake-9.02.06/comp/updateparser0000755000175000017500000000014613176557635015513 0ustar frankfrank#!/bin/bash ./updategrammar || exit 1 cd parser bison --defines=tokens.h -o parse.c grammar icmake-9.02.06/comp/scanner/0000755000175000017500000000000013232314221014465 5ustar frankfrankicmake-9.02.06/comp/scanner/lexer0000644000175000017500000003362413176557635015570 0ustar frankfrank%{ #include "scanner.ih" #define YY_NO_INPUT %} %option 8bit %x str %% \" { /* having read a "string", unescape it the returned string does not have surrounding double quotes */ BEGIN 0; return STRING; } . { util_catString(yytext); } \\x[[:xdigit:]]{2} { util_catString(sc_scan("%x", yytext + 2)); } \\[0-7]{3} { util_catString(sc_scan("%o", yytext + 1)); } \\. { util_catString(sc_escapedChar(yytext[1])); } [ \t] ; \n ++yylineno; ^#[0-9]+\n { sc_setLineNr(); } ^#>.* { sc_changeFile(yytext + 2); } ^#$ { sc_popFile(); } '.' { sc_charConst(); return STRING; } '\\[0-7]{3}' { util_setString(sc_scan("%o", yytext + 2)); return STRING; } '\\x[[:xdigit:]]{2}' { util_setString(sc_scan("%x", yytext + 3)); return STRING; } '\\.' { util_setString(sc_escapedChar(yytext[2])); return STRING; } [1-9][0-9]* { util_scan("%u", yytext); return NUMBER; } 0[0-7]* { util_scan("%o", yytext); return NUMBER; } 0x[[:xdigit:]]+ { util_scan("%x", yytext + 2); return NUMBER; } \" { util_setString(""); BEGIN str; } arghead { yylval.type = f_arg_head; return ARG_HEAD; } argtail { yylval.type = f_arg_tail; return ARG_TAIL; } ascii { /* ascii_int may become ascii_str */ yylval.type = f_ascii_int; return ASCII; } break { return BREAK; } chdir { yylval.type = f_chdir; return CHDIR; } cmdtail { yylval.type = f_cmd_tail; return CMD_TAIL; } cmdhead { yylval.type = f_cmd_head; return CMD_HEAD; } change_base { yylval.type = f_c_base; return C_BASE; } change_ext { yylval.type = f_c_ext; return C_EXT; } change_path { yylval.type = f_c_path; return C_PATH; } continue { return CONTINUE; } fprintf { yylval.type = f_fprintf; return FPRINTF; } get_base { yylval.type = f_g_base; return G_BASE; } get_ext { yylval.type = f_g_ext; return G_EXT; } get_dext { yylval.type = f_g_dext; return G_DEXT; } get_path { yylval.type = f_g_path; return G_PATH; } getch { yylval.type = f_getch; return GETCH; } getpid { yylval.type = f_getpid; return GETPID; } gets { yylval.type = f_gets; return GETS; } echo { yylval.type = f_echo; return ECHO_TOKEN; } element { yylval.type = f_element; return ELEMENT; } else { return ELSE; } eval { yylval.type = f_eval; return EVAL; } exec { yylval.type = f_exec; return EXEC; } execute { yylval.type = f_execute; return EXECUTE; } exists { yylval.type = f_exists; return EXISTS; } exit { yylval.type = op_exit; return EXIT; } fgets { yylval.type = f_fgets; return FGETS; } for { return FOR; } getenv { yylval.type = f_getenv; return GETENV; } if { return IF; } void { yylval.type = 0; /* 0 == void */ return VOID; } int { yylval.type = e_int; return INT; } list { yylval.type = e_list; return LIST; } listfind { yylval.type = f_listfind; return LISTFIND; } listunion { yylval.type = f_listunion; return LISTUNION; } listlen | sizeof | sizeoflist { sc_saveInfo(); yylval.type = f_listlen; return LISTLEN; } makelist { yylval.type = f_makelist; return MAKELIST; } older { yylval.type = op_older; return OLDER; } printf { yylval.type = f_printf; return PRINTF; } putenv { yylval.type = f_putenv; return PUTENV; } resize { yylval.type = f_resize; return RESIZE; } return { yylval.type = op_ret; return RETURN; } stat { yylval.type = f_stat; return STAT; } strchr { yylval.type = f_strchr; return STRCHR; } string { yylval.type = e_str; return STRINGTYPE; } strlen { yylval.type = f_strlen; return STRLEN; } strlwr { yylval.type = f_strlwr; return STRLWR; } strupr { yylval.type = f_strupr; return STRUPR; } strtok { yylval.type = f_strtok; return FIELDS; } strfind { yylval.type = f_strfind; return STRFIND; } strformat { yylval.type = f_strformat; return STRFORMAT; } substr { yylval.type = f_substr; return SUBSTR; } system { yylval.type = f_system; return SYSTEM; } trim { yylval.type = f_trim; return TRIMLEFT; } trimleft { yylval.type = f_trimleft; return TRIMLEFT; } trimright { yylval.type = f_trimright; return TRIMRIGHT; } while { return WHILE; } newer | younger { yylval.type = op_younger; return YOUNGER; } "++" { return INC; } "--" { return DEC; } "/=" { return DIV_IS; } "-=" { return MINUS_IS; } "*=" { return MUL_IS; } "%=" { return MOD_IS; } "+=" { return PLUS_IS; } "&=" { return AND_IS; } "|=" { return OR_IS; } "^=" { return XOR_IS; } "<<=" { return SHL_IS; } ">>=" { return SHR_IS; } "||" { return OR; } "&&" { return AND; } "==" { return EQUAL; } "!=" { return NOT_EQUAL; } "<=" { return SMALLER_EQUAL; } ">=" { return GREATER_EQUAL; } ">>" { return SHR; } "<<" { return SHL; } OFF | P_CHECK { util_setString("0"); return NUMBER; } S_IFDIR | O_FILE | ON { util_setString("1"); return NUMBER; } S_IFCHR | P_NOCHECK | O_DIR { util_setString("2"); return NUMBER; } S_IFREG | O_SUBDIR { util_setString("4"); return NUMBER; } S_IREAD | O_ALL { util_setString("8"); return NUMBER; } S_IWRITE { util_setString("16"); return NUMBER; } S_IEXEC { util_setString("32"); return NUMBER; } [_A-Za-z][A-Za-z0-9_]* { util_setString(yytext); return IDENTIFIER; } . return yytext[0]; icmake-9.02.06/comp/scanner/scappend.c0000644000175000017500000000006113176557635016454 0ustar frankfrank#include "scanner.ih" void sc_append() { } icmake-9.02.06/comp/scanner/scsaveinfo.c0000644000175000017500000000021413176557635017017 0ustar frankfrank#include "scanner.ih" void sc_saveInfo() { gs_savedLineNr = yylineno; free(gs_savedText); gs_savedText = rss_strdup(yytext); } icmake-9.02.06/comp/scanner/filenames.c0000644000175000017500000000012413176557635016622 0ustar frankfrank#include "scanner.ih" char const *scanner_filenames() { return gs_filenames; } icmake-9.02.06/comp/scanner/savedlinenr.c0000644000175000017500000000012513176557635017172 0ustar frankfrank#include "scanner.ih" unsigned scanner_savedLineNr() { return gs_savedLineNr; } icmake-9.02.06/comp/scanner/sccharconst.c0000644000175000017500000000016013176557635017171 0ustar frankfrank#include "scanner.ih" void sc_charConst() { gs_char[0] = yytext[1]; util_setString(gs_char); } icmake-9.02.06/comp/scanner/scchangefile.c0000644000175000017500000000216713176557635017303 0ustar frankfrank#include "scanner.ih" static unsigned filenames_len; void sc_changeFile(char *s) /* name of source file to open */ { register int slen; if (*s) /* any filename ? */ { if (!gs_fileSp--) /* no more entries ? */ rss_fatal(0, 0, "more than 10 nested #include directives"); /* save the name and line nr. of the file */ gs_fileStack[gs_fileSp].fname = rss_strdup(s); gs_fileStack[gs_fileSp].former_linenr = yylineno; gs_filenames = rss_realloc(gs_filenames, /* room for new filename */ filenames_len + (slen = strlen(s)) + 2); /* append name */ sprintf(gs_filenames + filenames_len, "%s\n", s); filenames_len += slen + 1; /* new length of string */ yylineno = 0; /* start at new file */ } util_setSourceName(gs_fileStack[gs_fileSp].fname); } icmake-9.02.06/comp/scanner/scscan.c0000644000175000017500000000037113176557635016135 0ustar frankfrank#define msgx #include "scanner.ih" char const *sc_scan(char const *fmt, char const *text) { msg("saw %s", text); unsigned value = 0; sscanf(text, fmt, &value); value %= 0x100; gs_char[0] = value % 0x100; return gs_char; } icmake-9.02.06/comp/scanner/data.c0000644000175000017500000000025513176557635015575 0ustar frankfrank#include "scanner.ih" char gs_char[2]; char *gs_filenames; char *gs_savedText; unsigned gs_savedLineNr; unsigned gs_fileSp = N_FILES; FileStack gs_fileStack[N_FILES]; icmake-9.02.06/comp/scanner/scanner.ih0000644000175000017500000000236313176557635016475 0ustar frankfrank#include "scanner.h" #include #include #include #include "../../rss/rss.h" #include "../util/util.h" #include "../global.h" #include "../parser/semval.ih" #include "../parser/tokens.h" /* parser.h" */ #ifndef fileno int fileno(FILE *stream); #endif #ifdef unput /* If this stops working, have a look at lexer2.c to see what was */ /* changed in the flex-implementation */ static void yyunput (int c,char *buf_ptr ); void (*unusedUnput)(int c,char *buf_ptr) = &yyunput; #endif enum { N_FILES = 11 }; typedef struct { int former_linenr; char *fname; } FileStack; extern FileStack gs_fileStack[]; extern unsigned gs_fileSp; extern char gs_char[]; extern char *gs_filenames; extern char *gs_savedText; extern unsigned gs_savedLineNr; extern size_t yyleng; extern FILE *yyin; extern FILE *yyout; void sc_changeFile(char *s); /* name of source file to open */ void sc_popFile(); void sc_saveInfo(void); /* saves yylineno and yytext */ void sc_setLineNr(void); /* updates yylineno at #\n lines */ char const *sc_escapedChar(int ch); char const *sc_scan(char const *fmt, char const *text); void sc_charConst(void); icmake-9.02.06/comp/scanner/scanner.c0000644000175000017500000000030013176557635016304 0ustar frankfrank#include "scanner.ih" void scanner(char const *infile) { if (!(yyin = fopen(infile, "rt"))) /* open text file for parsing */ rss_fatal(0, 0, "%s Can't read `%s'", infile); } icmake-9.02.06/comp/scanner/scsetlinenr.c0000644000175000017500000000012013176557635017204 0ustar frankfrank#include "scanner.ih" void sc_setLineNr() { yylineno = atoi(yytext + 1); } icmake-9.02.06/comp/scanner/scescapedchar.c0000644000175000017500000000057713176557635017463 0ustar frankfrank#include "scanner.ih" static char stdEscape[] = {'n', 't', 'v', 'b', 'r', 'f', 'a', '\'', '"', '\\'}; static char escapedChar[] = {'\n', '\t', '\v', '\b', '\r', '\f', '\a', '\'', '"', '\\'}; char const *sc_escapedChar(int ch) { char *cp = strchr(stdEscape, ch); gs_char[0] = cp == NULL ? ch : escapedChar[cp - stdEscape]; return gs_char; } icmake-9.02.06/comp/scanner/lexer.c0000644000175000017500000022613713176557635016014 0ustar frankfrank#line 2 "lexer.c" #line 4 "lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 39 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ yy_size_t yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 117 #define YY_END_OF_BUFFER 118 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[407] = { 0, 0, 0, 0, 0, 118, 116, 6, 7, 116, 18, 116, 116, 116, 116, 116, 116, 116, 16, 15, 116, 116, 116, 115, 115, 115, 115, 116, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, 116, 2, 117, 1, 2, 96, 86, 94, 88, 0, 0, 85, 81, 87, 82, 84, 83, 16, 0, 15, 100, 97, 95, 98, 99, 115, 115, 105, 115, 115, 115, 90, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 49, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 89, 93, 10, 0, 9, 5, 5, 5, 11, 0, 11, 0, 0, 17, 91, 92, 101, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 47, 115, 115, 51, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 8, 9, 0, 0, 14, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 38, 115, 40, 41, 42, 115, 45, 115, 115, 115, 115, 115, 115, 37, 52, 115, 115, 115, 115, 115, 115, 115, 115, 64, 115, 115, 115, 115, 115, 115, 115, 115, 75, 50, 115, 115, 4, 3, 0, 0, 112, 108, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 21, 22, 115, 23, 115, 115, 115, 115, 115, 115, 46, 115, 115, 115, 115, 115, 35, 115, 115, 115, 115, 115, 115, 79, 59, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 78, 115, 12, 13, 104, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 44, 115, 115, 115, 115, 115, 48, 36, 115, 115, 115, 115, 60, 61, 62, 63, 56, 65, 115, 115, 66, 67, 68, 70, 69, 73, 74, 115, 115, 115, 115, 102, 115, 114, 106, 103, 109, 111, 115, 19, 20, 115, 25, 24, 115, 39, 43, 30, 115, 115, 32, 115, 115, 55, 115, 115, 115, 71, 115, 115, 115, 80, 110, 115, 113, 115, 115, 115, 29, 31, 33, 34, 53, 115, 58, 115, 115, 76, 115, 107, 115, 115, 115, 54, 115, 72, 77, 115, 27, 115, 57, 26, 28, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 1, 7, 8, 9, 1, 1, 10, 11, 1, 12, 1, 13, 14, 15, 15, 15, 15, 15, 15, 15, 16, 16, 1, 1, 17, 18, 19, 1, 1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 29, 32, 33, 34, 29, 35, 36, 37, 38, 29, 39, 40, 29, 29, 1, 41, 1, 42, 43, 1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 29, 53, 54, 55, 56, 57, 58, 29, 59, 60, 61, 62, 63, 64, 65, 66, 67, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[69] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 5, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1 } ; static yyconst flex_int16_t yy_base[418] = { 0, 0, 465, 66, 67, 470, 472, 472, 472, 451, 472, 450, 65, 426, 448, 63, 64, 447, 63, 70, 62, 446, 69, 0, 66, 420, 419, 443, 30, 401, 42, 48, 46, 411, 56, 406, 413, 408, 401, 33, 406, 54, 394, 395, 400, 393, 57, 107, 472, 472, 472, 86, 472, 472, 472, 472, 440, 115, 472, 472, 472, 472, 472, 472, 103, 0, 117, 430, 472, 472, 472, 429, 0, 421, 0, 114, 113, 417, 472, 394, 397, 394, 94, 394, 384, 388, 88, 394, 92, 389, 377, 376, 373, 0, 372, 372, 378, 366, 382, 376, 366, 82, 359, 102, 380, 364, 371, 370, 369, 358, 472, 472, 472, 144, 0, 472, 138, 0, 472, 410, 409, 140, 408, 0, 472, 472, 0, 385, 387, 386, 375, 385, 378, 132, 111, 358, 365, 352, 355, 112, 345, 348, 349, 355, 348, 355, 104, 339, 0, 347, 131, 0, 337, 349, 348, 347, 338, 345, 340, 329, 342, 328, 132, 328, 326, 331, 338, 330, 327, 472, 0, 154, 0, 472, 161, 0, 351, 346, 349, 358, 354, 355, 336, 160, 351, 339, 325, 328, 319, 317, 319, 309, 319, 322, 313, 0, 316, 0, 0, 301, 301, 0, 301, 304, 140, 308, 302, 305, 0, 65, 302, 296, 295, 292, 296, 284, 291, 292, 0, 297, 140, 291, 142, 289, 287, 283, 295, 142, 0, 294, 291, 472, 472, 331, 330, 0, 0, 314, 314, 314, 308, 310, 306, 304, 307, 310, 301, 284, 275, 0, 0, 278, 0, 281, 272, 267, 266, 260, 260, 0, 258, 274, 269, 251, 271, 0, 251, 266, 260, 263, 254, 257, 0, 0, 259, 244, 258, 249, 255, 244, 246, 242, 250, 243, 239, 244, 237, 236, 239, 245, 240, 0, 243, 472, 472, 0, 262, 259, 264, 265, 251, 250, 258, 260, 245, 234, 226, 236, 231, 223, 214, 214, 226, 0, 224, 212, 206, 209, 208, 0, 0, 212, 211, 214, 205, 0, 0, 0, 0, 210, 0, 216, 207, 0, 0, 0, 0, 0, 0, 0, 212, 210, 200, 223, 0, 235, 0, 0, 0, 0, 0, 232, 0, 0, 154, 0, 0, 207, 0, 0, 0, 206, 192, 0, 201, 204, 0, 193, 188, 196, 0, 203, 185, 194, 0, 0, 214, 0, 199, 177, 192, 0, 0, 0, 0, 0, 175, 0, 166, 158, 0, 150, 0, 150, 148, 147, 0, 146, 0, 0, 157, 0, 153, 0, 0, 0, 472, 212, 217, 219, 224, 229, 199, 234, 196, 237, 166, 162 } ; static yyconst flex_int16_t yy_def[418] = { 0, 406, 1, 407, 407, 406, 406, 406, 406, 406, 406, 406, 406, 408, 406, 406, 406, 406, 406, 406, 406, 406, 406, 409, 409, 409, 409, 406, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 406, 406, 406, 406, 406, 410, 406, 406, 406, 406, 406, 411, 406, 406, 406, 406, 406, 406, 406, 412, 406, 406, 406, 406, 406, 406, 409, 409, 409, 409, 409, 409, 406, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 406, 406, 406, 406, 413, 406, 406, 414, 406, 406, 406, 406, 415, 412, 406, 406, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 406, 413, 406, 416, 406, 406, 417, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 406, 406, 406, 406, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 406, 406, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 0, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406 } ; static yyconst flex_int16_t yy_nxt[541] = { 0, 6, 7, 8, 9, 10, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25, 23, 26, 23, 23, 23, 23, 6, 27, 23, 28, 29, 30, 23, 31, 32, 33, 23, 34, 23, 35, 36, 37, 38, 39, 40, 41, 42, 23, 43, 44, 23, 45, 23, 46, 49, 49, 50, 50, 54, 59, 110, 61, 64, 64, 67, 68, 60, 62, 55, 66, 66, 66, 70, 71, 79, 80, 73, 99, 82, 85, 100, 89, 83, 74, 84, 116, 116, 86, 90, 91, 93, 102, 51, 51, 75, 112, 87, 94, 88, 268, 103, 104, 64, 64, 269, 105, 113, 113, 113, 120, 111, 114, 270, 65, 121, 121, 66, 66, 66, 127, 131, 142, 128, 137, 129, 145, 138, 158, 159, 146, 132, 161, 169, 143, 173, 130, 117, 171, 171, 174, 174, 182, 183, 113, 113, 113, 162, 186, 192, 200, 201, 234, 184, 231, 231, 232, 185, 187, 193, 204, 233, 233, 205, 219, 206, 122, 220, 242, 243, 221, 261, 222, 262, 263, 207, 283, 208, 280, 223, 224, 244, 289, 281, 264, 378, 172, 290, 379, 123, 405, 404, 284, 403, 402, 401, 400, 399, 380, 48, 48, 48, 48, 48, 56, 398, 56, 56, 56, 72, 72, 115, 397, 115, 115, 115, 119, 396, 119, 119, 119, 170, 395, 170, 170, 170, 175, 175, 394, 393, 392, 391, 390, 389, 388, 387, 386, 385, 384, 383, 382, 381, 377, 376, 375, 374, 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 288, 287, 286, 285, 282, 279, 278, 277, 276, 275, 274, 273, 272, 271, 267, 266, 265, 260, 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 241, 240, 239, 238, 237, 236, 235, 230, 229, 228, 227, 226, 225, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 203, 202, 199, 198, 197, 196, 195, 194, 191, 190, 189, 188, 181, 180, 179, 178, 177, 176, 173, 173, 173, 168, 167, 166, 165, 164, 163, 160, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 144, 141, 140, 139, 136, 135, 134, 133, 126, 125, 124, 118, 109, 108, 107, 106, 101, 98, 97, 96, 95, 92, 81, 78, 77, 76, 69, 63, 58, 57, 53, 52, 406, 47, 5, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406 } ; static yyconst flex_int16_t yy_chk[541] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 3, 4, 12, 15, 46, 16, 18, 18, 20, 20, 15, 16, 12, 19, 19, 19, 22, 22, 28, 28, 24, 39, 30, 31, 39, 32, 30, 24, 30, 51, 51, 31, 32, 32, 34, 41, 3, 4, 24, 47, 31, 34, 31, 209, 41, 41, 64, 64, 209, 41, 47, 47, 47, 57, 46, 47, 209, 18, 57, 57, 66, 66, 66, 75, 76, 86, 75, 82, 75, 88, 82, 101, 101, 88, 76, 103, 113, 86, 121, 75, 51, 116, 116, 121, 121, 133, 133, 113, 113, 113, 103, 134, 139, 146, 146, 417, 133, 171, 171, 416, 133, 134, 139, 150, 174, 174, 150, 162, 150, 57, 162, 183, 183, 162, 204, 162, 204, 204, 150, 222, 150, 220, 162, 162, 183, 227, 220, 204, 354, 414, 227, 354, 412, 402, 400, 222, 397, 395, 394, 393, 391, 354, 407, 407, 407, 407, 407, 408, 389, 408, 408, 408, 409, 409, 410, 388, 410, 410, 410, 411, 386, 411, 411, 411, 413, 380, 413, 413, 413, 415, 415, 379, 378, 376, 373, 372, 371, 369, 368, 367, 365, 364, 362, 361, 357, 351, 345, 343, 342, 341, 340, 332, 331, 329, 324, 323, 322, 321, 318, 317, 316, 315, 314, 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296, 292, 290, 289, 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, 274, 271, 270, 269, 268, 267, 266, 264, 263, 262, 261, 260, 258, 257, 256, 255, 254, 253, 251, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 234, 233, 230, 229, 226, 225, 224, 223, 221, 219, 217, 216, 215, 214, 213, 212, 211, 210, 207, 206, 205, 203, 202, 200, 199, 196, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 182, 181, 180, 179, 178, 177, 176, 168, 167, 166, 165, 164, 163, 161, 160, 159, 158, 157, 156, 155, 154, 153, 152, 149, 147, 145, 144, 143, 142, 141, 140, 138, 137, 136, 135, 132, 131, 130, 129, 128, 127, 122, 120, 119, 109, 108, 107, 106, 105, 104, 102, 100, 99, 98, 97, 96, 95, 94, 92, 91, 90, 89, 87, 85, 84, 83, 81, 80, 79, 77, 73, 71, 67, 56, 45, 44, 43, 42, 40, 38, 37, 36, 35, 33, 29, 27, 26, 25, 21, 17, 14, 13, 11, 9, 5, 2, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "lexer" #line 2 "lexer" #include "scanner.ih" #define YY_NO_INPUT #line 720 "lexer.c" #define INITIAL 0 #define str 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * in_str ); FILE *yyget_out (void ); void yyset_out (FILE * out_str ); yy_size_t yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 12 "lexer" #line 941 "lexer.c" while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 407 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 472 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 14 "lexer" { /* having read a "string", unescape it the returned string does not have surrounding double quotes */ BEGIN 0; return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 21 "lexer" { util_catString(yytext); } YY_BREAK case 3: YY_RULE_SETUP #line 25 "lexer" { util_catString(sc_scan("%x", yytext + 2)); } YY_BREAK case 4: YY_RULE_SETUP #line 29 "lexer" { util_catString(sc_scan("%o", yytext + 1)); } YY_BREAK case 5: YY_RULE_SETUP #line 33 "lexer" { util_catString(sc_escapedChar(yytext[1])); } YY_BREAK case 6: YY_RULE_SETUP #line 37 "lexer" ; YY_BREAK case 7: /* rule 7 can match eol */ YY_RULE_SETUP #line 38 "lexer" ++yylineno; YY_BREAK case 8: /* rule 8 can match eol */ YY_RULE_SETUP #line 39 "lexer" { sc_setLineNr(); } YY_BREAK case 9: YY_RULE_SETUP #line 42 "lexer" { sc_changeFile(yytext + 2); } YY_BREAK case 10: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 45 "lexer" { sc_popFile(); } YY_BREAK case 11: YY_RULE_SETUP #line 48 "lexer" { sc_charConst(); return STRING; } YY_BREAK case 12: YY_RULE_SETUP #line 53 "lexer" { util_setString(sc_scan("%o", yytext + 2)); return STRING; } YY_BREAK case 13: YY_RULE_SETUP #line 58 "lexer" { util_setString(sc_scan("%x", yytext + 3)); return STRING; } YY_BREAK case 14: YY_RULE_SETUP #line 63 "lexer" { util_setString(sc_escapedChar(yytext[2])); return STRING; } YY_BREAK case 15: YY_RULE_SETUP #line 68 "lexer" { util_scan("%u", yytext); return NUMBER; } YY_BREAK case 16: YY_RULE_SETUP #line 72 "lexer" { util_scan("%o", yytext); return NUMBER; } YY_BREAK case 17: YY_RULE_SETUP #line 76 "lexer" { util_scan("%x", yytext + 2); return NUMBER; } YY_BREAK case 18: YY_RULE_SETUP #line 81 "lexer" { util_setString(""); BEGIN str; } YY_BREAK case 19: YY_RULE_SETUP #line 86 "lexer" { yylval.type = f_arg_head; return ARG_HEAD; } YY_BREAK case 20: YY_RULE_SETUP #line 90 "lexer" { yylval.type = f_arg_tail; return ARG_TAIL; } YY_BREAK case 21: YY_RULE_SETUP #line 94 "lexer" { /* ascii_int may become ascii_str */ yylval.type = f_ascii_int; return ASCII; } YY_BREAK case 22: YY_RULE_SETUP #line 98 "lexer" { return BREAK; } YY_BREAK case 23: YY_RULE_SETUP #line 101 "lexer" { yylval.type = f_chdir; return CHDIR; } YY_BREAK case 24: YY_RULE_SETUP #line 105 "lexer" { yylval.type = f_cmd_tail; return CMD_TAIL; } YY_BREAK case 25: YY_RULE_SETUP #line 109 "lexer" { yylval.type = f_cmd_head; return CMD_HEAD; } YY_BREAK case 26: YY_RULE_SETUP #line 113 "lexer" { yylval.type = f_c_base; return C_BASE; } YY_BREAK case 27: YY_RULE_SETUP #line 117 "lexer" { yylval.type = f_c_ext; return C_EXT; } YY_BREAK case 28: YY_RULE_SETUP #line 121 "lexer" { yylval.type = f_c_path; return C_PATH; } YY_BREAK case 29: YY_RULE_SETUP #line 125 "lexer" { return CONTINUE; } YY_BREAK case 30: YY_RULE_SETUP #line 128 "lexer" { yylval.type = f_fprintf; return FPRINTF; } YY_BREAK case 31: YY_RULE_SETUP #line 132 "lexer" { yylval.type = f_g_base; return G_BASE; } YY_BREAK case 32: YY_RULE_SETUP #line 136 "lexer" { yylval.type = f_g_ext; return G_EXT; } YY_BREAK case 33: YY_RULE_SETUP #line 140 "lexer" { yylval.type = f_g_dext; return G_DEXT; } YY_BREAK case 34: YY_RULE_SETUP #line 144 "lexer" { yylval.type = f_g_path; return G_PATH; } YY_BREAK case 35: YY_RULE_SETUP #line 148 "lexer" { yylval.type = f_getch; return GETCH; } YY_BREAK case 36: YY_RULE_SETUP #line 152 "lexer" { yylval.type = f_getpid; return GETPID; } YY_BREAK case 37: YY_RULE_SETUP #line 156 "lexer" { yylval.type = f_gets; return GETS; } YY_BREAK case 38: YY_RULE_SETUP #line 160 "lexer" { yylval.type = f_echo; return ECHO_TOKEN; } YY_BREAK case 39: YY_RULE_SETUP #line 164 "lexer" { yylval.type = f_element; return ELEMENT; } YY_BREAK case 40: YY_RULE_SETUP #line 168 "lexer" { return ELSE; } YY_BREAK case 41: YY_RULE_SETUP #line 171 "lexer" { yylval.type = f_eval; return EVAL; } YY_BREAK case 42: YY_RULE_SETUP #line 175 "lexer" { yylval.type = f_exec; return EXEC; } YY_BREAK case 43: YY_RULE_SETUP #line 179 "lexer" { yylval.type = f_execute; return EXECUTE; } YY_BREAK case 44: YY_RULE_SETUP #line 183 "lexer" { yylval.type = f_exists; return EXISTS; } YY_BREAK case 45: YY_RULE_SETUP #line 187 "lexer" { yylval.type = op_exit; return EXIT; } YY_BREAK case 46: YY_RULE_SETUP #line 191 "lexer" { yylval.type = f_fgets; return FGETS; } YY_BREAK case 47: YY_RULE_SETUP #line 195 "lexer" { return FOR; } YY_BREAK case 48: YY_RULE_SETUP #line 198 "lexer" { yylval.type = f_getenv; return GETENV; } YY_BREAK case 49: YY_RULE_SETUP #line 202 "lexer" { return IF; } YY_BREAK case 50: YY_RULE_SETUP #line 205 "lexer" { yylval.type = 0; /* 0 == void */ return VOID; } YY_BREAK case 51: YY_RULE_SETUP #line 209 "lexer" { yylval.type = e_int; return INT; } YY_BREAK case 52: YY_RULE_SETUP #line 213 "lexer" { yylval.type = e_list; return LIST; } YY_BREAK case 53: YY_RULE_SETUP #line 217 "lexer" { yylval.type = f_listfind; return LISTFIND; } YY_BREAK case 54: YY_RULE_SETUP #line 221 "lexer" { yylval.type = f_listunion; return LISTUNION; } YY_BREAK case 55: #line 226 "lexer" case 56: #line 227 "lexer" case 57: YY_RULE_SETUP #line 227 "lexer" { sc_saveInfo(); yylval.type = f_listlen; return LISTLEN; } YY_BREAK case 58: YY_RULE_SETUP #line 232 "lexer" { yylval.type = f_makelist; return MAKELIST; } YY_BREAK case 59: YY_RULE_SETUP #line 236 "lexer" { yylval.type = op_older; return OLDER; } YY_BREAK case 60: YY_RULE_SETUP #line 240 "lexer" { yylval.type = f_printf; return PRINTF; } YY_BREAK case 61: YY_RULE_SETUP #line 244 "lexer" { yylval.type = f_putenv; return PUTENV; } YY_BREAK case 62: YY_RULE_SETUP #line 248 "lexer" { yylval.type = f_resize; return RESIZE; } YY_BREAK case 63: YY_RULE_SETUP #line 253 "lexer" { yylval.type = op_ret; return RETURN; } YY_BREAK case 64: YY_RULE_SETUP #line 257 "lexer" { yylval.type = f_stat; return STAT; } YY_BREAK case 65: YY_RULE_SETUP #line 261 "lexer" { yylval.type = f_strchr; return STRCHR; } YY_BREAK case 66: YY_RULE_SETUP #line 265 "lexer" { yylval.type = e_str; return STRINGTYPE; } YY_BREAK case 67: YY_RULE_SETUP #line 269 "lexer" { yylval.type = f_strlen; return STRLEN; } YY_BREAK case 68: YY_RULE_SETUP #line 273 "lexer" { yylval.type = f_strlwr; return STRLWR; } YY_BREAK case 69: YY_RULE_SETUP #line 277 "lexer" { yylval.type = f_strupr; return STRUPR; } YY_BREAK case 70: YY_RULE_SETUP #line 281 "lexer" { yylval.type = f_strtok; return FIELDS; } YY_BREAK case 71: YY_RULE_SETUP #line 285 "lexer" { yylval.type = f_strfind; return STRFIND; } YY_BREAK case 72: YY_RULE_SETUP #line 289 "lexer" { yylval.type = f_strformat; return STRFORMAT; } YY_BREAK case 73: YY_RULE_SETUP #line 293 "lexer" { yylval.type = f_substr; return SUBSTR; } YY_BREAK case 74: YY_RULE_SETUP #line 297 "lexer" { yylval.type = f_system; return SYSTEM; } YY_BREAK case 75: YY_RULE_SETUP #line 301 "lexer" { yylval.type = f_trim; return TRIMLEFT; } YY_BREAK case 76: YY_RULE_SETUP #line 305 "lexer" { yylval.type = f_trimleft; return TRIMLEFT; } YY_BREAK case 77: YY_RULE_SETUP #line 309 "lexer" { yylval.type = f_trimright; return TRIMRIGHT; } YY_BREAK case 78: YY_RULE_SETUP #line 313 "lexer" { return WHILE; } YY_BREAK case 79: #line 317 "lexer" case 80: YY_RULE_SETUP #line 317 "lexer" { yylval.type = op_younger; return YOUNGER; } YY_BREAK case 81: YY_RULE_SETUP #line 321 "lexer" { return INC; } YY_BREAK case 82: YY_RULE_SETUP #line 324 "lexer" { return DEC; } YY_BREAK case 83: YY_RULE_SETUP #line 327 "lexer" { return DIV_IS; } YY_BREAK case 84: YY_RULE_SETUP #line 330 "lexer" { return MINUS_IS; } YY_BREAK case 85: YY_RULE_SETUP #line 333 "lexer" { return MUL_IS; } YY_BREAK case 86: YY_RULE_SETUP #line 336 "lexer" { return MOD_IS; } YY_BREAK case 87: YY_RULE_SETUP #line 339 "lexer" { return PLUS_IS; } YY_BREAK case 88: YY_RULE_SETUP #line 342 "lexer" { return AND_IS; } YY_BREAK case 89: YY_RULE_SETUP #line 345 "lexer" { return OR_IS; } YY_BREAK case 90: YY_RULE_SETUP #line 348 "lexer" { return XOR_IS; } YY_BREAK case 91: YY_RULE_SETUP #line 351 "lexer" { return SHL_IS; } YY_BREAK case 92: YY_RULE_SETUP #line 354 "lexer" { return SHR_IS; } YY_BREAK case 93: YY_RULE_SETUP #line 357 "lexer" { return OR; } YY_BREAK case 94: YY_RULE_SETUP #line 360 "lexer" { return AND; } YY_BREAK case 95: YY_RULE_SETUP #line 363 "lexer" { return EQUAL; } YY_BREAK case 96: YY_RULE_SETUP #line 366 "lexer" { return NOT_EQUAL; } YY_BREAK case 97: YY_RULE_SETUP #line 369 "lexer" { return SMALLER_EQUAL; } YY_BREAK case 98: YY_RULE_SETUP #line 372 "lexer" { return GREATER_EQUAL; } YY_BREAK case 99: YY_RULE_SETUP #line 375 "lexer" { return SHR; } YY_BREAK case 100: YY_RULE_SETUP #line 378 "lexer" { return SHL; } YY_BREAK case 101: #line 382 "lexer" case 102: YY_RULE_SETUP #line 382 "lexer" { util_setString("0"); return NUMBER; } YY_BREAK case 103: #line 387 "lexer" case 104: #line 388 "lexer" case 105: YY_RULE_SETUP #line 388 "lexer" { util_setString("1"); return NUMBER; } YY_BREAK case 106: #line 393 "lexer" case 107: #line 394 "lexer" case 108: YY_RULE_SETUP #line 394 "lexer" { util_setString("2"); return NUMBER; } YY_BREAK case 109: #line 399 "lexer" case 110: YY_RULE_SETUP #line 399 "lexer" { util_setString("4"); return NUMBER; } YY_BREAK case 111: #line 404 "lexer" case 112: YY_RULE_SETUP #line 404 "lexer" { util_setString("8"); return NUMBER; } YY_BREAK case 113: YY_RULE_SETUP #line 408 "lexer" { util_setString("16"); return NUMBER; } YY_BREAK case 114: YY_RULE_SETUP #line 412 "lexer" { util_setString("32"); return NUMBER; } YY_BREAK case 115: YY_RULE_SETUP #line 416 "lexer" { util_setString(yytext); return IDENTIFIER; } YY_BREAK case 116: YY_RULE_SETUP #line 420 "lexer" return yytext[0]; YY_BREAK case 117: YY_RULE_SETUP #line 421 "lexer" ECHO; YY_BREAK #line 1839 "lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(str): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 407 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 407 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 406); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ yy_size_t yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 420 "lexer" icmake-9.02.06/comp/scanner/scpopfile.c0000644000175000017500000000057613176557635016656 0ustar frankfrank#include "scanner.ih" void sc_popFile() { if (gs_fileSp == N_FILES - 1) rss_fatal(util_sourceName(), yylineno, "include file stack empty"); free(gs_fileStack[gs_fileSp].fname); yylineno = gs_fileStack[gs_fileSp].former_linenr - 1; gs_fileSp++; /* free stack element */ util_setSourceName(gs_fileStack[gs_fileSp].fname); } icmake-9.02.06/comp/scanner/scanner.h0000644000175000017500000000036513176557635016324 0ustar frankfrank#ifndef INCLUDED_SCANNER_H_ #define INCLUDED_SCANNER_H_ #include void scanner(char const *infile); int yylex(); char const *scanner_filenames(); char const *scanner_savedText(void); unsigned scanner_savedLineNr(void); #endif icmake-9.02.06/comp/scanner/frame0000644000175000017500000000004413176557635015531 0ustar frankfrank#include "scanner.ih" void sc_ { } icmake-9.02.06/comp/scanner/savedtext.c0000644000175000017500000000012413176557635016666 0ustar frankfrank#include "scanner.ih" char const *scanner_savedText() { return gs_savedText; } icmake-9.02.06/comp/icm_bootstrap0000755000175000017500000000022613176557635015660 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/${LIBDIR}/icm-comp build icm-comp util symtab scanner parser icmake-9.02.06/comp/updategrammar0000755000175000017500000000030213176557635015637 0ustar frankfrank#!/bin/bash cd parser/inc files=`ls -X | grep -v 'build\|OBS'` for file in $files do if [ $file -nt "../grammar" ] ; then cat $files > ../grammar exit 0 fi done icmake-9.02.06/comp/parser/0000755000175000017500000000000013232314221014330 5ustar frankfrankicmake-9.02.06/comp/parser/pbreakstm.c0000644000175000017500000000065613176557635016524 0ustar frankfrank/* B R E A K S T M . C */ #include "parser.ih" static SemVal e; SemVal *p_break() { e = *p_stackFrame(0); if (!gp_breakOK) util_semantic("'break' only in 'while' or 'for' statements"); else { p_generateCode(&e, op_jmp, j_truelist); e.type = e_bool | e_stack; ++gp_dead[gp_dead_sp]; /* next code is gp_dead */ } return &e; } icmake-9.02.06/comp/parser/phiddenfunctions.c0000644000175000017500000000216713176557635020077 0ustar frankfrank#include "parser.ih" void p_hiddenFunctions(void) { long eof; register int funIdx; if (!gp_hidden_called) return; /* no hidden calls: nothing to do */ eof = ftell(gp_bin); /* remember the eof position */ /* go to begin of code */ fseek(gp_bin, sizeof(BinHeader), SEEK_SET); while (ftell(gp_bin) < eof) /* continue until code processed */ { if (p_nextCall()) /* find function call */ { funIdx = -rss_getInt16(gp_bin); /* get the address (toggled sign) */ if (funIdx >= 0) /* hidden function */ { /* reset to p_patchup */ fseek(gp_bin, -(long)sizeof(int16_t), SEEK_CUR); util_setString(gp_hiddenFun[funIdx].name); /* update the function's address */ symtab_writeFunAddress(gp_bin, funIdx); fseek(gp_bin, 0, SEEK_CUR); /* ready to read again */ } } } } icmake-9.02.06/comp/parser/plcast.c0000644000175000017500000000072313176557635016015 0ustar frankfrank#include "parser.ih" SemVal *p_lCast(SemVal *e) { if (test_type(e, e_int)) /* (int)list not ok */ { util_semantic(gp_illegalCast); p_discard(e); set_type(e, e_list | e_var); } else if (test_type(e, e_str)) /* (string)int ok */ { p_expr2stack(e); /* convert to code */ p_generateCode(e, op_atol); set_type(e, e_stack | e_list); } return (e); } icmake-9.02.06/comp/parser/pyoung.c0000644000175000017500000000064513176557635016053 0ustar frankfrank#define msgx #include "parser.ih" SemVal *p_young(SemVal *lval, SemVal *rval) { msg("start"); if (p_testBinOp(op_younger, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_expr2stack(lval); /* convert to code */ p_expr2stack(rval); p_binOp(lval, rval, op_younger); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pzeroargs.c0000644000175000017500000000027213176557635016542 0ustar frankfrank#include "parser.ih" static SemVal e; SemVal *p_zeroArgs(ExprType type) { e = *p_stackFrame(0); /* reinitialize e */ p_callRss(&e, type); return &e; } icmake-9.02.06/comp/parser/ptestoperand.c0000644000175000017500000000035613176557635017241 0ustar frankfrank#include "parser.ih" int p_testOperand(SemVal *e, Opcode opcode) { register int ret = !test_type(e, gp_opType[opcode]); /* 0: type error */ if (ret) util_semantic(gp_illegalType, gp_opstring[opcode]); return ret; } icmake-9.02.06/comp/parser/poptintstring.c0000644000175000017500000000233613176557635017455 0ustar frankfrank#include "parser.ih" SemVal *p_optIntString(ExprType type, SemVal *larg, SemVal *rarg) { p_expr2stack(larg); /* argument to stack */ if ( test_type(larg, e_str) /* left is string */ && !rarg->type /* right is zeroframe */ ) /* -> REQUIRE_ZERO implied */ { rarg->type = e_int | e_const; /* indicate constant */ rarg->evalue = REQUIRE_ZERO; /* indicate REQUIRE_ZERO */ p_expr2stack(rarg); /* right arg now code */ p_catCode(larg, rarg); /* catenate code */ } else if ( test_type(larg, e_int) /* left is int: explicit check */ && test_type(rarg, e_str) /* right must be string */ ) { p_expr2stack(rarg); /* right arg to code */ p_catCode(rarg, larg); larg = rarg; } else { util_semantic(gp_typeConflict, gp_funstring[type]); p_discard (rarg); return (larg); } p_callRss(larg, type); /* call the function */ return (larg); } icmake-9.02.06/comp/parser/pincdec.c0000644000175000017500000000173113176557635016134 0ustar frankfrank/*#define msg */ #include "parser.ih" SemVal *p_incDec(PREPOST_ pp, Opcode opcode, SemVal *e) { register unsigned varnr; if (p_testOperand(e, opcode)) { util_semantic(gp_illegalType, gp_opstring[opcode]); return (e); } if (!test_type(e, e_var)) { util_semantic(gp_lvalueNeeded, gp_opstring[opcode]); return (e); } varnr = e->evalue; e->codelen = 0; /* INITIALIZED CODELEN HERE */ msg(" inc/dec opcode BEGIN"); p_generateCode(e, opcode, varnr); /* Generate INC/DEC opcode */ msg(" inc/dec opcode END"); e->type = /* Indicate pre/post inc- decrement */ (pp == pre_op) ? e_int | e_pre_inc_dec /* NB: no e_stack yet: push the */ : /* value on the stack when */ e_int | e_post_inc_dec; /* required */ return e; } icmake-9.02.06/comp/parser/psmequal.c0000644000175000017500000000167213176557635016362 0ustar frankfrank#include "parser.ih" SemVal *p_smEqual(SemVal *lval, SemVal *rval) { p_bool2int(lval); /* convert boolean to i */ p_bool2int(rval); if (p_conflict(lval, rval, op_smeq)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) { if (test_type(lval, e_int)) lval->evalue = (lval->evalue <= rval->evalue); else { lval->evalue = ( strcmp ( gp_stringTable[lval->evalue].string, gp_stringTable[rval->evalue].string ) ) <= 0; set_type(lval, e_int | e_const); } } else p_binOp(lval, rval, op_smeq); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pif.c0000644000175000017500000000301413232306464015262 0ustar frankfrank#include "parser.ih" SemVal *p_if(SemVal *cond, SemVal *trueStmnt, SemVal *falseStmnt) { register unsigned len; unsigned *list; gp_nestLevel--; /* reduce nesting level */ p_expr2bool(cond); /* make links for cond */ if (test_type(cond, e_const)) /* consts: either always/never */ { p_discard(cond); if (cond->evalue) /* trueStmnt always executed */ { p_discard(falseStmnt); return trueStmnt; } /* falsestmnt always executed */ p_discard(trueStmnt); return falseStmnt; } p_patchupTrue(cond, 1); /* true dest: the end of cond */ if (!falseStmnt->type) /* no falsestmnt */ { p_catCode(cond, trueStmnt); /* cond = cond ~ trueStmnt */ return cond; } p_generateCode(trueStmnt, op_jmp, j_falselist); list = trueStmnt->falselist; /* save the falselist */ len = trueStmnt->falselen; p_addPatch(list, len, cond->codelen); /* increase the patch targets */ trueStmnt->falselen = 0; p_catCode(cond, trueStmnt); /* cond = cond ~ trueStmnt */ p_patchupFalse(cond, 1); /* patch to EOC */ cond->falselen = len; /* restore the falselist */ cond->falselist = list; p_catCode(cond, falseStmnt); /* if .. else cat. */ return cond; /* if .. else return */ } icmake-9.02.06/comp/parser/pternary.c0000644000175000017500000000257313176557635016400 0ustar frankfrank#include "parser.ih" SemVal *p_ternary(SemVal *cond, SemVal *ifTrue, SemVal *ifFalse) { if ((ifTrue->type & ifFalse->type & e_typeMask) == 0) { util_semantic(gp_typeConflict, "?:"); return p_nullFrame3(cond, ifTrue, ifFalse); } if (test_type(cond, e_const)) /* constant: true or false */ { p_discard(cond); if (cond->evalue) { p_discard(ifFalse); p_expr2stack(ifTrue); return ifTrue; } p_discard(ifTrue); p_expr2stack(ifFalse); return ifFalse; } p_expr2bool(cond); /* convert the condition to bool */ p_expr2stack(ifTrue); /* convert the expressions to code */ p_expr2stack(ifFalse); p_patchupTrue(cond, 1); /* destination for the ifTrue code */ p_catCode(cond, ifTrue); /* cond = cond + ifTrue */ p_generateCode(cond, op_jmp, j_truelist); /* jmp around ifFalse */ p_patchupFalse(cond, 1); /* destination of the false alternative */ p_catCode(cond, ifFalse); /* cond = cond + ifTrue + jmp + ifFalse */ p_patchupTrue(cond, 1); /* jump from ifTrue to the end of expr. */ set_type(cond, ifTrue->type); /* return type must be the ifTrue/ifFalse type */ return cond; /* ?: return */ } icmake-9.02.06/comp/parser/pcallhidden.c0000644000175000017500000000116013176557635016772 0ustar frankfrank///* // Hidden functions are called by their negative function offset // to be patched up at code-generation time //*/ // //#include "parser.ih" // //void p_callHidden(register int fun, SemVal *rarg) //{ // gp_hidden_called = 1; /* hidden function calls */ // // gp_hiddenFun[fun].this = 1; /* this hidden function is called */ // // p_generateCode(rarg, op_call, -fun); /* dummy, to be address of hidden */ // // p_generateCode(rarg, op_asp, gp_hiddenFun[fun].nargs); /* clear pushed arguments */ // // set_type(rarg, gp_hiddenFun[fun].type); /* set the returntype */ //} icmake-9.02.06/comp/parser/pbtoi.c0000644000175000017500000000071013176557635015640 0ustar frankfrank#include "parser.ih" void p_bool2int(SemVal *e) { if (!test_type(e, e_bool)) /* no batchpatching needed */ return; p_patchupTrue(e, 1); e->truelen = 0; p_generateCode(e, op_push_1_jmp_end); /* truelist target */ p_patchupFalse(e, 1); e->falselen = 0; p_generateCode(e, op_push_0); /* falselist target */ set_type(e, e_int | e_stack); /* set int code type */ } icmake-9.02.06/comp/parser/pnextcall.c0000644000175000017500000000413313176557635016520 0ustar frankfrank#include "parser.ih" int p_nextCall(void) { register int opcode; switch (opcode = rss_getOpcode(gp_bin)) { case op_push_imm: case op_jmp: case op_jmp_false: case op_jmp_true: case op_push_strconst: case op_push_var: case op_pop_var: case op_copy_var: case op_inc: case op_dec: fseek(gp_bin, sizeof(int16_t), SEEK_CUR); return 0; /* close, but no cigar */ case op_push_1_jmp_end: case op_call_rss: case op_asp: fseek(gp_bin, sizeof(char), SEEK_CUR); return 0; /* close, but no cigar */ case op_push_0: case op_push_reg: case op_umin: case op_atoi: case op_itoa: case op_atol: case op_mul: case op_div: case op_mod: case op_add: case op_sub: case op_eq: case op_neq: case op_sm: case op_gr: case op_younger: case op_older: case op_smeq: case op_greq: case op_exit: case op_ret: case op_band: case op_bor: case op_bnot: case op_xor: case op_shl: case op_shr: case op_pop_reg: /* no argument with opcodes */ return 0; /* close, but no cigar */ case op_call: return 1; /* cigar! check this argument */ case op_frame: /* next byte: # bytes to skip */ fseek(gp_bin, (int)rss_getOpcode(gp_bin), SEEK_CUR); return 0; /* close, but no cigar */ default: rss_fatal(0, 0, "at offset 0x%lx:\n" "*INTERNAL ICM-COMP COMPILER ERROR / INVALID BIM-FILE*\n" "In function p_nextCall: unrecognized opcode " "0x%x encountered\n", ftell(gp_bin), opcode ); } return 0; } icmake-9.02.06/comp/parser/pxor.c0000644000175000017500000000115413176557635015516 0ustar frankfrank#include "parser.ih" SemVal *p_xor(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_xor, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_xor)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) lval->evalue ^= rval->evalue; else p_binOp(lval, rval, op_xor); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/prmjmpzero.c0000644000175000017500000000042513176557635016733 0ustar frankfrank#include "parser.ih" unsigned p_rmJmpZero(register unsigned codelen, unsigned *list, register unsigned listlen) { return listlen && (list[listlen - 1] == codelen) ? (sizeof(int8_t) + sizeof(int16_t)) : 0 ; } icmake-9.02.06/comp/parser/ponearg.c0000644000175000017500000000314513176557635016163 0ustar frankfrank#include "parser.ih" SemVal *p_oneArg(ExprType type, SemVal *arg) { msg("calling function 0x%x", type); register int ok; p_expr2stack(arg); /* arg to stack */ switch ((FunNr)type) { case f_ascii_int: if ( (ok = test_type(arg, e_str | e_int)) ) { if (test_type(arg, e_int)) /* int received */ type = f_ascii_str; /* string returned */ } break; case f_listlen: if (strcmp(scanner_savedText(), "listlen") != 0) rss_warning(util_sourceName(), scanner_savedLineNr(), "`%s' is deprecated. Use `listlen'\n", scanner_savedText()); ok = test_type(arg, e_list); break; case f_echo: ok = test_type(arg, e_int); break; default: /* case f_backtick: case f_getenv: case f_putenv: case f_eval: case f_exists: case f_cmd_head: case f_cmd_tail: case f_arg_head: case f_arg_tail: case f_g_path: case f_g_base: case f_g_ext: case f_strlen: case f_strlwr: case f_strupr: case f_trim: case f_trimright: case f_trimleft: */ ok = test_type(arg, e_str); } if (ok) p_callRss(arg, type); else util_semantic(gp_typeConflict, gp_funstring[type]); return (arg); } icmake-9.02.06/comp/parser/pendfunction.c0000644000175000017500000000157413176557635017230 0ustar frankfrank#define msgx #include "parser.ih" static int8_t opret = op_ret; void p_endFunction(SemVal *funStmnt) { msg("START"); gp_nestLevel = 0; /* function completed: writing code to gp_bin now OK */ p_makeFrame(); /* make the frame, defining the local variables */ p_lastStmnt(funStmnt); /* add the function's statements, patching funStmnnt's false list */ if (!gp_dead[gp_dead_sp]) util_out(gp_bin, &opret, sizeof(int8_t)); /* add a 'ret' instruction */ else gp_dead[gp_dead_sp] = 0; /* leaving a function: code generation ok, */ /* e.g. to define global variables */ symtab_cleanup(); /* pop all but the global symtab, update the local variable offsets */ msg("END"); } icmake-9.02.06/comp/parser/parse.c0000644000175000017500000027422613176557635015654 0ustar frankfrank/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Copy the first part of user declarations. */ #line 1 "grammar" /* yacc.c:339 */ /* #define msg */ #include "parser.ih" #line 72 "parse.c" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* In a future release of Bison, this section will be replaced by #include "tokens.h". */ #ifndef YY_YY_TOKENS_H_INCLUDED # define YY_YY_TOKENS_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { ARG_HEAD = 258, ARG_TAIL = 259, ASCII = 260, BREAK = 261, CHDIR = 262, CMD_HEAD = 263, CMD_TAIL = 264, CONTINUE = 265, C_BASE = 266, C_EXT = 267, C_PATH = 268, G_BASE = 269, G_EXT = 270, G_DEXT = 271, G_PATH = 272, ELEMENT = 273, ELSE = 274, EVAL = 275, EXEC = 276, EXECUTE = 277, EXISTS = 278, EXIT = 279, FGETS = 280, FIELDS = 281, FOR = 282, FPRINTF = 283, GETENV = 284, GETCH = 285, GETPID = 286, GETS = 287, IDENTIFIER = 288, IF = 289, INT = 290, LIST = 291, LISTFIND = 292, LISTLEN = 293, LISTUNION = 294, MAKELIST = 295, ECHO_TOKEN = 296, NUMBER = 297, PRINTF = 298, PUTENV = 299, RETURN = 300, STAT = 301, STRCHR = 302, STRING = 303, STRINGTYPE = 304, STRLEN = 305, STRLWR = 306, RESIZE = 307, STRUPR = 308, STRFIND = 309, STRFORMAT = 310, SUBSTR = 311, SYSTEM = 312, TRIM = 313, TRIMLEFT = 314, TRIMRIGHT = 315, VOID = 316, WHILE = 317, AND_IS = 318, OR_IS = 319, XOR_IS = 320, SHL_IS = 321, SHR_IS = 322, DIV_IS = 323, MINUS_IS = 324, MUL_IS = 325, MOD_IS = 326, PLUS_IS = 327, OR = 328, AND = 329, EQUAL = 330, NOT_EQUAL = 331, SMALLER_EQUAL = 332, GREATER_EQUAL = 333, OLDER = 334, YOUNGER = 335, SHL = 336, SHR = 337, INC = 338, DEC = 339 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_TOKENS_H_INCLUDED */ /* Copy the second part of user declarations. */ #line 208 "parse.c" /* yacc.c:358 */ #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE # if (defined __GNUC__ \ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C # define YY_ATTRIBUTE(Spec) __attribute__(Spec) # else # define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif #ifndef YY_ATTRIBUTE_PURE # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) #endif #ifndef YY_ATTRIBUTE_UNUSED # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif #if !defined _Noreturn \ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) # if defined _MSC_VER && 1200 <= _MSC_VER # define _Noreturn __declspec (noreturn) # else # define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 891 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 109 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 84 /* YYNRULES -- Number of rules. */ #define YYNRULES 218 /* YYNSTATES -- Number of states. */ #define YYNSTATES 361 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 339 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 95, 80, 2, 106, 102, 93, 91, 103, 92, 2, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 75, 107, 83, 63, 84, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 100, 2, 105, 79, 2, 104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 108, 78, 101, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 76, 77, 81, 82, 85, 86, 87, 88, 89, 90, 97, 98 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 117, 117, 120, 124, 131, 137, 142, 148, 148, 155, 155, 161, 161, 167, 175, 177, 180, 186, 193, 199, 202, 207, 214, 221, 221, 230, 236, 238, 240, 244, 250, 258, 261, 268, 268, 275, 282, 290, 297, 304, 311, 318, 325, 332, 339, 346, 353, 360, 367, 374, 381, 388, 397, 404, 411, 418, 425, 432, 439, 446, 453, 460, 467, 474, 481, 488, 495, 502, 509, 515, 521, 527, 533, 539, 545, 551, 557, 565, 570, 575, 582, 584, 592, 600, 607, 611, 613, 615, 620, 622, 629, 631, 635, 667, 672, 676, 680, 681, 686, 696, 704, 713, 715, 717, 721, 723, 725, 727, 729, 731, 733, 735, 737, 739, 741, 743, 745, 747, 749, 751, 753, 755, 757, 759, 761, 765, 767, 769, 771, 773, 775, 777, 779, 781, 783, 785, 789, 791, 793, 797, 803, 807, 809, 813, 819, 823, 825, 829, 836, 842, 849, 858, 869, 877, 885, 892, 899, 906, 913, 916, 924, 930, 934, 956, 965, 972, 974, 978, 978, 988, 1003, 1018, 1040, 1064, 1070, 1076, 1076, 1086, 1086, 1092, 1097, 1102, 1104, 1108, 1113, 1117, 1127, 1127, 1133, 1135, 1141, 1144, 1146, 1148, 1150, 1153, 1156, 1159, 1164, 1166, 1170, 1176, 1184, 1191, 1199, 1201, 1203, 1207, 1214, 1220, 1228, 1231, 1240, 1248, 1250, 1259, 1264, 1276 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "ARG_HEAD", "ARG_TAIL", "ASCII", "BREAK", "CHDIR", "CMD_HEAD", "CMD_TAIL", "CONTINUE", "C_BASE", "C_EXT", "C_PATH", "G_BASE", "G_EXT", "G_DEXT", "G_PATH", "ELEMENT", "ELSE", "EVAL", "EXEC", "EXECUTE", "EXISTS", "EXIT", "FGETS", "FIELDS", "FOR", "FPRINTF", "GETENV", "GETCH", "GETPID", "GETS", "IDENTIFIER", "IF", "INT", "LIST", "LISTFIND", "LISTLEN", "LISTUNION", "MAKELIST", "ECHO_TOKEN", "NUMBER", "PRINTF", "PUTENV", "RETURN", "STAT", "STRCHR", "STRING", "STRINGTYPE", "STRLEN", "STRLWR", "RESIZE", "STRUPR", "STRFIND", "STRFORMAT", "SUBSTR", "SYSTEM", "TRIM", "TRIMLEFT", "TRIMRIGHT", "VOID", "WHILE", "'='", "AND_IS", "OR_IS", "XOR_IS", "SHL_IS", "SHR_IS", "DIV_IS", "MINUS_IS", "MUL_IS", "MOD_IS", "PLUS_IS", "'?'", "':'", "OR", "AND", "'|'", "'^'", "'&'", "EQUAL", "NOT_EQUAL", "'<'", "'>'", "SMALLER_EQUAL", "GREATER_EQUAL", "OLDER", "YOUNGER", "SHL", "SHR", "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "INC", "DEC", "'~'", "'['", "'}'", "')'", "','", "'`'", "']'", "'('", "';'", "'{'", "$accept", "input", "args", "break_ok", "break_stat", "closebrace", "$@1", "closepar", "$@2", "comma", "$@3", "compound", "condition", "continue_stat", "_voidtype", "def_var_or_fun", "enterid", "enter_varid", "err_expression", "$@4", "expr_code", "_p_casttype", "_string", "_func_or_var", "_backtick", "$@5", "expression", "_for", "_expr_list", "_opt_init_expression", "_opt_cond_expression", "_opt_inc_expression", "for_stat", "_partype", "_pars", "_opt_parlist", "_funvars", "_funid", "funcdef", "_zero_arg_funs", "_one_arg_funs", "_two_arg_funs", "_optint_string", "_comma_expr", "_optint_special", "_comma_arglist", "_opt_arglist", "_funname", "function", "_if", "_else", "if_stat", "_p_makeList_expr", "_p_makeList_normal", "_old_young", "_older_younger", "$@6", "p_makeList", "nesting", "ok", "openbrace", "$@7", "openpar", "$@8", "popdead", "pushdead", "_return_tail", "_leave", "return_stat", "semicol", "$@9", "_stm", "statement", "statements", "typed_condition", "typed_varlist", "_varType", "type_of_var", "var_condition", "var_expr", "var_expr_list", "_while", "while_stat", "zeroframe", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 61, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 63, 58, 328, 329, 124, 94, 38, 330, 331, 60, 62, 332, 333, 334, 335, 336, 337, 43, 45, 42, 47, 37, 33, 338, 339, 126, 91, 125, 41, 44, 96, 93, 40, 59, 123 }; # endif #define YYPACT_NINF -317 #define yypact_value_is_default(Yystate) \ (!!((Yystate) == (-317))) #define YYTABLE_NINF -219 #define yytable_value_is_error(Yytable_value) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { 48, -317, -317, -317, -317, 31, -26, -317, -317, -317, 24, -317, -317, -317, -317, -317, -317, -88, -86, -77, 2, 13, -317, -317, -39, -317, 26, -28, -317, -317, -317, -317, 646, 46, -22, 328, -317, -317, -17, -9, 46, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -10, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 646, 646, 646, 646, 646, 646, 646, 542, 51, -317, 771, -317, -317, -317, -317, -317, -317, -317, -1, -317, -317, -317, -317, -86, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 4, -317, -317, -317, 646, -317, -317, -317, -317, -317, -317, -5, -3, -317, -317, -317, -317, 25, -317, -317, 26, -317, -317, -317, -317, -317, -317, -317, -80, -80, -80, -80, -80, -80, 771, -317, -317, -317, 11, 771, -317, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, -317, -317, 646, -317, -317, -317, -317, -317, 16, -317, 53, -32, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 771, -317, 5, 26, 328, -317, -317, -317, -317, -317, -317, 26, -317, -317, 54, -317, -317, 56, 57, -317, -317, 58, 646, -317, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 733, 314, 421, 524, 627, 791, 225, 225, 75, 75, 75, 75, 75, 75, 117, 117, 133, 133, -80, -80, -80, 690, -317, -317, 12, 68, 59, -317, -317, -317, 72, -317, -24, -317, 74, -317, -317, -317, -317, -317, -317, 46, -317, -317, -317, -317, -317, -80, 646, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 0, 436, -317, 43, -317, -317, -317, -317, 190, -317, -317, 77, -317, -317, -317, -317, -317, -317, 646, 436, -317, -317, -317, 16, -317, 771, -317, -317, -317, 74, -317, -317, 141, -317, -317, 436, -317, -317, 436, -317, -317, -317, -317 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 205, 207, 206, 18, 0, 0, 3, 187, 208, 0, 1, 2, 100, 178, 21, 19, 0, 0, 22, 218, 0, 20, 214, 12, 218, 98, 0, 188, 175, 218, 211, 0, 0, 0, 0, 202, 96, 12, 0, 0, 179, 215, 112, 113, 105, 138, 111, 110, 127, 126, 128, 114, 116, 117, 115, 129, 106, 142, 143, 107, 130, 131, 178, 119, 102, 103, 104, 33, 132, 108, 133, 178, 109, 79, 178, 118, 137, 134, 31, 120, 122, 136, 121, 135, 178, 178, 139, 123, 124, 125, 0, 0, 0, 0, 0, 0, 0, 0, 78, 81, 212, 178, 178, 178, 178, 178, 178, 10, 12, 159, 22, 213, 13, 0, 7, 17, 185, 181, 181, 184, 181, 218, 187, 101, 0, 189, 187, 26, 0, 187, 178, 194, 178, 193, 218, 0, 24, 187, 199, 201, 187, 0, 178, 192, 0, 176, 94, 24, 24, 24, 24, 24, 74, 69, 76, 70, 72, 75, 34, 27, 28, 29, 0, 10, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 73, 0, 149, 24, 24, 24, 24, 24, 32, 0, 24, 170, 198, 83, 174, 160, 216, 190, 196, 9, 197, 25, 191, 24, 24, 0, 177, 182, 186, 183, 195, 200, 24, 95, 99, 12, 5, 164, 12, 12, 12, 82, 0, 0, 80, 36, 43, 44, 45, 46, 47, 39, 42, 38, 40, 41, 0, 48, 49, 59, 60, 58, 50, 51, 53, 54, 55, 56, 66, 65, 61, 62, 57, 63, 64, 67, 68, 0, 150, 12, 218, 218, 12, 158, 147, 11, 12, 12, 0, 85, 86, 187, 87, 88, 10, 15, 16, 0, 14, 10, 24, 24, 35, 77, 0, 37, 24, 24, 153, 141, 24, 154, 145, 168, 24, 166, 167, 169, 24, 24, 0, 23, 209, 203, 6, 4, 12, 52, 151, 140, 12, 12, 165, 84, 89, 187, 180, 0, 0, 24, 24, 172, 24, 181, 210, 180, 152, 173, 91, 10, 92, 218, 217, 6, 0, 180, 162, 0, 161, 163, 180, 93 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -317, -317, -146, -172, -317, -43, -317, -141, -317, -23, -317, -317, -49, -317, -317, 178, -38, -109, -115, -317, -163, -317, -317, -317, -317, -317, -47, -317, -153, -317, -317, -317, -317, 44, -317, -317, -317, -317, 182, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -138, -317, -116, -317, -317, -107, 83, 55, -317, -33, -317, -316, -143, -317, -317, -317, -114, -317, -317, -242, 65, -317, 3, -317, 6, -317, 171, -317, -317, -317, -20 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 5, 234, 337, 123, 124, 125, 207, 208, 299, 34, 126, 293, 127, 6, 7, 20, 21, 128, 129, 130, 163, 99, 100, 240, 241, 101, 131, 289, 290, 334, 348, 132, 37, 38, 39, 25, 14, 15, 102, 103, 104, 105, 307, 106, 310, 282, 107, 108, 133, 354, 134, 109, 210, 316, 286, 287, 110, 212, 30, 135, 136, 26, 27, 342, 213, 227, 137, 138, 16, 17, 139, 140, 35, 295, 141, 9, 142, 322, 23, 24, 143, 144, 36 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 31, 33, 147, 8, 237, 238, 10, 13, 8, 217, 42, 10, 214, 219, 215, 145, 221, 198, 199, 28, 200, 29, 226, 243, 229, 18, 18, 230, 351, -100, 148, 11, 40, 235, 236, 235, 235, 239, 358, 149, 1, 2, 150, 360, 153, 154, 155, 156, 157, 158, 159, 164, 151, 152, 3, -168, -168, 19, 111, 288, 281, 1, 2, 314, 315, -23, 1, 2, -204, 201, 202, 203, 204, 205, 206, 3, 32, 335, 41, 111, 3, 113, 220, 1, 2, -97, 209, 277, 278, 279, 280, 235, 4, 146, 285, 344, -148, 3, 222, 165, 223, -165, 216, 225, -218, 218, 336, -90, 294, 4, 231, 357, -218, 242, 359, 306, 294, 228, -218, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 40, 319, 276, 332, 284, -156, 323, -155, -157, 353, -146, 301, 329, 191, 192, 193, 194, 195, 196, 197, 309, 198, 199, -171, 200, 318, 317, 288, -144, 356, 297, 298, 12, 324, 325, 283, 321, 347, 232, 327, 328, 22, 340, 235, 302, 330, 211, 331, 350, 224, 233, 292, 333, 112, 0, 0, 352, 193, 194, 195, 196, 197, 0, 198, 199, 300, 200, 0, 0, 341, 0, 0, 345, 346, 291, 195, 196, 197, 296, 198, 199, 0, 200, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 326, 0, 320, 308, 311, 0, 312, 313, 177, 0, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 343, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 338, 0, 0, 0, 0, 339, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 349, 198, 199, 0, 200, 0, 0, 0, 114, 355, -24, -24, -24, 115, -24, -24, -24, 116, -24, -24, -24, -24, -24, -24, -24, -24, 0, -24, -24, -24, -24, 117, -24, -24, 118, -24, -24, -24, -24, -24, -24, 119, 1, 2, -24, -24, -24, -24, -24, -24, -24, -24, 120, -24, -24, -24, 3, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, 0, 121, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200, 0, 0, 0, 0, -24, -24, 0, 0, 0, -24, -24, -24, -24, 0, -8, 0, 0, -24, 0, -24, 122, -176, 114, 0, -24, -24, -24, 115, -24, -24, -24, 116, -24, -24, -24, -24, -24, -24, -24, -24, 0, -24, -24, -24, -24, 117, -24, -24, 118, -24, -24, -24, -24, -24, -24, 119, 1, 2, -24, -24, -24, -24, -24, -24, -24, -24, 120, -24, -24, -24, 3, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, 0, 121, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200, 0, 0, 0, 0, 0, -24, -24, 0, 0, 0, -24, -24, -24, -24, 0, 0, 0, 0, -24, 0, -24, 122, -176, 43, 44, 45, 0, 46, 47, 48, 0, 49, 50, 51, 52, 53, 54, 55, 56, 0, 57, 58, 59, 60, 0, 61, 62, 0, 63, 64, 65, 66, 67, 68, 0, 160, 161, 69, 70, 71, 72, 73, 74, 75, 76, 0, 77, 78, 79, 162, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 91, 92, 0, 0, 0, 93, 94, 95, 96, 0, 0, 0, 0, 97, 0, 98, 43, 44, 45, 0, 46, 47, 48, 0, 49, 50, 51, 52, 53, 54, 55, 56, 0, 57, 58, 59, 60, 0, 61, 62, 0, 63, 64, 65, 66, 67, 68, 0, 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, 0, 77, 78, 79, 0, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 92, 0, 0, 0, 93, 94, 95, 96, 0, 0, 0, 0, 97, 0, 98, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 0, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200, 0, 0, 0, 0, 304, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 303, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 0, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, 199, 0, 200 }; static const yytype_int16 yycheck[] = { 20, 24, 40, 0, 150, 151, 0, 33, 5, 123, 30, 5, 119, 127, 121, 38, 130, 97, 98, 107, 100, 107, 137, 164, 138, 1, 1, 141, 344, 106, 63, 0, 26, 148, 149, 150, 151, 152, 354, 72, 35, 36, 75, 359, 91, 92, 93, 94, 95, 96, 97, 98, 85, 86, 49, 87, 88, 33, 33, 222, 206, 35, 36, 87, 88, 63, 35, 36, 107, 102, 103, 104, 105, 106, 107, 49, 63, 319, 106, 33, 49, 103, 129, 35, 36, 102, 109, 202, 203, 204, 205, 206, 61, 102, 209, 337, 106, 49, 131, 48, 133, 102, 122, 108, 107, 101, 63, 107, 223, 61, 143, 353, 107, 102, 356, 103, 231, 137, 102, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 145, 293, 200, 317, 102, 102, 298, 102, 102, 19, 102, 104, 309, 89, 90, 91, 92, 93, 94, 95, 103, 97, 98, 102, 100, 290, 103, 341, 102, 352, 224, 231, 5, 299, 300, 206, 296, 341, 145, 305, 306, 10, 331, 309, 242, 312, 114, 313, 342, 135, 146, 222, 318, 33, -1, -1, 348, 91, 92, 93, 94, 95, -1, 97, 98, 239, 100, -1, -1, 334, -1, -1, 338, 339, 222, 93, 94, 95, 223, 97, 98, -1, 100, -1, -1, -1, 231, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 278, 303, -1, 296, 279, 280, -1, 285, 286, 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, 336, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 325, -1, -1, -1, -1, 330, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 341, 97, 98, -1, 100, -1, -1, -1, 1, 350, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, 62, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, -1, 91, 92, -1, -1, -1, 96, 97, 98, 99, -1, 101, -1, -1, 104, -1, 106, 107, 108, 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, 62, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, -1, -1, 91, 92, -1, -1, -1, 96, 97, 98, 99, -1, -1, -1, -1, 104, -1, 106, 107, 108, 3, 4, 5, -1, 7, 8, 9, -1, 11, 12, 13, 14, 15, 16, 17, 18, -1, 20, 21, 22, 23, -1, 25, 26, -1, 28, 29, 30, 31, 32, 33, -1, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, 91, 92, -1, -1, -1, 96, 97, 98, 99, -1, -1, -1, -1, 104, -1, 106, 3, 4, 5, -1, 7, 8, 9, -1, 11, 12, 13, 14, 15, 16, 17, 18, -1, 20, 21, 22, 23, -1, 25, 26, -1, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 38, 39, 40, 41, 42, 43, 44, -1, 46, 47, 48, -1, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, 92, -1, -1, -1, 96, 97, 98, 99, -1, -1, -1, -1, 104, -1, 106, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, -1, 105, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, 97, 98, -1, 100 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 35, 36, 49, 61, 110, 123, 124, 184, 185, 186, 0, 124, 33, 146, 147, 178, 179, 1, 33, 125, 126, 147, 188, 189, 145, 171, 172, 107, 107, 168, 192, 63, 118, 119, 182, 192, 142, 143, 144, 186, 106, 192, 3, 4, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 91, 92, 96, 97, 98, 99, 104, 106, 131, 132, 135, 148, 149, 150, 151, 153, 156, 157, 161, 166, 33, 188, 103, 1, 6, 10, 24, 27, 34, 45, 62, 107, 113, 114, 115, 120, 122, 127, 128, 129, 136, 141, 158, 160, 169, 170, 176, 177, 180, 181, 184, 186, 190, 191, 118, 102, 125, 171, 171, 171, 171, 171, 135, 135, 135, 135, 135, 135, 135, 35, 36, 49, 130, 135, 48, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 97, 98, 100, 171, 171, 171, 171, 171, 171, 116, 117, 118, 162, 168, 167, 174, 167, 167, 192, 178, 101, 178, 135, 178, 171, 171, 182, 108, 127, 175, 192, 178, 178, 171, 142, 169, 111, 127, 127, 111, 111, 127, 133, 134, 102, 116, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 127, 127, 127, 127, 111, 155, 192, 102, 127, 164, 165, 129, 137, 138, 184, 192, 121, 127, 183, 186, 114, 121, 118, 118, 104, 135, 75, 105, 118, 103, 152, 192, 103, 154, 192, 118, 118, 87, 88, 163, 103, 178, 116, 125, 126, 187, 116, 127, 127, 135, 127, 127, 111, 164, 127, 129, 127, 139, 181, 63, 112, 118, 118, 162, 178, 173, 135, 181, 127, 127, 137, 140, 192, 174, 173, 116, 19, 159, 192, 112, 181, 173, 181, 173 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 109, 110, 110, 111, 111, 112, 113, 115, 114, 117, 116, 119, 118, 120, 121, 121, 122, 123, 124, 124, 124, 125, 126, 128, 127, 129, 130, 130, 130, 131, 131, 132, 132, 134, 133, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 136, 137, 137, 138, 138, 138, 139, 139, 140, 140, 141, 142, 143, 143, 144, 144, 145, 146, 147, 148, 148, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 151, 151, 151, 152, 152, 153, 153, 154, 154, 155, 155, 156, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 158, 159, 159, 160, 161, 162, 163, 163, 165, 164, 166, 166, 166, 166, 167, 168, 170, 169, 172, 171, 173, 174, 175, 175, 176, 176, 177, 179, 178, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, 181, 182, 182, 183, 184, 185, 185, 185, 186, 187, 187, 188, 188, 189, 189, 189, 190, 191, 192 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 1, 3, 1, 0, 1, 0, 2, 0, 2, 0, 2, 3, 1, 1, 1, 1, 2, 2, 2, 1, 1, 0, 2, 1, 1, 1, 1, 2, 1, 2, 1, 0, 2, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 4, 1, 1, 3, 1, 3, 2, 3, 1, 1, 1, 1, 1, 0, 1, 1, 11, 2, 3, 1, 1, 0, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 3, 5, 7, 4, 4, 3, 3, 3, 3, 1, 2, 2, 1, 9, 3, 0, 1, 1, 0, 2, 2, 3, 6, 7, 1, 1, 0, 2, 0, 2, 0, 0, 1, 1, 1, 1, 2, 0, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 3, 2, 3, 3, 1, 3, 2, 7, 0 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*----------------------------------------. | Print this symbol's value on YYOUTPUT. | `----------------------------------------*/ static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyo = yyoutput; YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyoutput, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T yystrlen (const char *yystr) { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (void) { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 4: #line 127 "grammar" /* yacc.c:1646 */ { (yyval) = *p_multipleArgs(&(yyvsp[-2]), &(yyvsp[0])); } #line 1687 "parse.c" /* yacc.c:1646 */ break; case 5: #line 132 "grammar" /* yacc.c:1646 */ { (yyval) = *p_firstArg(&(yyvsp[0])); } #line 1695 "parse.c" /* yacc.c:1646 */ break; case 6: #line 137 "grammar" /* yacc.c:1646 */ { gp_breakOK++; } #line 1703 "parse.c" /* yacc.c:1646 */ break; case 7: #line 143 "grammar" /* yacc.c:1646 */ { (yyval) = *p_break(); } #line 1711 "parse.c" /* yacc.c:1646 */ break; case 8: #line 148 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_closebrace_expected; symtab_pop(); } #line 1720 "parse.c" /* yacc.c:1646 */ break; case 10: #line 155 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_closepar_expected; } #line 1728 "parse.c" /* yacc.c:1646 */ break; case 12: #line 161 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_comma_expected; } #line 1736 "parse.c" /* yacc.c:1646 */ break; case 14: #line 170 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } #line 1744 "parse.c" /* yacc.c:1646 */ break; case 17: #line 181 "grammar" /* yacc.c:1646 */ { (yyval) = *p_continue(); } #line 1752 "parse.c" /* yacc.c:1646 */ break; case 18: #line 187 "grammar" /* yacc.c:1646 */ { gp_varType = 0; } #line 1760 "parse.c" /* yacc.c:1646 */ break; case 19: #line 195 "grammar" /* yacc.c:1646 */ { gp_init = *p_catCode(&gp_init, &(yyvsp[-1])); } #line 1768 "parse.c" /* yacc.c:1646 */ break; case 22: #line 208 "grammar" /* yacc.c:1646 */ { p_defineVar(); /* the first n variables of a function, up to the end of the parameter list are the parameters. */ } #line 1777 "parse.c" /* yacc.c:1646 */ break; case 23: #line 215 "grammar" /* yacc.c:1646 */ { (yyval) = *p_fetchVar(); } #line 1785 "parse.c" /* yacc.c:1646 */ break; case 24: #line 221 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_in_expression; } #line 1793 "parse.c" /* yacc.c:1646 */ break; case 25: #line 225 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 1801 "parse.c" /* yacc.c:1646 */ break; case 26: #line 231 "grammar" /* yacc.c:1646 */ { (yyval) = *p_expression(&(yyvsp[0])); } #line 1809 "parse.c" /* yacc.c:1646 */ break; case 30: #line 246 "grammar" /* yacc.c:1646 */ { /* catenate the new string */ gp_stringbuf = rss_strcat(gp_stringbuf, util_string()); } #line 1817 "parse.c" /* yacc.c:1646 */ break; case 31: #line 251 "grammar" /* yacc.c:1646 */ { free(gp_stringbuf); /* free former string */ gp_stringbuf = rss_strdup(util_string()); /* duplicate initial string */ } #line 1826 "parse.c" /* yacc.c:1646 */ break; case 33: #line 262 "grammar" /* yacc.c:1646 */ { (yyval) = *p_fetchVar(); } #line 1834 "parse.c" /* yacc.c:1646 */ break; case 34: #line 268 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_backtick_expected; } #line 1842 "parse.c" /* yacc.c:1646 */ break; case 36: #line 278 "grammar" /* yacc.c:1646 */ { (yyval) = *p_assign(&(yyvsp[-2]), &(yyvsp[0])); } #line 1850 "parse.c" /* yacc.c:1646 */ break; case 37: #line 286 "grammar" /* yacc.c:1646 */ { (yyval) = *p_indexOp(&(yyvsp[-3]), &(yyvsp[-1])); } #line 1858 "parse.c" /* yacc.c:1646 */ break; case 38: #line 293 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_multiply, "*="); } #line 1866 "parse.c" /* yacc.c:1646 */ break; case 39: #line 300 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_divide, "/="); } #line 1874 "parse.c" /* yacc.c:1646 */ break; case 40: #line 307 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_modulo, "%="); } #line 1882 "parse.c" /* yacc.c:1646 */ break; case 41: #line 314 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_addition, "+="); } #line 1890 "parse.c" /* yacc.c:1646 */ break; case 42: #line 321 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_subtract, "-="); } #line 1898 "parse.c" /* yacc.c:1646 */ break; case 43: #line 328 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_and, "&="); } #line 1906 "parse.c" /* yacc.c:1646 */ break; case 44: #line 335 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_or, "|="); } #line 1914 "parse.c" /* yacc.c:1646 */ break; case 45: #line 342 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_xor, "^="); } #line 1922 "parse.c" /* yacc.c:1646 */ break; case 46: #line 349 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_shl, "<<="); } #line 1930 "parse.c" /* yacc.c:1646 */ break; case 47: #line 356 "grammar" /* yacc.c:1646 */ { (yyval) = *p_compoundAss(&(yyvsp[-2]), &(yyvsp[0]), p_shr, ">>="); } #line 1938 "parse.c" /* yacc.c:1646 */ break; case 48: #line 363 "grammar" /* yacc.c:1646 */ { (yyval) = *p_orBool(&(yyvsp[-2]), &(yyvsp[0])); } #line 1946 "parse.c" /* yacc.c:1646 */ break; case 49: #line 370 "grammar" /* yacc.c:1646 */ { (yyval) = *p_andBoolean(&(yyvsp[-2]), &(yyvsp[0])); } #line 1954 "parse.c" /* yacc.c:1646 */ break; case 50: #line 377 "grammar" /* yacc.c:1646 */ { (yyval) = *p_equal(&(yyvsp[-2]), &(yyvsp[0])); } #line 1962 "parse.c" /* yacc.c:1646 */ break; case 51: #line 384 "grammar" /* yacc.c:1646 */ { (yyval) = *p_unequal(&(yyvsp[-2]), &(yyvsp[0])); } #line 1970 "parse.c" /* yacc.c:1646 */ break; case 52: #line 393 "grammar" /* yacc.c:1646 */ { (yyval) = *p_ternary(&(yyvsp[-4]), &(yyvsp[-2]), &(yyvsp[0])); } #line 1978 "parse.c" /* yacc.c:1646 */ break; case 53: #line 400 "grammar" /* yacc.c:1646 */ { (yyval) = *p_smaller(&(yyvsp[-2]), &(yyvsp[0])); } #line 1986 "parse.c" /* yacc.c:1646 */ break; case 54: #line 407 "grammar" /* yacc.c:1646 */ { (yyval) = *p_greater(&(yyvsp[-2]), &(yyvsp[0])); } #line 1994 "parse.c" /* yacc.c:1646 */ break; case 55: #line 414 "grammar" /* yacc.c:1646 */ { (yyval) = *p_smEqual(&(yyvsp[-2]), &(yyvsp[0])); } #line 2002 "parse.c" /* yacc.c:1646 */ break; case 56: #line 421 "grammar" /* yacc.c:1646 */ { (yyval) = *p_grEqual(&(yyvsp[-2]), &(yyvsp[0])); } #line 2010 "parse.c" /* yacc.c:1646 */ break; case 57: #line 428 "grammar" /* yacc.c:1646 */ { (yyval) = *p_addition(&(yyvsp[-2]), &(yyvsp[0])); } #line 2018 "parse.c" /* yacc.c:1646 */ break; case 58: #line 435 "grammar" /* yacc.c:1646 */ { (yyval) = *p_and(&(yyvsp[-2]), &(yyvsp[0])); } #line 2026 "parse.c" /* yacc.c:1646 */ break; case 59: #line 442 "grammar" /* yacc.c:1646 */ { (yyval) = *p_or(&(yyvsp[-2]), &(yyvsp[0])); } #line 2034 "parse.c" /* yacc.c:1646 */ break; case 60: #line 449 "grammar" /* yacc.c:1646 */ { (yyval) = *p_xor(&(yyvsp[-2]), &(yyvsp[0])); } #line 2042 "parse.c" /* yacc.c:1646 */ break; case 61: #line 456 "grammar" /* yacc.c:1646 */ { (yyval) = *p_shl(&(yyvsp[-2]), &(yyvsp[0])); } #line 2050 "parse.c" /* yacc.c:1646 */ break; case 62: #line 463 "grammar" /* yacc.c:1646 */ { (yyval) = *p_shr(&(yyvsp[-2]), &(yyvsp[0])); } #line 2058 "parse.c" /* yacc.c:1646 */ break; case 63: #line 470 "grammar" /* yacc.c:1646 */ { (yyval) = *p_subtract(&(yyvsp[-2]), &(yyvsp[0])); } #line 2066 "parse.c" /* yacc.c:1646 */ break; case 64: #line 477 "grammar" /* yacc.c:1646 */ { (yyval) = *p_multiply(&(yyvsp[-2]), &(yyvsp[0])); } #line 2074 "parse.c" /* yacc.c:1646 */ break; case 65: #line 484 "grammar" /* yacc.c:1646 */ { (yyval) = *p_young(&(yyvsp[-2]), &(yyvsp[0])); } #line 2082 "parse.c" /* yacc.c:1646 */ break; case 66: #line 491 "grammar" /* yacc.c:1646 */ { (yyval) = *p_old(&(yyvsp[-2]), &(yyvsp[0])); } #line 2090 "parse.c" /* yacc.c:1646 */ break; case 67: #line 498 "grammar" /* yacc.c:1646 */ { (yyval) = *p_divide(&(yyvsp[-2]), &(yyvsp[0])); } #line 2098 "parse.c" /* yacc.c:1646 */ break; case 68: #line 505 "grammar" /* yacc.c:1646 */ { (yyval) = *p_modulo(&(yyvsp[-2]), &(yyvsp[0])); } #line 2106 "parse.c" /* yacc.c:1646 */ break; case 69: #line 511 "grammar" /* yacc.c:1646 */ { (yyval) = *p_negate(&(yyvsp[0])); } #line 2114 "parse.c" /* yacc.c:1646 */ break; case 70: #line 517 "grammar" /* yacc.c:1646 */ { (yyval) = *p_incDec(pre_op, op_inc, &(yyvsp[0])); } #line 2122 "parse.c" /* yacc.c:1646 */ break; case 71: #line 523 "grammar" /* yacc.c:1646 */ { (yyval) = *p_incDec(post_op, op_inc, &(yyvsp[-1])); } #line 2130 "parse.c" /* yacc.c:1646 */ break; case 72: #line 529 "grammar" /* yacc.c:1646 */ { (yyval) = *p_incDec(pre_op, op_dec, &(yyvsp[0])); } #line 2138 "parse.c" /* yacc.c:1646 */ break; case 73: #line 535 "grammar" /* yacc.c:1646 */ { (yyval) = *p_incDec(post_op, op_dec, &(yyvsp[-1])); } #line 2146 "parse.c" /* yacc.c:1646 */ break; case 74: #line 541 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2154 "parse.c" /* yacc.c:1646 */ break; case 75: #line 547 "grammar" /* yacc.c:1646 */ { (yyval) = *p_not(&(yyvsp[0])); } #line 2162 "parse.c" /* yacc.c:1646 */ break; case 76: #line 553 "grammar" /* yacc.c:1646 */ { (yyval) = *p_notBoolean(&(yyvsp[0])); } #line 2170 "parse.c" /* yacc.c:1646 */ break; case 77: #line 561 "grammar" /* yacc.c:1646 */ { (yyval) = *p_cast((yyvsp[-2]).type, &(yyvsp[0])); } #line 2178 "parse.c" /* yacc.c:1646 */ break; case 78: #line 566 "grammar" /* yacc.c:1646 */ { (yyval) = *p_stackFrame(e_str | e_const); } #line 2186 "parse.c" /* yacc.c:1646 */ break; case 79: #line 571 "grammar" /* yacc.c:1646 */ { (yyval) = *p_stackFrame(e_int | e_const); } #line 2194 "parse.c" /* yacc.c:1646 */ break; case 80: #line 578 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } #line 2202 "parse.c" /* yacc.c:1646 */ break; case 82: #line 587 "grammar" /* yacc.c:1646 */ { (yyval) = *p_oneArg(f_backtick, &(yyvsp[-1])); } #line 2210 "parse.c" /* yacc.c:1646 */ break; case 83: #line 594 "grammar" /* yacc.c:1646 */ { symtab_push(); } #line 2218 "parse.c" /* yacc.c:1646 */ break; case 84: #line 603 "grammar" /* yacc.c:1646 */ { (yyval) = *p_catCode(&(yyvsp[-2]), &(yyvsp[0])); } #line 2226 "parse.c" /* yacc.c:1646 */ break; case 90: #line 622 "grammar" /* yacc.c:1646 */ { (yyval) = *p_stackFrame(e_int | e_const); (yyval).evalue = 1; } #line 2235 "parse.c" /* yacc.c:1646 */ break; case 93: #line 646 "grammar" /* yacc.c:1646 */ { (yyval) = *p_for(&(yyvsp[-8]), &(yyvsp[-6]), &(yyvsp[-4]), &(yyvsp[-1])); } #line 2243 "parse.c" /* yacc.c:1646 */ break; case 99: #line 690 "grammar" /* yacc.c:1646 */ { symtab_setFunParams(); /* the # variables so far are the parameters */ } #line 2251 "parse.c" /* yacc.c:1646 */ break; case 100: #line 697 "grammar" /* yacc.c:1646 */ { p_beginFunction(); } #line 2259 "parse.c" /* yacc.c:1646 */ break; case 101: #line 708 "grammar" /* yacc.c:1646 */ { p_endFunction(&(yyvsp[-1])); } #line 2267 "parse.c" /* yacc.c:1646 */ break; case 140: #line 799 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2275 "parse.c" /* yacc.c:1646 */ break; case 144: #line 815 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2283 "parse.c" /* yacc.c:1646 */ break; case 148: #line 830 "grammar" /* yacc.c:1646 */ { (yyval).evalue = p_functionIdx(); } #line 2291 "parse.c" /* yacc.c:1646 */ break; case 149: #line 838 "grammar" /* yacc.c:1646 */ { (yyval) = *p_zeroArgs((yyvsp[-1]).type); } #line 2299 "parse.c" /* yacc.c:1646 */ break; case 150: #line 845 "grammar" /* yacc.c:1646 */ { (yyval) = *p_oneArg((yyvsp[-2]).type, &(yyvsp[0])); } #line 2307 "parse.c" /* yacc.c:1646 */ break; case 151: #line 854 "grammar" /* yacc.c:1646 */ { (yyval) = *p_twoArgs((yyvsp[-4]).type, &(yyvsp[-2]), &(yyvsp[0])); } #line 2315 "parse.c" /* yacc.c:1646 */ break; case 152: #line 865 "grammar" /* yacc.c:1646 */ { (yyval) = *p_threeArgs((yyvsp[-6]).type, &(yyvsp[-4]), &(yyvsp[-2]), &(yyvsp[0])); } #line 2323 "parse.c" /* yacc.c:1646 */ break; case 153: #line 873 "grammar" /* yacc.c:1646 */ { (yyval) = *p_optIntString((yyvsp[-3]).type, &(yyvsp[-1]), &(yyvsp[0])); } #line 2331 "parse.c" /* yacc.c:1646 */ break; case 154: #line 881 "grammar" /* yacc.c:1646 */ { (yyval) = *p_optIntSpecial((yyvsp[-3]).type, &(yyvsp[-1]), &(yyvsp[0])); } #line 2339 "parse.c" /* yacc.c:1646 */ break; case 155: #line 888 "grammar" /* yacc.c:1646 */ { (yyval) = *p_specials(f_printf, &(yyvsp[0])); } #line 2347 "parse.c" /* yacc.c:1646 */ break; case 156: #line 895 "grammar" /* yacc.c:1646 */ { (yyval) = *p_fprintf((yyvsp[-2]).type, &(yyvsp[0])); } #line 2355 "parse.c" /* yacc.c:1646 */ break; case 157: #line 902 "grammar" /* yacc.c:1646 */ { (yyval) = *p_specials(f_strformat, &(yyvsp[0])); } #line 2363 "parse.c" /* yacc.c:1646 */ break; case 158: #line 909 "grammar" /* yacc.c:1646 */ { (yyval) = *p_callFunction((yyvsp[-2]).evalue, &(yyvsp[0])); } #line 2371 "parse.c" /* yacc.c:1646 */ break; case 160: #line 918 "grammar" /* yacc.c:1646 */ { symtab_push(); } #line 2379 "parse.c" /* yacc.c:1646 */ break; case 161: #line 926 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2387 "parse.c" /* yacc.c:1646 */ break; case 163: #line 943 "grammar" /* yacc.c:1646 */ { (yyval) = *p_if(&(yyvsp[-6]), &(yyvsp[-4]), &(yyvsp[-1])); symtab_pop(); } #line 2396 "parse.c" /* yacc.c:1646 */ break; case 164: #line 959 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2404 "parse.c" /* yacc.c:1646 */ break; case 165: #line 965 "grammar" /* yacc.c:1646 */ { (yyval) = *p_stackFrame(e_int | e_const); (yyval).evalue = IS_FILE; } #line 2413 "parse.c" /* yacc.c:1646 */ break; case 168: #line 978 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_older_younger; } #line 2421 "parse.c" /* yacc.c:1646 */ break; case 169: #line 982 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2429 "parse.c" /* yacc.c:1646 */ break; case 170: #line 990 "grammar" /* yacc.c:1646 */ { (yyval) = *p_makeList ( p_multipleArgs ( p_firstArg(&(yyvsp[0])), /* IS_FILE is passed */ &(yyvsp[-1]) /* expression is passed */ ), op_hlt /* not op_younger or op_older */ ); } #line 2445 "parse.c" /* yacc.c:1646 */ break; case 171: #line 1006 "grammar" /* yacc.c:1646 */ { (yyval) = *p_makeList ( p_multipleArgs ( p_firstArg(&(yyvsp[-2])), /* fileattribute is passed */ &(yyvsp[0]) /* expression is passed */ ), op_hlt /* not op_younger or op_older */ ); } #line 2461 "parse.c" /* yacc.c:1646 */ break; case 172: #line 1024 "grammar" /* yacc.c:1646 */ { (yyval) = *p_makeList ( p_multipleArgs ( p_multipleArgs ( p_firstArg(&(yyvsp[0])), /* IS_FILE is passed */ &(yyvsp[-5]) /* 1st expression is passed */ ), &(yyvsp[-1]) /* 2nd expression is passed */ ), (yyvsp[-3]).type /* older/younger */ ); } #line 2481 "parse.c" /* yacc.c:1646 */ break; case 173: #line 1047 "grammar" /* yacc.c:1646 */ { (yyval) = *p_makeList ( p_multipleArgs ( p_multipleArgs ( p_firstArg(&(yyvsp[-6])), /* attribute is passed */ &(yyvsp[-4]) /* 2nd expression is passed */ ), &(yyvsp[0]) /* 3rd expression is passed */ ), (yyvsp[-2]).type /* older/younger */ ); } #line 2501 "parse.c" /* yacc.c:1646 */ break; case 174: #line 1065 "grammar" /* yacc.c:1646 */ { gp_nestLevel++; } #line 2509 "parse.c" /* yacc.c:1646 */ break; case 175: #line 1071 "grammar" /* yacc.c:1646 */ { yyerrok; } #line 2517 "parse.c" /* yacc.c:1646 */ break; case 176: #line 1076 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_openbrace_expected; } #line 2525 "parse.c" /* yacc.c:1646 */ break; case 177: #line 1080 "grammar" /* yacc.c:1646 */ { symtab_push(); } #line 2533 "parse.c" /* yacc.c:1646 */ break; case 178: #line 1086 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_openpar_expected; } #line 2541 "parse.c" /* yacc.c:1646 */ break; case 180: #line 1092 "grammar" /* yacc.c:1646 */ { p_popDead(); } #line 2549 "parse.c" /* yacc.c:1646 */ break; case 181: #line 1097 "grammar" /* yacc.c:1646 */ { p_pushDead(); /* set new dead-level */ } #line 2557 "parse.c" /* yacc.c:1646 */ break; case 184: #line 1109 "grammar" /* yacc.c:1646 */ { msg("saw return"); } #line 2565 "parse.c" /* yacc.c:1646 */ break; case 186: #line 1119 "grammar" /* yacc.c:1646 */ { (yyval) = *p_return((yyvsp[-1]).type, &(yyvsp[0])); msg("SAW return stmt"); } #line 2574 "parse.c" /* yacc.c:1646 */ break; case 187: #line 1127 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_semicol_expected; } #line 2582 "parse.c" /* yacc.c:1646 */ break; case 190: #line 1137 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2590 "parse.c" /* yacc.c:1646 */ break; case 201: #line 1172 "grammar" /* yacc.c:1646 */ { (yyval) = *p_catStmnts(&(yyvsp[-1]), &(yyvsp[0])); } #line 2598 "parse.c" /* yacc.c:1646 */ break; case 203: #line 1186 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2606 "parse.c" /* yacc.c:1646 */ break; case 204: #line 1193 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2614 "parse.c" /* yacc.c:1646 */ break; case 208: #line 1208 "grammar" /* yacc.c:1646 */ { gp_parse_error = err_identifier_expected; gp_varType = (yyvsp[0]).type; } #line 2623 "parse.c" /* yacc.c:1646 */ break; case 209: #line 1215 "grammar" /* yacc.c:1646 */ { p_generateCode(&(yyvsp[0]), op_push_imm, 0); (yyval) = (yyvsp[0]); } #line 2632 "parse.c" /* yacc.c:1646 */ break; case 210: #line 1223 "grammar" /* yacc.c:1646 */ { (yyval) = *p_assign(&(yyvsp[-2]), &(yyvsp[0])); /* explicit initialization */ } #line 2640 "parse.c" /* yacc.c:1646 */ break; case 212: #line 1234 "grammar" /* yacc.c:1646 */ { (yyval) = *p_expression(p_assign(&(yyvsp[-2]), &(yyvsp[0]))); /* explicit initialization */ } #line 2648 "parse.c" /* yacc.c:1646 */ break; case 213: #line 1243 "grammar" /* yacc.c:1646 */ { (yyval) = *p_catCode(&(yyvsp[-2]), &(yyvsp[0])); /* catenate variable */ /* initialization code */ } #line 2657 "parse.c" /* yacc.c:1646 */ break; case 215: #line 1253 "grammar" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } #line 2665 "parse.c" /* yacc.c:1646 */ break; case 217: #line 1271 "grammar" /* yacc.c:1646 */ { (yyval) = *p_while(&(yyvsp[-4]), &(yyvsp[-1]), 1); } #line 2673 "parse.c" /* yacc.c:1646 */ break; case 218: #line 1276 "grammar" /* yacc.c:1646 */ { (yyval) = *p_stackFrame(0); /* by default initializes a variable to 0 */ } #line 2681 "parse.c" /* yacc.c:1646 */ break; #line 2685 "parse.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 1281 "grammar" /* yacc.c:1906 */ int yywrap(void) { return 1; } icmake-9.02.06/comp/parser/pmultipleargs.c0000644000175000017500000000105313176557635017414 0ustar frankfrank#include "parser.ih" SemVal *p_multipleArgs(SemVal *left, SemVal *right) { register unsigned count; count = ++left->type; // get/increase # of args // room for extra SemVal left->code = rss_realloc(left->code, count * sizeof(SemVal)); p_expr2stack(right); // argument is code now // right expression in array *codestruc(left, count - 1) = *right; return left; /* done */ } icmake-9.02.06/comp/parser/parser.h0000644000175000017500000000032613176557635016027 0ustar frankfrank#ifndef INCLUDED_PARSER_H_ #define INCLUDED_PARSER_H_ #include "../global.h" void parser(char **argv); /* call once */ int yyparse(void); /* in parse.c */ int parser_backend(); #endif icmake-9.02.06/comp/parser/pgreater.c0000644000175000017500000000165613176557635016346 0ustar frankfrank#include "parser.ih" SemVal *p_greater(SemVal *lval, SemVal *rval) { p_bool2int(lval); /* convert boolean to i */ p_bool2int(rval); if (p_conflict(lval, rval, op_gr)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) { if (test_type(lval, e_int)) lval->evalue = (lval->evalue > rval->evalue); else { lval->evalue = ( strcmp ( gp_stringTable[lval->evalue].string, gp_stringTable[rval->evalue].string ) ) > 0; set_type(lval, e_int | e_const); } } else p_binOp(lval, rval, op_gr); return (lval); /* return new expression */ } icmake-9.02.06/comp/parser/pshr.c0000644000175000017500000000115513176557635015503 0ustar frankfrank#include "parser.ih" SemVal *p_shr(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_shr, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_shr)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) lval->evalue >>= rval->evalue; else p_binOp(lval, rval, op_shr); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pyyerror.c0000644000175000017500000000275313176557635016427 0ustar frankfrank#include "parser.ih" static char *err_msg[] = { "(", /* err_openpar_expected, */ ")", /* err_closepar_expected, */ "{", /* err_openbrace_expected, */ "}", /* err_closebrace_expected, */ ";", /* err_semicol_expected, */ "=", /* err_p_assign_expected, */ "error in expression", /* err_in_expression, */ ",", /* err_comma_expected, */ "statement(s)", /* err_statements_expected, */ "identifier", /* err_identifier_expected, */ "code or vars", /* err_code_or_vars_expected, */ ",' or ')'", /* err_comma_or_closepar_expected, */ "number", /* err_number_expected, */ "older', 'younger' or 'newer'", /* err_older_younger, */ "` (backtick)", /* err_backtick_expected, */ }; int yyerror(char *s) { if (!yytext[0]) rss_fatal(util_sourceName(), yylineno, "Unexpected end of file."); rss_error(util_sourceName(), yylineno, "at '%s': '%s'%s", yytext, err_msg[gp_parse_error], gp_parse_error == err_in_expression ? "" : " expected"); return 0; } icmake-9.02.06/comp/parser/pbinop.c0000644000175000017500000000052713176557635016020 0ustar frankfrank#define msg #include "parser.ih" void p_binOp(SemVal *lval, SemVal *rval, Opcode opcode) { p_expr2stack(lval); /* convert to code */ p_expr2stack(rval); p_catCode(lval, rval); p_generateCode(lval, opcode); /* append instruction */ set_type(lval, e_int | e_stack); /* set appropriate type */ } icmake-9.02.06/comp/parser/pcallrss.c0000644000175000017500000000741513176557635016357 0ustar frankfrank/*#define msg */ #include "parser.ih" void p_callRss(SemVal *e, FunNr funnr, ...) { register ExprType type = e_reg | e_int; /* default return type: intreg */ register unsigned args = 1; /* most f()s having 1 argument */ va_list marker; va_start(marker, funnr); msg("calling rss function 0x%x", funnr); p_generateCode(e, op_call_rss, funnr); /* call the function */ switch (funnr) { /* 0 args, returning string */ case f_getch: case f_gets: args--; type = e_str | e_reg; break; /* 0 args, returning int */ case f_getpid: args--; type = e_int | e_reg; break; /* 1 arg, returning string */ case f_strupr: case f_strlwr: case f_ascii_str: case f_g_base: case f_g_dext: case f_g_ext: case f_g_path: case f_trimleft: case f_trimright: case f_trim: type = e_str | e_reg; break; case f_eval: /* 1 arg, returning list */ case f_getenv: case f_backtick: type = e_list | e_reg; break; /* 2 arguments, returning int */ case f_listfind: case f_strfind: case f_strchr: case f_system: ++args; break; /* 2 args, returning string */ case f_chdir: case f_c_base: case f_c_ext: case f_c_path: case f_str_el: case f_element: case f_resize: ++args; /* two arguments */ type = e_str | e_reg; /* returning string */ break; /* 3 args, returning string */ case f_substr: args = 3; /* three arguments */ type = e_str | e_reg; /* returning string */ break; /* 2 args, returning list */ case f_listunion: case f_stat: case f_fgets: /* list fgets(string, int) */ case f_strtok: /* list strtok(string, string) */ // case f_makelist: /* list p_makeList(int, string) */ ++args; type = e_list | e_reg; break; /* # args passed as argument */ case f_makelist: /* list p_makeList(int, string) */ args = va_arg(marker, unsigned); type = e_list | e_reg; break; /* # args passed as argument */ case f_execute: case f_exec: case f_fprintf: case f_printf: args = va_arg(marker, unsigned); break; case f_strformat: args = va_arg(marker, unsigned); type = e_str | e_reg; break; default: /* default is entered in the switch to prevent a long compiler warning default: functions having one arg returning an int case f_ascii_int: case f_putenv: case f_arg_head: case f_arg_tail: case f_cmd_head: case f_cmd_tail: case f_echo: case f_exists: case f_listlen: case f_strlen: */ break; } if (args) p_generateCode (e, op_asp, args); /* add stack pointer */ set_type(e, type); /* type of resulting expression */ } icmake-9.02.06/comp/parser/pmakelist.c0000644000175000017500000000330213176557635016514 0ustar frankfrank/* Possibilities: 1- p_makeList(int, string) 2- p_makeList(int, string, older, string) -- younger ok too The parser may insert the int-argument as int IS_FILE */ #include "parser.ih" // op_hlt indicates not younger or older // otherwise it's younger or older SemVal *p_makeList(SemVal *args, ExprType type) { if ( /* first arg not int */ !test_type(codestruc(args, 0), e_int) || /* or second not string */ !test_type(codestruc(args, 1), e_str) || /* or three arguments, but */ ( args->type == 3 && /* last is not string */ !test_type(codestruc(args, 2), e_str) ) ) { util_semantic(gp_typeConflict, gp_funstring[f_makelist]); return p_stackFrame(e_list); } SemVal function; int nArgs = 3 + ((Opcode)type != op_hlt); memset(&function, 0, sizeof(SemVal)); function.type = e_int | e_const; // set the opcode value function.evalue = (Opcode)type; args = p_multipleArgs(args, &function); // make room // shift upwards memmove(args->code + sizeof(SemVal), args->code, ((int)args->type - 1) * sizeof(SemVal)); *(SemVal *)args->code = function; // put op_xxx first p_catArgs(args); // catenate all arguments p_callRss(args, f_makelist, nArgs); return args; // return called function code } icmake-9.02.06/comp/parser/pfirstarg.c0000644000175000017500000000077013176557635016532 0ustar frankfrank/* F I R S T A R G . C */ #include "parser.ih" static SemVal arr; SemVal *p_firstArg(SemVal *e) { p_expr2stack(e); /* argument is code now */ /* code points to SemVal */ arr.code = rss_realloc(NULL, sizeof(SemVal)); *(SemVal *)arr.code = *e; /* arr->code contains e */ arr.type = 1; /* type field: # of active e's */ return (&arr); } icmake-9.02.06/comp/parser/pcompoundass.c0000644000175000017500000000106213176557635017237 0ustar frankfrank#include "parser.ih" SemVal *p_compoundAss(SemVal *lval, SemVal *rval, SemVal *(*fun)(SemVal *, SemVal *), char *opstr) { register ExprType ltype; register unsigned evalue; ltype = lval->type; evalue = lval->evalue; fun(lval, rval); /* perform operation */ rval->type = ltype; /* restore ltype/value */ rval->evalue = evalue; rval->codelen = 0; rval->code = NULL; return p_assignment(rval, lval, opstr); /* perform p_assignment */ } icmake-9.02.06/comp/parser/ppatchupcontinue.c0000644000175000017500000000024713176557635020121 0ustar frankfrank#include "parser.ih" void p_patchupContinue(SemVal *e, int pos) { p_patchup(e->code, e->codelen, e->continuelist, e->continuelen, pos); e->continuelen = 0; } icmake-9.02.06/comp/parser/pforceexpr2bool.c0000644000175000017500000000065013176557635017641 0ustar frankfrank/* Force conversion of expression to boolean expression */ #include "parser.ih" void p_forceExpr2Bool(SemVal *e) { if (test_type(e, e_bool)) return; /* done if boolean aloready */ p_expr2stack(e); /* convert to code unless bool */ p_generateCode (e, op_jmp_true); p_generateCode (e, op_jmp, j_falselist); set_type(e, e_stack | e_bool); } icmake-9.02.06/comp/parser/pcatstmnts.c0000644000175000017500000000056513176557635016733 0ustar frankfrank /* #define msg */ #include "parser.ih" SemVal *p_catStmnts(SemVal *lval, SemVal *rval) { p_patchupFalse(lval, 1); msg("lval length: %u, rval length: %u", lval->codelen, rval->codelen); if (gp_nestLevel == 0) { util_out(gp_bin, lval->code, lval->codelen); p_discard(lval); return rval; } return p_catCode(lval, rval); } icmake-9.02.06/comp/parser/pexpr.c0000644000175000017500000000055513176557635015670 0ustar frankfrank#include "parser.ih" SemVal *p_expression(SemVal *e) { p_bool2int(e); /* convert boolean to i */ if (gp_lastOp == op_copy_var) p_popVar(e); else if ( test_type(e, e_stack) && !test_type(e, e_pre_inc_dec | e_post_inc_dec) ) p_generateCode(e, op_asp, 1); return (e); } icmake-9.02.06/comp/parser/pexpr2bool.c0000644000175000017500000000165213176557635016625 0ustar frankfrank/* Convert expression to boolean expression Links are not generated by p_expr2bool(), but they may exist. */ #include "parser.ih" void p_expr2bool(SemVal *e) { switch (e->type & (e_int | e_str | e_list | e_bool)) { case e_int: if (test_type(e, e_const)) { e->evalue = e->evalue != 0; set_type(e, e_int | e_const); return; } break; case e_str: if (test_type(e, e_const)) { e->evalue = 1; set_type(e, e_int | e_const); return; } break; case e_bool: return; } p_expr2stack(e); /* convert to code */ p_generateCode (e, op_jmp_true); p_generateCode (e, op_jmp, j_falselist); set_type(e, e_stack | e_bool); } icmake-9.02.06/comp/parser/passign.c0000644000175000017500000000024513176557635016172 0ustar frankfrank/* A S S I G N . C */ #include "parser.ih" SemVal *p_assign(SemVal *lval, SemVal *rval) { return p_assignment(lval, rval, "="); } icmake-9.02.06/comp/parser/parser.ih0000644000175000017500000002373113176557635016205 0ustar frankfrank#include "parser.h" #include #include #include #include "../../rss/rss.h" #include "../scanner/scanner.h" #include "../util/util.h" #include "../symtab/symtab.h" #include "semval.ih" #define test_type(e,v) ((e)->type & (v)) #define set_type(e,v) ((e)->type = (v)) #define up_type(e,v) ((e)->type |= (v)) #define down_type(e,v) ((e)->type &= ~(v)) #define e_typeMask (e_int | e_list | e_str | e_bool) #define codestruc(estruc, x) (&(((SemVal *)((estruc)->code))[x])) typedef enum /* order of elements must follow */ { /* definition of hidden[] in */ he_older = 0, /* data.c */ he_younger = 1, /* reserved values 0 and 1 */ he_ /* must be last ! */ } Hidden; typedef struct { char *name; /* name of the hidden fun */ char *source; /* source of the hidden function */ unsigned type; /* returntype */ unsigned this; /* set to 1 if called */ unsigned nargs; /* # of arguments */ } HiddenFunction; typedef struct { unsigned index; /* index in stringsection */ char *string; /* string itself */ } StringTable; typedef enum { err_openpar_expected, err_closepar_expected, err_openbrace_expected, err_closebrace_expected, err_semicol_expected, err_p_assign_expected, err_in_expression, err_comma_expected, err_statements_expected, err_identifier_expected, err_code_or_vars_expected, err_comma_or_closepar_expected, err_number_expected, err_older_younger, err_backtick_expected } PARSE_ERR_; typedef enum { pre_op, post_op } PREPOST_; typedef enum { j_uncond, /* unconditional jump */ j_truelist, /* jump batchpatch for truelist */ j_falselist, /* jump backbatch for falselist */ j_continuelist /* jump backp. for continuelist */ } JMP_COND_; extern int gp_parse_error; extern unsigned gp_breakOK; extern unsigned gp_nestLevel; extern unsigned gp_stringsize; extern char gp_typeConflict[]; extern char *gp_funstring[]; extern char gp_illegalType[]; extern char *gp_opstring[]; extern char gp_lvalueNeeded[]; extern char gp_illegalArgCount[]; extern char gp_illegalCast[]; extern char *gp_listlen; extern ExprType gp_varType; extern ExprType gp_opType[]; extern Opcode gp_lastOp; extern unsigned gp_dead_sp; extern unsigned *gp_dead; extern FILE *gp_bin; extern unsigned gp_hidden_called; extern HiddenFunction gp_hiddenFun[]; extern unsigned gp_nStrings; extern StringTable *gp_stringTable; extern SemVal gp_init; /* code initializing globals */ extern char *gp_stringbuf; extern int yydebug; /* ================================================================== */ SemVal *p_addition (SemVal *, SemVal *); /* + code */ SemVal *p_andBoolean (SemVal *, SemVal *); /* && code */ SemVal *p_assign (SemVal *, SemVal *); /* = code (shell) */ SemVal *p_and (SemVal *, SemVal *); /* & (binary) code */ SemVal *p_not (SemVal *); /* ~ code */ SemVal *p_notBoolean (SemVal *); /* ! code */ SemVal *p_or (SemVal *, SemVal *); /* | (binary) code */ SemVal *p_break (void); /* break stmnt */ SemVal *p_callFunction(int funIdx, SemVal *); /* call a function */ SemVal *p_cast (ExprType, SemVal *); /* perform p_cast */ SemVal *p_catCode (SemVal *, SemVal *); /* write info rval behind lval */ SemVal *cat_expr (SemVal *, SemVal *); /* ,-separated expressions */ SemVal *p_catStmnts (SemVal *, SemVal *); /* catenate/write stmnts */ SemVal *p_continue (void); /* process continue stmnt */ SemVal *p_divide (SemVal *, SemVal *); /* / code */ SemVal *p_equal (SemVal *, SemVal *); /* == code */ SemVal *p_fprintf (ExprType, SemVal *); /* exec() and fprintf() */ SemVal *p_execute (SemVal *); /* execute() (full arglist) */ SemVal *p_expression (SemVal *); /* expr ; code */ SemVal *p_fetchVar (void); /* fetch variable */ SemVal *p_firstArg (SemVal *); /* (arg code */ SemVal *p_firstStmnt (SemVal *); /* catenate/write stmnts */ SemVal *p_for (SemVal *, SemVal *, /* for statement */ SemVal *, SemVal *); SemVal *p_greater (SemVal *, SemVal *); /* > code */ SemVal *p_grEqual (SemVal *, SemVal *); /* >= code */ SemVal *p_if(SemVal *, SemVal *, /* if code */ SemVal *); SemVal *p_incDec (PREPOST_, Opcode, /* E.g., c++ */ SemVal *); SemVal *p_indexOp (SemVal *, SemVal *); /* [] operator */ SemVal *p_makeList (SemVal *, ExprType); /* p_makeList() */ SemVal *p_compoundAss (SemVal *, SemVal *, /* shell for math-asgnmt */ SemVal *(*)(SemVal *, SemVal *), char *); SemVal *p_modulo (SemVal *, SemVal *); /* % code */ SemVal *p_multipleArgs (SemVal *, SemVal *); /* (arg1, arg2, ... code */ SemVal *p_multiply (SemVal *, SemVal *); /* * code */ SemVal *p_negate (SemVal *); /* - (unary) code */ SemVal *p_not (SemVal *); /* ! code */ SemVal *p_old (SemVal *, SemVal *); /* older code */ SemVal *p_oneArg (ExprType, SemVal *); /* fun(x) code */ SemVal *p_optIntSpecial (ExprType, /* fun([int,] ...) */ SemVal *, SemVal *); SemVal *p_optIntString (ExprType, /* chdir(), system() */ SemVal *, SemVal *); SemVal *p_orBool (SemVal *, SemVal *);/* || code */ SemVal *p_return(ExprType, SemVal *);/* exit(), return(); */ SemVal *p_specials (ExprType, SemVal *); /* fun(x, y, ...) code */ SemVal *p_shl (SemVal *, SemVal *); /* << (binary) code */ SemVal *p_shr (SemVal *, SemVal *); /* >> (binary) code */ SemVal *p_smaller (SemVal *, SemVal *); /* < code */ SemVal *p_smEqual (SemVal *, SemVal *); /* <= code */ SemVal *p_stackFrame (ExprType); /* initialize a stack-element */ SemVal *p_subtract (SemVal *, SemVal *); /* - (binary) code */ SemVal *p_ternary(SemVal *cond, SemVal *iftrue, SemVal *iffalse); SemVal *p_threeArgs (ExprType, SemVal *, /* fun(x, y, z) code */ SemVal *, SemVal *); SemVal *p_twoArgs (ExprType, SemVal *, /* fun(x, y) code */ SemVal *); SemVal *p_unequal (SemVal *, SemVal *); /* != code */ SemVal *p_while (SemVal *, SemVal *, int pureWhile);/* while code */ SemVal *p_young (SemVal *, SemVal *); /* younger code */ SemVal *p_xor (SemVal *, SemVal *); /* ^ (binary) code */ SemVal *p_zeroArgs (ExprType); /* fun() code */ void p_endFunction (SemVal *); /* close a function def. */ void p_makeFrame (void); /* generate op_frame */ void p_popDead(void); /* restore dead-level */ void p_pushDead(void); /* new dead-level */ SemVal *p_assignment(SemVal *lval, SemVal *rval, char *opstr); SemVal *p_execute(SemVal *arr); SemVal *p_iCast(SemVal *e); SemVal *p_insertArg(SemVal *insert, SemVal *mult); SemVal *p_lCast(SemVal *e); SemVal *p_nullFrame3(SemVal *e1, SemVal *e2, SemVal *e3); /* e3 may be NULL, discards all e*s, returns pointer to p_stackFrame(e_null). */ SemVal *p_sCast(SemVal *e); int p_conflict(SemVal *lval, SemVal *rval, Opcode opcode); int p_testBinOp(Opcode opcode, SemVal *lval, SemVal *rval); /* 0 return means no errors */ int p_testOperand(SemVal *e, Opcode opcode); /* 0 ret. means no error */ int yyerror(char *s); unsigned p_findString(char *s); unsigned p_rmJmpZero(register unsigned codelen, unsigned *list, register unsigned listlen); void p_addPatch(unsigned *list, unsigned len, register unsigned value); void p_bool2int(SemVal *e); void p_callHidden(register int fun, SemVal *rarg); void p_callRss(SemVal *e, FunNr funnr, ...); void p_catArgs(SemVal *arr); void p_catStrings(SemVal *lval, SemVal *rval); //FBB void p_clearOperands(SemVal **lval, SemVal *rval); /* *lval: zeroFrame */ void p_popVar(SemVal *e); void p_binOp(SemVal *lval, SemVal *rval, Opcode opcode); void p_defineVar(void); /* parameter or local var */ void p_discard(SemVal *e); void p_expr2bool(SemVal *e); void p_expr2stack(SemVal *e); void p_forceExpr2Bool(SemVal *e); void p_generateCode(SemVal *e, Opcode opcode, ...); void p_lastStmnt(SemVal *lval); void p_beginFunction(void); void p_outCode(SemVal *ep, int value, register unsigned size); void p_patchContinue(SemVal *e); void p_patchFalse(SemVal *e); void p_patchTrue(SemVal *e); /* 'pos' == 0 means: jump back to the begin of the code, otherwise jump forward to the end of the code */ void p_patchup(int8_t *code, unsigned len, unsigned *list, unsigned listlen, int pos); void p_patchupContinue(SemVal *e, int pos); void p_patchupFalse(SemVal *e, int pos); void p_patchupTrue(SemVal *e, int pos); int p_functionIdx(void); void p_checkArgumentTypes(unsigned nParams, unsigned funIdx, SemVal *a); void p_hiddenFunctions(void); int p_nextCall(void); void p_listlen(void); int p_trySIconvert(SemVal *lval, SemVal *rval); /* convert single char const. string (rval) to int if lval is an int */ inline SemVal *p_nullFrame(SemVal *e1, SemVal *e2) { return p_nullFrame3(e1, e2, NULL); } icmake-9.02.06/comp/parser/semval.ih0000644000175000017500000000105313176557635016171 0ustar frankfranktypedef struct /* see also display code in */ { /* p_callFunction.c */ ExprType type; /* type of the expression */ unsigned truelen; unsigned falselen; unsigned continuelen; unsigned codelen; /* length of the code */ int evalue; /* index or value of the expression */ unsigned *truelist; unsigned *falselist; unsigned *continuelist; int8_t *code; } SemVal; #define YYSTYPE SemVal icmake-9.02.06/comp/parser/pscast.c0000644000175000017500000000141613176557635016024 0ustar frankfrank#include "parser.ih" SemVal *p_sCast(SemVal *e) { char buffer[10]; if (test_type(e, e_list)) /* (string)list not ok */ { util_semantic(gp_illegalCast); p_discard(e); set_type(e, e_str | e_const); } else if (test_type(e, e_int)) /* (string)int ok */ { if (test_type(e, e_const)) { sprintf(buffer, "%u", (unsigned)e->evalue); /* convert to string */ e->evalue = p_findString(buffer); set_type(e, e_const | e_str); } else { p_expr2stack(e); /* convert to code */ p_generateCode(e, op_itoa); set_type(e, e_stack | e_str); } } return e; } icmake-9.02.06/comp/parser/ppatchfalse.c0000644000175000017500000000064513176557635017024 0ustar frankfrank#include "parser.ih" void p_patchFalse(SemVal *e) { e->falselist = rss_realloc(e->falselist, /* expand the falselist */ (e->falselen + 1) * sizeof(unsigned)); /* room for the jump-backpatch */ e->code = rss_realloc(e->code, e->codelen += sizeof(int16_t)); e->falselist[e->falselen++] = e->codelen; /* store jumpstart location */ } icmake-9.02.06/comp/parser/pinsertarg.c0000644000175000017500000000130213176557635016677 0ustar frankfrank#include "parser.ih" SemVal *p_insertArg(SemVal *insert, SemVal *mult) { register unsigned count; count = ++mult->type; /* get/increase # of args */ /* room for extra SemVal */ mult->code = rss_realloc(mult->code, count * sizeof(SemVal)); memmove( /* shift up for new p_firstArg */ codestruc(mult, 1), codestruc(mult, 0), (count - 1) * sizeof(SemVal)); p_expr2stack(insert); /* argument is code now */ *codestruc(mult, 0) = *insert; /* insert expression in array */ return mult; /* done */ } icmake-9.02.06/comp/parser/pequal.c0000644000175000017500000000166313176557635016022 0ustar frankfrank#include "parser.ih" SemVal *p_equal(SemVal *lval, SemVal *rval) { p_bool2int(lval); /* convert boolean to i */ p_bool2int(rval); if (p_conflict(lval, rval, op_eq)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) { if (test_type(lval, e_int)) lval->evalue = (lval->evalue == rval->evalue); else { lval->evalue = ! ( strcmp ( gp_stringTable[lval->evalue].string, gp_stringTable[rval->evalue].string ) ); set_type(lval, e_int | e_const); } } else p_binOp(lval, rval, op_eq); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/ppopvar.c0000644000175000017500000000023013176557635016207 0ustar frankfrank#include "parser.ih" void p_popVar(SemVal *e) { e->code[e->codelen - sizeof(int16_t) - sizeof(int8_t)] = op_pop_var; gp_lastOp = op_pop_var; } icmake-9.02.06/comp/parser/tokens.h0000644000175000017500000000666313176557635016050 0ustar frankfrank/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ #ifndef YY_YY_TOKENS_H_INCLUDED # define YY_YY_TOKENS_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { ARG_HEAD = 258, ARG_TAIL = 259, ASCII = 260, BREAK = 261, CHDIR = 262, CMD_HEAD = 263, CMD_TAIL = 264, CONTINUE = 265, C_BASE = 266, C_EXT = 267, C_PATH = 268, G_BASE = 269, G_EXT = 270, G_DEXT = 271, G_PATH = 272, ELEMENT = 273, ELSE = 274, EVAL = 275, EXEC = 276, EXECUTE = 277, EXISTS = 278, EXIT = 279, FGETS = 280, FIELDS = 281, FOR = 282, FPRINTF = 283, GETENV = 284, GETCH = 285, GETPID = 286, GETS = 287, IDENTIFIER = 288, IF = 289, INT = 290, LIST = 291, LISTFIND = 292, LISTLEN = 293, LISTUNION = 294, MAKELIST = 295, ECHO_TOKEN = 296, NUMBER = 297, PRINTF = 298, PUTENV = 299, RETURN = 300, STAT = 301, STRCHR = 302, STRING = 303, STRINGTYPE = 304, STRLEN = 305, STRLWR = 306, RESIZE = 307, STRUPR = 308, STRFIND = 309, STRFORMAT = 310, SUBSTR = 311, SYSTEM = 312, TRIM = 313, TRIMLEFT = 314, TRIMRIGHT = 315, VOID = 316, WHILE = 317, AND_IS = 318, OR_IS = 319, XOR_IS = 320, SHL_IS = 321, SHR_IS = 322, DIV_IS = 323, MINUS_IS = 324, MUL_IS = 325, MOD_IS = 326, PLUS_IS = 327, OR = 328, AND = 329, EQUAL = 330, NOT_EQUAL = 331, SMALLER_EQUAL = 332, GREATER_EQUAL = 333, OLDER = 334, YOUNGER = 335, SHL = 336, SHR = 337, INC = 338, DEC = 339 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_TOKENS_H_INCLUDED */ icmake-9.02.06/comp/parser/ppopdead.c0000644000175000017500000000036713176557635016327 0ustar frankfrank#include "parser.ih" void p_popDead() /* dead_sp: lastused, dead[0] = 0 */ { if (gp_dead_sp) /* anything to pop ? */ --gp_dead_sp; /* then reduce SP */ } icmake-9.02.06/comp/parser/porboolean.c0000644000175000017500000000143413176557635016667 0ustar frankfrank#include "parser.ih" SemVal *p_orBool(SemVal *lexp, SemVal *rexp) { if (lexp->type & rexp->type & e_const) /* two constants: compute result */ { lexp->evalue = (test_type(lexp, e_str) || lexp->evalue) || (test_type(rexp, e_str) || rexp->evalue); set_type(lexp, e_const | e_int); } else /* at least one code-part */ { p_forceExpr2Bool(lexp); /* boolean code */ p_forceExpr2Bool(rexp); lexp->codelen -= p_rmJmpZero(lexp->codelen, lexp->falselist, lexp->falselen); p_patchupFalse(lexp, 1); lexp = p_catCode(lexp, rexp); set_type(lexp, e_bool | e_stack); } return (lexp); } icmake-9.02.06/comp/parser/pfindstring.c0000644000175000017500000000160013176557635017051 0ustar frankfrank/* Lookup (and maybe enter) a string */ #include "parser.ih" static unsigned n_allocated; unsigned p_findString(char *s) { register unsigned idx; for (idx = 0; idx < gp_nStrings; idx++) if (!strcmp(gp_stringTable[idx].string, s)) /* string found ? */ return (idx); /* return string idx */ if (n_allocated == gp_nStrings) /* full table */ gp_stringTable = rss_realloc(gp_stringTable, (n_allocated += 20) * sizeof(StringTable)); /* set the string in memory */ gp_stringTable[gp_nStrings].string = rss_strdup(s); gp_stringTable[gp_nStrings].index = gp_stringsize; gp_stringsize += strlen(s) + 1; gp_nStrings++; /* next free */ return idx; /* return string idx */ } icmake-9.02.06/comp/parser/preturn.c0000644000175000017500000000252713176557635016232 0ustar frankfrank#define msgx #include "parser.ih" SemVal *p_return(ExprType op, SemVal *e) { msg("BEGIN 0x%x", e->type); if (test_type(e, e_bool) || !test_type(e, e_stack)) p_expr2stack(e); msg("NEXT 0x%x", e->type); unsigned funIdx = symtab_lastFunction(); if ((Opcode)op == op_ret) /* return opcode received */ { ExprType funType = symtab_funType(funIdx); msg("Got op_ret, function type %s is 0x%x", symtab_funName(funIdx), \ funType); /* void if the union of the type of the function and the type of the expression is not a std type */ if ((e_typeMask & (funType | e->type)) == 0) { msg("void function, generate 'ret' opcode"); p_generateCode(e, op); /* generate the 'ret' opcode */ msg("END"); return e; /* done */ } if (!(test_type(e, funType & e_typeMask))) util_semantic("Incorrect returntype for function '%s()'", symtab_funName(funIdx)); } msg("popping the pushed return value and returning"); p_generateCode(e, op_pop_reg); p_generateCode(e, op); return e; } icmake-9.02.06/comp/parser/psmaller.c0000644000175000017500000000165613176557635016354 0ustar frankfrank#include "parser.ih" SemVal *p_smaller(SemVal *lval, SemVal *rval) { p_bool2int(lval); /* convert boolean to i */ p_bool2int(rval); if (p_conflict(lval, rval, op_sm)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) { if (test_type(lval, e_int)) lval->evalue = (lval->evalue < rval->evalue); else { lval->evalue = ( strcmp ( gp_stringTable[lval->evalue].string, gp_stringTable[rval->evalue].string ) ) < 0; set_type(lval, e_int | e_const); } } else p_binOp(lval, rval, op_sm); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/ppatchupfalse.c0000644000175000017500000000023313176557635017362 0ustar frankfrank#include "parser.ih" void p_patchupFalse(SemVal *e, int pos) { p_patchup(e->code, e->codelen, e->falselist, e->falselen, pos); e->falselen = 0; } icmake-9.02.06/comp/parser/ptestbinop.c0000644000175000017500000000043313176557635016714 0ustar frankfrank#include "parser.ih" int p_testBinOp(Opcode opcode, SemVal *lval, SemVal *rval) { if (! p_trySIconvert(lval, rval)) p_trySIconvert(rval, lval); return p_testOperand(lval, opcode) /* returns 0 if no errors */ || p_testOperand(rval, opcode); } icmake-9.02.06/comp/parser/pdiscard.c0000644000175000017500000000027413176557635016321 0ustar frankfrank#include "parser.ih" void p_discard(SemVal *e) { if (e->falselen) free(e->falselist); if (e->truelen) free(e->truelist); if (e->code) free(e->code); } icmake-9.02.06/comp/parser/pmakeframe.c0000644000175000017500000000134013176557635016633 0ustar frankfrank/* p_makeFrame writes the op_frame instruction, defining the number and types of all local variables, to gp_bin. p_makeFrame is called by p_endFunction, which writes the statements of the functions to gp_bin after calling p_makeFrame. */ /*#define msg */ #include "parser.ih" void p_makeFrame() { if (symtab_nLocals()) { SemVal e = *p_stackFrame(0); /* initialize empty frame */ p_pushDead(); gp_dead[gp_dead_sp] = 0; p_generateCode(&e, op_frame); /* generate frame instruction */ p_popDead(); util_out(gp_bin, e.code, e.codelen); /* write to gp_bin */ msg("write code frame of %u bytes", e.codelen); free(e.code); } } icmake-9.02.06/comp/parser/pbeginfunction.c0000644000175000017500000000113413176557635017536 0ustar frankfrank #define msgx #include "parser.ih" void p_beginFunction() { /* test if function name already exists */ if (symtab_addFunction(gp_varType, ftell(gp_bin)) != 0) { util_semantic("%s p_multiply defined", util_string()); return; } symtab_push(); /* setup the local symbol table */ /* 1 global, 1 local symbol table */ gp_dead_sp = 0; /* allow code generation */ gp_dead[0] = 0; ++gp_nestLevel; /* no code-writes to gp_bin in functions */ msg("END"); } icmake-9.02.06/comp/parser/pfetchvar.c0000644000175000017500000000260613176557635016513 0ustar frankfrank/* Frame organization: Low address Local x <- Var 0xbffc = 0xbfff - x Local ... <- Var 0xbffd = 0xbfff - ... Local 1 <- Var 0xbffe = 0xbfff - 1 Local 0 <- Var 0xbfff = 0xbfff - 0 Old BP <- Var 0xc000 RA <- Var 0xc001 parameters: Par 0 <- Var 0xc002 = 0xc002 + 0 Par 1 <- Var 0xc003 = 0xc002 + 1 ... High Address */ #include "parser.ih" static SemVal ret; SemVal *p_fetchVar() { register int idx; ret = *p_stackFrame(e_null); VarIndex vi = symtab_findVar(); /* find the index of var. util_string() */ if ((idx = vi.idx) == -1) { util_semantic("%s undefined", util_string()); return &ret; } if (vi.type != st_global) { register unsigned nParams = symtab_nParams(); if (idx < nParams) idx += 0xc002; /* offset of a parameter */ else idx = 0xbfff - (idx - nParams); /* offset of a local var */ } ret.evalue = idx; ret.type = symtab_varType(vi); return &ret; /* return the frame */ } icmake-9.02.06/comp/parser/pband.c0000644000175000017500000000115613176557635015614 0ustar frankfrank#include "parser.ih" SemVal *p_and(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_band, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_band)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) lval->evalue &= rval->evalue; else p_binOp(lval, rval, op_band); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/backend.c0000644000175000017500000000465113176557635016122 0ustar frankfrank#include "parser.ih" /* version offset of the string constant-area (int32_t) offset of the variable area (int32_t) offset of the strings area (int32_t) offset of the first instruction (int32_t) code (first byte is first instruction) ascii-z string constant area variables filenames */ static int8_t opexit[] = {op_push_0, op_pop_reg, op_exit}; static int8_t opcall = op_call; int parser_backend() { unsigned nErrors = rss_nErrors(); if (nErrors) /* backend if no errors */ { printf("\n%u error(s) detected\n", nErrors); return 1; } register int idx; BinHeader hdr; util_setString("main"); idx = symtab_findFun(); if (idx == -1) { util_semantic("function 'main()' not defined"); exit(1); } hdr.offset[3] = ftell(gp_bin); /* offset of first instruction */ p_hiddenFunctions(); /* p_patchup generated hidden */ /* function calls */ fseek(gp_bin, 0, SEEK_END); /* upwind to EOF again */ /* write global vars initializ. */ /* code */ util_out(gp_bin, gp_init.code, gp_init.codelen); util_out(gp_bin, &opcall, sizeof(int8_t)); /* call opcode for main */ uint16_t addr = symtab_funAddress(idx); /* get main's address */ util_out(gp_bin, &addr, sizeof(uint16_t)); /* write it out */ util_out(gp_bin, &opexit, sizeof(opexit)); strncpy(hdr.version, version, sizeof(hdr.version)); /* set the version */ hdr.offset[0] = ftell(gp_bin); /* here the strings start */ /* generate the strings */ for (idx = 0; idx < gp_nStrings; idx++) fprintf(gp_bin, "%s%c", gp_stringTable[idx].string, 0); hdr.offset[1] = ftell(gp_bin); /* here the vars start */ symtab_writeGlobals(gp_bin); /* write the global variables */ hdr.offset[2] = ftell(gp_bin); /* here the filenames start */ fputs(scanner_filenames(), gp_bin); rewind(gp_bin); /* write the offset info */ util_out(gp_bin, &hdr, sizeof(BinHeader)); return 0; } icmake-9.02.06/comp/parser/pnotboolean.c0000644000175000017500000000106213176557635017044 0ustar frankfrank#include "parser.ih" SemVal *p_notBoolean(SemVal *e) { unsigned len; unsigned *list; if (test_type(e, e_const)) /* immediate value */ { e->evalue = !(test_type(e, e_str) || e->evalue); set_type(e, e_int | e_const); } else { p_forceExpr2Bool(e); len = e->truelen; /* cross the links */ e->truelen = e->falselen; e->falselen = len; list = e->truelist; e->truelist = e->falselist; e->falselist = list; } return (e); } icmake-9.02.06/comp/parser/ptrysiconvert.c0000644000175000017500000000136513176557635017465 0ustar frankfrank#define msgx #include "parser.ih" int p_trySIconvert(SemVal *lval, SemVal *rval) { msg("intypes: 0x%x, 0x%x", lval->type, rval->type); if /* assigning a string of 1 char to an int is OK: */ ( /* the int gets the ascii value of its character */ test_type(lval, e_int) && test_type(rval, e_str | e_const) == (e_str | e_const) && strlen(gp_stringTable[rval->evalue].string) == 1 ) { set_type(rval, e_int | e_const); /* change the str to int */ rval->evalue = gp_stringTable[rval->evalue].string[0]; /* value is */ /* str's 1st character */ return 1; } return 0; } icmake-9.02.06/comp/parser/pcast.c0000644000175000017500000000131113176557635015633 0ustar frankfrank/* C A S T . C */ #include "parser.ih" SemVal *p_cast(ExprType target, SemVal *e) { p_bool2int(e); /* convert boolean to int */ switch (target) { case e_int: /* p_cast to ints */ p_iCast(e); break; case e_str: /* p_cast to strings */ p_sCast(e); break; case e_list: /* p_cast to lists */ p_lCast(e); break; default: /* default is entered in the switch to prevent a long compiler warning */ break; } return e; } icmake-9.02.06/comp/parser/pcatcode.c0000644000175000017500000000361713176557635016316 0ustar frankfrank#include "parser.ih" static void patchadd(register unsigned value, unsigned **dest, unsigned *dlen, unsigned *source, unsigned slen) { register unsigned idx; if (!*dlen) *dest = NULL; /* no memory for dest as yet */ for (idx = 0; idx < slen; idx++) /* all elements of source list: */ source[idx] += value; /* icrement addresses of targets */ /* expand the dest area */ *dest = rss_realloc(*dest, (*dlen + slen) * sizeof(unsigned)); /* append source list */ memcpy(*dest + *dlen, source, slen * sizeof(unsigned)); *dlen += slen; /* increment # element */ } SemVal *p_catCode(SemVal *lval, SemVal *rval) { register unsigned l; register unsigned r; r = rval->codelen; /* sizeof rval code */ l = lval->codelen; /* sizeof lval code */ lval->code = rss_realloc(lval->code, /* room for new code */ (l + r) * sizeof(int8_t)); /* catenate the code */ memcpy(lval->code + l, rval->code, r * sizeof(int8_t)); lval->codelen += r; /* new size */ patchadd(l, &lval->truelist, &lval->truelen, rval->truelist, rval->truelen); patchadd(l, &lval->falselist, &lval->falselen, rval->falselist, rval->falselen); patchadd(l, &lval->continuelist, &lval->continuelen, rval->continuelist, rval->continuelen); lval->type |= rval->type; /* type of combined code */ /* (is ok with same types) */ p_discard(rval); /* free memory used by SemVal */ return (lval); /* return new frame */ } icmake-9.02.06/comp/parser/pfprintf.c0000644000175000017500000000170313176557635016356 0ustar frankfrank#include "parser.ih" SemVal *p_fprintf(ExprType type, SemVal *args) { register int ok; SemVal *e0; if (args->type < 2) /* argcount must be at least 2 */ { util_semantic(gp_illegalArgCount, gp_funstring[type]); return (args); } e0 = codestruc(args, 0); /* pointer to first arg */ switch ((FunNr)type) { case f_fprintf: /* first arg must be string */ ok = test_type(e0, e_str); break; default: /* 1st arg must be int, */ ok = test_type(e0, e_int) && /* 2nd arg must be string */ test_type(codestruc(args, 1), e_str); } if (ok) return (p_specials(type, args)); /* return p_specials call */ /* type p_conflict error */ util_semantic(gp_typeConflict, gp_funstring[type]); return args; } icmake-9.02.06/comp/parser/grammar0000644000175000017500000004576113176557635015747 0ustar frankfrank%{ /* #define msg */ #include "parser.ih" %} %token ARG_HEAD ARG_TAIL ASCII BREAK CHDIR CMD_HEAD CMD_TAIL CONTINUE C_BASE C_EXT C_PATH G_BASE G_EXT G_DEXT G_PATH ELEMENT ELSE EVAL EXEC EXECUTE EXISTS EXIT FGETS FIELDS FOR FPRINTF GETENV GETCH GETPID GETS IDENTIFIER IF INT LIST LISTFIND LISTLEN LISTUNION MAKELIST ECHO_TOKEN NUMBER PRINTF PUTENV RETURN STAT STRCHR STRING STRINGTYPE STRLEN STRLWR RESIZE STRUPR STRFIND STRFORMAT SUBSTR SYSTEM TRIM TRIMLEFT TRIMRIGHT VOID WHILE %right '=' AND_IS /* binary-p_assignment */ OR_IS XOR_IS SHL_IS SHR_IS DIV_IS /* arithmetic p_assignment */ MINUS_IS MUL_IS MOD_IS PLUS_IS %right '?' ':' %left OR %left AND %left '|' %left '^' %left '&' %left EQUAL NOT_EQUAL %left '<' '>' SMALLER_EQUAL GREATER_EQUAL OLDER YOUNGER %left SHL SHR %left '+' '-' %left '*' '/' '%' %right '!' INC DEC '~' %left '[' %expect 1 /* Grammar Rules */ %% input: input def_var_or_fun | def_var_or_fun ; args: args comma err_expression { $$ = *p_multipleArgs(&$1, &$3); } | err_expression { $$ = *p_firstArg(&$1); } ; break_ok: { gp_breakOK++; } ; break_stat: BREAK { $$ = *p_break(); } ; closebrace: { gp_parse_error = err_closebrace_expected; symtab_pop(); } /* '{' for matching */ '}' ; closepar: { gp_parse_error = err_closepar_expected; } ')' ; comma: { gp_parse_error = err_comma_expected; } ',' ; compound: openbrace statements closebrace { $$ = $2; } ; condition: err_expression | typed_condition ; continue_stat: CONTINUE { $$ = *p_continue(); } ; _voidtype: VOID { gp_varType = 0; } ; def_var_or_fun: typed_varlist semicol { gp_init = *p_catCode(&gp_init, &$1); } | type_of_var funcdef | _voidtype funcdef ; enterid: IDENTIFIER { p_defineVar(); /* the first n variables of a function, up to the end of the parameter list are the parameters. */ } ; enter_varid: enterid { $$ = *p_fetchVar(); } ; err_expression: { gp_parse_error = err_in_expression; } expression { $$ = $2; } ; expr_code: err_expression { $$ = *p_expression(&$1); } ; _p_casttype: INT | LIST | STRINGTYPE ; _string: _string STRING { /* catenate the new string */ gp_stringbuf = rss_strcat(gp_stringbuf, util_string()); } | STRING { free(gp_stringbuf); /* free former string */ gp_stringbuf = rss_strdup(util_string()); /* duplicate initial string */ } ; _func_or_var: function closepar | IDENTIFIER { $$ = *p_fetchVar(); } ; _backtick: { gp_parse_error = err_backtick_expected; } '`' ; expression: expression '=' expression { $$ = *p_assign(&$1, &$3); } | expression '[' expression ']' { $$ = *p_indexOp(&$1, &$3); } | expression MUL_IS expression { $$ = *p_compoundAss(&$1, &$3, p_multiply, "*="); } | expression DIV_IS expression { $$ = *p_compoundAss(&$1, &$3, p_divide, "/="); } | expression MOD_IS expression { $$ = *p_compoundAss(&$1, &$3, p_modulo, "%="); } | expression PLUS_IS expression { $$ = *p_compoundAss(&$1, &$3, p_addition, "+="); } | expression MINUS_IS expression { $$ = *p_compoundAss(&$1, &$3, p_subtract, "-="); } | expression AND_IS expression { $$ = *p_compoundAss(&$1, &$3, p_and, "&="); } | expression OR_IS expression { $$ = *p_compoundAss(&$1, &$3, p_or, "|="); } | expression XOR_IS expression { $$ = *p_compoundAss(&$1, &$3, p_xor, "^="); } | expression SHL_IS expression { $$ = *p_compoundAss(&$1, &$3, p_shl, "<<="); } | expression SHR_IS expression { $$ = *p_compoundAss(&$1, &$3, p_shr, ">>="); } | expression OR expression { $$ = *p_orBool(&$1, &$3); } | expression AND expression { $$ = *p_andBoolean(&$1, &$3); } | expression EQUAL expression { $$ = *p_equal(&$1, &$3); } | expression NOT_EQUAL expression { $$ = *p_unequal(&$1, &$3); } | expression '?' expression ':' expression { $$ = *p_ternary(&$1, &$3, &$5); } | expression '<' expression { $$ = *p_smaller(&$1, &$3); } | expression '>' expression { $$ = *p_greater(&$1, &$3); } | expression SMALLER_EQUAL expression { $$ = *p_smEqual(&$1, &$3); } | expression GREATER_EQUAL expression { $$ = *p_grEqual(&$1, &$3); } | expression '+' expression { $$ = *p_addition(&$1, &$3); } | expression '&' expression { $$ = *p_and(&$1, &$3); } | expression '|' expression { $$ = *p_or(&$1, &$3); } | expression '^' expression { $$ = *p_xor(&$1, &$3); } | expression SHL expression { $$ = *p_shl(&$1, &$3); } | expression SHR expression { $$ = *p_shr(&$1, &$3); } | expression '-' expression { $$ = *p_subtract(&$1, &$3); } | expression '*' expression { $$ = *p_multiply(&$1, &$3); } | expression YOUNGER expression { $$ = *p_young(&$1, &$3); } | expression OLDER expression { $$ = *p_old(&$1, &$3); } | expression '/' expression { $$ = *p_divide(&$1, &$3); } | expression '%' expression { $$ = *p_modulo(&$1, &$3); } | '-' expression %prec '!' { $$ = *p_negate(&$2); } | INC expression { $$ = *p_incDec(pre_op, op_inc, &$2); } | expression INC { $$ = *p_incDec(post_op, op_inc, &$1); } | DEC expression { $$ = *p_incDec(pre_op, op_dec, &$2); } | expression DEC { $$ = *p_incDec(post_op, op_dec, &$1); } | '+' expression %prec '!' { $$ = $2; } | '~' expression %prec '!' { $$ = *p_not(&$2); } | '!' expression { $$ = *p_notBoolean(&$2); } | '(' _p_casttype ')' expression %prec '!' { $$ = *p_cast($2.type, &$4); } | _string { $$ = *p_stackFrame(e_str | e_const); } | NUMBER { $$ = *p_stackFrame(e_int | e_const); } | '(' expression closepar { $$ = $2; } | _func_or_var | '`' expression _backtick { $$ = *p_oneArg(f_backtick, &$2); } ; _for: FOR nesting { symtab_push(); } ; _expr_list: _expr_list ',' expr_code { $$ = *p_catCode(&$1, &$3); } | expr_code ; _opt_init_expression: _expr_list | typed_varlist | zeroframe ; _opt_cond_expression: err_expression | { $$ = *p_stackFrame(e_int | e_const); $$.evalue = 1; } ; _opt_inc_expression: _expr_list | zeroframe ; for_stat: _for openpar _opt_init_expression /* $3: init */ semicol _opt_cond_expression /* $5: cond */ semicol _opt_inc_expression /* $7 inc */ closepar break_ok statement /* $10 stmnt */ popdead { $$ = *p_for(&$3, &$5, &$7, &$10); } ; /* parameters are defined as local variables of the current function, while counting the number of parameters. At the end of a function definition head its symtab nParams fields holds the number of its parameters, which are represented by the initial nParams elements of symtab's local variables array. */ _partype: type_of_var enterid ; _pars: _pars comma _partype | _partype ; _opt_parlist: _pars | /* empty */ ; _funvars: openpar _opt_parlist ')' openbrace { symtab_setFunParams(); /* the # variables so far are the parameters */ } ; _funid: IDENTIFIER { p_beginFunction(); } ; funcdef: _funid /* name of the function */ _funvars /* returns init code */ statements closebrace { p_endFunction(&$3); } ; _zero_arg_funs: GETCH | GETPID | GETS ; _one_arg_funs: ASCII | EVAL | EXISTS | LISTLEN | ECHO_TOKEN | CMD_TAIL | CMD_HEAD | ARG_HEAD | ARG_TAIL | G_BASE | G_PATH | G_EXT | G_DEXT | PUTENV | GETENV | STRLEN | STRUPR | STRLWR | TRIM | TRIMLEFT | TRIMRIGHT ; _two_arg_funs: C_EXT /* string, string */ | C_BASE | C_PATH | ELEMENT /* int, list | int, string */ | FGETS /* list fgets(string, int) */ | FIELDS /* string, string */ | LISTFIND /* list, string */ | LISTUNION /* list, list | list, string */ | STRCHR /* string, string */ | STRFIND /* string, string */ | RESIZE /* string, int */ ; _optint_string: STAT | CHDIR | SYSTEM ; _comma_expr: ',' err_expression { $$ = $2; } | zeroframe ; _optint_special: EXEC /* optional int allowed */ | EXECUTE ; _comma_arglist: ',' args { $$ = $2; } | zeroframe ; _opt_arglist: args | zeroframe ; _funname: IDENTIFIER { $$.evalue = p_functionIdx(); } ; function: _zero_arg_funs /* getch() or gets() */ openpar { $$ = *p_zeroArgs($1.type); } | _one_arg_funs openpar err_expression { $$ = *p_oneArg($1.type, &$3); } | _two_arg_funs openpar err_expression comma err_expression { $$ = *p_twoArgs($1.type, &$3, &$5); } | SUBSTR /* three arg function */ openpar err_expression comma err_expression comma err_expression { $$ = *p_threeArgs($1.type, &$3, &$5, &$7); } | _optint_string /* CHDIR, SYSTEM, STAT */ openpar err_expression /* int inserted if string */ _comma_expr /* may be string if first == int */ { $$ = *p_optIntString($1.type, &$3, &$4); } | _optint_special /* EXEC, EXECUTE */ openpar /* alternatives: */ err_expression /* fun(int, string, ...) */ _comma_arglist /* fun(string, ...) */ { $$ = *p_optIntSpecial($1.type, &$3, &$4); } | PRINTF openpar args /* first may be anything */ { $$ = *p_specials(f_printf, &$3); } | FPRINTF openpar args /* argcount >= 2 required */ { $$ = *p_fprintf($1.type, &$3); } | STRFORMAT openpar args /* first may be anything */ { $$ = *p_specials(f_strformat, &$3); } | _funname openpar _opt_arglist { $$ = *p_callFunction($1.evalue, &$3); } | p_makeList ; _if: IF nesting { symtab_push(); } ; _else: ELSE statement { $$ = $2; } | zeroframe ; if_stat: _if openpar condition closepar statement popdead pushdead _else popdead { $$ = *p_if(&$3, &$5, &$8); symtab_pop(); } ; _p_makeList_expr: MAKELIST openpar err_expression { $$ = $3; } ; _p_makeList_normal: { $$ = *p_stackFrame(e_int | e_const); $$.evalue = IS_FILE; } ; _old_young: OLDER | YOUNGER ; _older_younger: { gp_parse_error = err_older_younger; } _old_young { $$ = $2; } ; p_makeList: _p_makeList_expr /* p_makeList(expr) */ _p_makeList_normal /* returns IS_FILE expression */ { $$ = *p_makeList ( p_multipleArgs ( p_firstArg(&$2), /* IS_FILE is passed */ &$1 /* expression is passed */ ), op_hlt /* not op_younger or op_older */ ); } | /* p_makeList(expr, expr) */ _p_makeList_expr comma err_expression { $$ = *p_makeList ( p_multipleArgs ( p_firstArg(&$1), /* fileattribute is passed */ &$3 /* expression is passed */ ), op_hlt /* not op_younger or op_older */ ); } | _p_makeList_expr /* p_makeList(expr, older, expr) */ comma _older_younger comma err_expression _p_makeList_normal { $$ = *p_makeList ( p_multipleArgs ( p_multipleArgs ( p_firstArg(&$6), /* IS_FILE is passed */ &$1 /* 1st expression is passed */ ), &$5 /* 2nd expression is passed */ ), $3.type /* older/younger */ ); } | _p_makeList_expr /* p_makeList(expr, expr, older, expr) */ comma err_expression comma _older_younger comma err_expression { $$ = *p_makeList ( p_multipleArgs ( p_multipleArgs ( p_firstArg(&$1), /* attribute is passed */ &$3 /* 2nd expression is passed */ ), &$7 /* 3rd expression is passed */ ), $5.type /* older/younger */ ); } ; nesting: pushdead { gp_nestLevel++; } ; ok: ';' { yyerrok; } ; openbrace: { gp_parse_error = err_openbrace_expected; } '{' /* } (for matching) */ { symtab_push(); } ; openpar: { gp_parse_error = err_openpar_expected; } '(' ; popdead: { p_popDead(); } ; pushdead: { p_pushDead(); /* set new dead-level */ } ; _return_tail: err_expression | zeroframe ; _leave: RETURN { msg("saw return"); } | EXIT ; return_stat: _leave _return_tail { $$ = *p_return($1.type, &$2); msg("SAW return stmt"); } ; semicol: { gp_parse_error = err_semicol_expected; } ';' ; _stm: compound | ';' zeroframe { $$ = $2; } | expr_code semicol | while_stat | if_stat | for_stat | return_stat semicol | break_stat semicol | continue_stat semicol | error ok ; statement: _stm | typed_varlist semicol ; statements: statements statement { $$ = *p_catStmnts(&$1, &$2); } | zeroframe ; typed_condition: type_of_var var_condition { $$ = $2; } ; typed_varlist: type_of_var var_expr_list { $$ = $2; } ; _varType: INT | STRINGTYPE | LIST ; type_of_var: _varType { gp_parse_error = err_identifier_expected; gp_varType = $1.type; } ; var_condition: enter_varid { p_generateCode(&$1, op_push_imm, 0); $$ = $1; } | enter_varid '=' expression { $$ = *p_assign(&$1, &$3); /* explicit initialization */ } ; var_expr: enterid zeroframe /* no explicit initialization */ | enter_varid '=' expression { $$ = *p_expression(p_assign(&$1, &$3)); /* explicit initialization */ } ; var_expr_list: var_expr_list comma var_expr { $$ = *p_catCode(&$1, &$3); /* catenate variable */ /* initialization code */ } | var_expr | error ok zeroframe /* Empty stmnt */ { $$ = $3; } ; _while: WHILE nesting ; while_stat: _while openpar condition closepar break_ok statement popdead { $$ = *p_while(&$3, &$6, 1); } ; zeroframe: { $$ = *p_stackFrame(0); /* by default initializes a variable to 0 */ } ; %% int yywrap(void) { return 1; } icmake-9.02.06/comp/parser/pwhilestm.c0000644000175000017500000000251513176557635016544 0ustar frankfrank#include "parser.ih" SemVal *p_while(SemVal *expr, SemVal *stmnt, int pureWhile) { register unsigned len; unsigned *list; gp_nestLevel--; /* reduce nesting level */ gp_breakOK--; /* reduce break ok */ p_expr2bool(expr); /* make links for EXPR */ if (test_type(expr, e_const)) /* constant: never xeq */ { if (expr->evalue == 0) /* value 0? ignore the while */ return p_nullFrame(expr, stmnt); expr->evalue = 0; /* no value means no code for */ /* p_catCode */ } p_patchupTrue(expr, 1); /* patch to EOC */ list = expr->falselist; len = expr->falselen; expr->falselen = 0; /* no more false links avail. */ p_catCode(expr, stmnt); /* append stmnt to expr */ if (pureWhile) /* not a while stmd that's part */ p_patchupContinue(expr, -expr->codelen); /* of a for stmnt */ p_generateCode(expr, op_jmp, j_falselist); /* jmp to begin of code */ p_patchupFalse(expr, 0); /* patch to BOC */ expr->falselist = list; expr->falselen = len; p_patchupTrue(expr, 1); /* p_patchup break targets to EOC */ return expr; } icmake-9.02.06/comp/parser/pgeneratecode.c0000644000175000017500000000767013176557635017344 0ustar frankfrank /* #define msg */ #include "parser.ih" void p_generateCode(SemVal *e, Opcode opcode, ...) { msg("BEGIN"); register unsigned idx; int marker_value; va_list marker; if (gp_dead[gp_dead_sp]) { msg("DEAD"); return; } msg("WITHIN: codelen = %u", e->codelen); va_start(marker, opcode); gp_lastOp = opcode; /* remember last opcode */ p_outCode(e, (int)opcode, sizeof(char)); msg("OUTCODE, opcode = 0x%x", opcode); switch (opcode) { case op_jmp: /* write target to jump to */ switch ((JMP_COND_)va_arg(marker, JMP_COND_)) { case j_uncond: /* absolute jumplocation */ p_outCode(e, va_arg(marker, int), sizeof(int16_t)); break; case j_truelist: p_patchTrue(e); /* new truelist item */ break; case j_falselist: p_patchFalse(e); /* new falselist item */ break; case j_continuelist: p_patchContinue(e); /* new continuelist item */ break; } break; case op_jmp_false: /* write target to jump if false */ p_patchFalse(e); break; case op_jmp_true: /* write target to jump if true */ p_patchTrue(e); break; case op_push_strconst: /* write idx of the const */ p_outCode(e, (int)gp_stringTable[va_arg(marker, int)].index, sizeof(int16_t)); break; case op_frame: { unsigned nLocalVars = symtab_nLocals(); p_outCode(e, (int)nLocalVars, sizeof(char)); for (idx = 0; idx != nLocalVars; ++idx) { ExprType type = symtab_localType(idx); p_outCode(e, type, sizeof(char)); } } break; case op_copy_var: /* write # of the var. */ case op_push_var: /* write # of the var. */ case op_dec: /* write # of the var. */ case op_inc: /* write # of the var. */ /* write backpatch info and fall through ? */ // FALLING THRU case op_push_imm: /* write value of the int */ case op_call: /* write offset of function */ p_outCode(e, va_arg(marker, int), sizeof(int16_t)); break; case op_asp: /* write # of args to remove */ marker_value = va_arg(marker, int); if (!marker_value) /* nothing to add to sp */ e->codelen--; /* opcode removed from code */ else p_outCode(e, marker_value, sizeof(char)); break; case op_call_rss: /* write # of function */ p_outCode(e, va_arg(marker, int), sizeof(char)); break; case op_ret: case op_exit: ++gp_dead[gp_dead_sp]; break; default: /* The default switch entry is inserted to prvent a long compiler warning about a not-handled enum value following opcodes already out: op_pop_reg op_push_reg op_push_1_jmp_end op_push_0 op_umin op_atoi op_itoa op_atol op_mul op_div op_mod op_add op_sub op_eq op_neq op_sm op_gr op_younger op_older op_smeq op_greq */ break; } msg("END"); } icmake-9.02.06/comp/parser/pgrequal.c0000644000175000017500000000166213176557635016352 0ustar frankfrank#include "parser.ih" SemVal *p_grEqual(SemVal *lval, SemVal *rval) { p_bool2int(lval); /* convert boolean to i */ p_bool2int(rval); if (p_conflict(lval, rval, op_greq)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) { if (test_type(lval, e_int)) lval->evalue = (lval->evalue >= rval->evalue); else { lval->evalue = ( strcmp ( gp_stringTable[lval->evalue].string, gp_stringTable[rval->evalue].string ) ) >= 0; set_type(lval, e_int | e_const); } } else p_binOp(lval, rval, op_greq); return (lval); /* return new expression */ } icmake-9.02.06/comp/parser/parser.c0000644000175000017500000000137113176557635016023 0ustar frankfrank#include "parser.ih" void parser(char **argv) { symtab(); scanner(argv[1]); if (!(gp_bin = fopen(argv[2], "w+b"))) /* open binary file */ rss_fatal(0, 0, "%s Can't write `%s'", argv[2]); /* malloc the gp_dead-stack */ gp_dead = rss_realloc(NULL, sizeof(unsigned)); gp_dead[0] = 0; /* and initialize its element */ gp_stringbuf = rss_strdup(""); /* malloc initial gp_stringbuf */ util_setString(""); /* initial util_string() */ /* go to first codebyte pos */ fseek(gp_bin, sizeof(BinHeader), SEEK_SET); /* #if YYDEBUG yydebug = YYDEBUG; #endif */ } icmake-9.02.06/comp/parser/ppatchuptrue.c0000644000175000017500000000022713176557635017252 0ustar frankfrank#include "parser.ih" void p_patchupTrue(SemVal *e, int pos) { p_patchup(e->code, e->codelen, e->truelist, e->truelen, pos); e->truelen = 0; } icmake-9.02.06/comp/parser/passignment.c0000644000175000017500000000204013176557635017051 0ustar frankfrank#include "parser.ih" /* opstr is '=', or "/=", etc. */ SemVal *p_assignment(SemVal *lval, SemVal *rval, char *opstr) { SemVal *tmp; unsigned type; unsigned value; if (!test_type(lval, e_var)) { util_semantic(gp_lvalueNeeded, opstr); p_discard(rval); return lval; } p_trySIconvert(lval, rval); p_expr2stack(rval); /* convert rval to code */ /* same types */ if (lval->type & rval->type & (e_int | e_str | e_list)) { type = lval->type; /* save type/idx for return */ value = lval->evalue; p_generateCode(lval, op_copy_var, lval->evalue); tmp = p_catCode(rval, lval); /* catenate p_assignment code */ tmp->evalue = value; /* set lvalue type and idx */ tmp->type = type; return tmp; } util_semantic(gp_typeConflict, opstr); p_discard(rval); return lval; } icmake-9.02.06/comp/parser/picast.c0000644000175000017500000000145113176557635016011 0ustar frankfrank#include "parser.ih" SemVal *p_iCast(SemVal *e) { if (test_type(e, e_list)) /* (int)list not ok */ { util_semantic(gp_illegalCast); p_discard(e); set_type(e, e_int | e_const); } else if (test_type(e, e_str)) /* (int)string ok */ { if (test_type(e, e_const)) /* string const to a */ { e->evalue = /* convert to string */ atoi(gp_stringTable[e->evalue].string); set_type(e, e_const | e_int); } else { p_expr2stack(e); /* convert to code */ p_generateCode(e, op_atoi); /* runtime conversion needed */ set_type(e, e_int | e_stack); } } return e; } icmake-9.02.06/comp/parser/data.c0000644000175000017500000001462313176557635015444 0ustar frankfrank#include "parser.ih" int gp_parse_error = err_code_or_vars_expected; unsigned gp_breakOK; unsigned gp_nestLevel; unsigned gp_stringsize; unsigned gp_hidden_called; HiddenFunction gp_hiddenFun[he_]; char *gp_funstring[] = /* only one_arg */ { /* 0 */ "arghead", "argtail", "ascii", "ascii", /* 4 */ "backtick-operator", "change_base", "change_ext", "change_path", /* 8 */ "chdir", "cmdhead", "cmdtail", "echo", /* c */ "element", "eval", "exec", "execute", /* 10 */ "exists", "fgets", "fprintf", "get_base", /* 14 */ "get_dext", "get_ext", "get_path", "getch", /* 18 */ "getenv", "getpid", "gets", "listlen", /* 1c */ "makelist", "printf", "putenv", "stat", /* 20 */ "element", /* f_str_el */ "strfind", "strfmt", "strlen", /* 24 */ "strlwr", "resize", "strtok", "strupr", /* 28 */ "substr", "system", "trim", "trimleft", /* 2c */ "trimright", "strchr", "listfind", "listunion" /* 30 */ }; ExprType gp_opType[] = { 0, /* op_jmp, */ 0, /* op_jmp_false, */ 0, /* op_jmp_true, */ 0, /* op_push_1_jmp_end, */ 0, /* op_push_0, */ 0, /* op_push_imm, */ 0, /* op_push_strconst, */ 0, /* op_push_var, */ 0, /* op_push_reg, */ 0, /* op_pop_var, */ e_int | e_list | e_bool, /* op_umin, */ e_str, /* op_atoi, */ e_int | e_bool, /* op_itoa, */ e_str, /* op_atol, */ e_int | e_bool, /* op_mul, */ e_int | e_bool, /* op_div, */ e_int | e_bool, /* op_mod, */ e_typeMask, /* op_add, */ e_typeMask, /* op_sub, */ e_typeMask, /* op_eq, */ e_typeMask, /* op_neq, */ e_int | e_bool | e_str, /* op_sm, */ e_int | e_bool | e_str, /* op_gr, */ e_str, /* op_younger, */ e_str, /* op_older, */ e_int | e_bool | e_str, /* op_smeq, */ e_int | e_bool | e_str, /* op_greq, */ 0, /* op_call */ 0, /* op_asp */ 0, /* op_ret */ 0, /* op_copy_var */ e_int, /* op_inc */ e_int, /* op_dec */ 0, /* op_call */ 0, /* op_frame */ 0, /* op_ret */ 0, /* op_pop_ */ e_int, /* op_band */ e_int, /* op_bor */ e_int, /* op_bnot */ e_int, /* op_xor */ e_int, /* op_shl */ e_int, /* op_shr */ }; char *gp_opstring[] = { NULL, /* op_jmp, */ NULL, /* op_jmp_false, */ NULL, /* op_jmp_true, */ NULL, /* op_push_1_jmp_end, */ NULL, /* op_push_0, */ NULL, /* op_push_imm, */ NULL, /* op_push_strconst, */ NULL, /* op_push_var, */ NULL, /* op_push_reg, */ NULL, /* op_pop_var, */ "(unary) -", /* op_umin, */ "(int)", /* op_atoi, */ "(string)", /* op_itoa, */ "(list)", /* op_atol, */ "*", /* op_mul, */ "/", /* op_div, */ "%%", /* op_mod, */ "+", /* op_add, */ "-", /* op_sub, */ "==", /* op_eq, */ "!=", /* op_neq, */ "<", /* op_sm, */ ">", /* op_gr, */ "younger", /* op_younger, */ "older", /* op_older, */ "<=", /* op_smeq, */ ">=", /* op_greq, */ NULL, /* op_call */ NULL, /* op_asp */ NULL, /* op_ret */ NULL, /* op_copy_var */ "++", /* op_inc */ "--", /* op_dec */ NULL, /* op_call */ NULL, /* op_frame */ NULL, /* op_ret */ NULL, /* op_pop_ */ "&", /* op_band */ "|", /* op_bor */ "~", /* op_bnot */ "^", /* op_xor */ "<<", /* op_shl */ ">>", /* op_shr */ }; char gp_typeConflict[] = "conflicting operand types for %s"; char gp_illegalType[] = "illegal type for %s"; char gp_lvalueNeeded[] = "lvalue needed for %s"; char gp_illegalArgCount[] = "%s(): too few arguments"; char gp_illegalCast[] = "illegal p_cast"; ExprType gp_varType; Opcode gp_lastOp = op_hlt; unsigned gp_dead_sp; unsigned *gp_dead; FILE *gp_bin; unsigned gp_nStrings; StringTable *gp_stringTable; SemVal gp_init; /* code initializing globals */ char *gp_stringbuf; char *gp_listlen; icmake-9.02.06/comp/parser/psubtract.c0000644000175000017500000000146713176557635016544 0ustar frankfrank#include "parser.ih" SemVal *p_subtract(SemVal *lval, SemVal *rval) { register ExprType type; if (p_testBinOp(op_sub, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_sub)) /* test type p_conflict */ return p_nullFrame(lval, rval); /* test for correct types */ type = lval->type; /* remember the type */ if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) lval->evalue -= rval->evalue; else { p_binOp(lval, rval, op_sub); set_type(lval, type & (e_typeMask | e_stack)); } return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pcontinue.c0000644000175000017500000000064313176557635016534 0ustar frankfrank#include "parser.ih" static SemVal e; SemVal *p_continue() { e = *p_stackFrame(0); if (!gp_breakOK) util_semantic("'continue' only in 'while' or 'for' statements"); else { p_generateCode(&e, op_jmp, j_continuelist);/* jump to the continue dest */ e.type = e_bool | e_stack; ++gp_dead[gp_dead_sp]; /* next code is gp_dead */ } return &e; } icmake-9.02.06/comp/parser/pfunctionidx.c0000644000175000017500000000030313176557635017233 0ustar frankfrank#include "parser.ih" int p_functionIdx() { register int idx = symtab_findFun(); if (idx == -1) util_semantic("Function '%s' not defined", util_string()); return idx; } icmake-9.02.06/comp/parser/pconflict.c0000644000175000017500000000037013176557635016506 0ustar frankfrank#include "parser.ih" int p_conflict(SemVal *lval, SemVal *rval, Opcode opcode) { register int ret = !(lval->type & rval->type & gp_opType[opcode]); if (ret) util_semantic(gp_typeConflict, gp_opstring[opcode]); return ret; } icmake-9.02.06/comp/parser/punequal.c0000644000175000017500000000164113176557635016361 0ustar frankfrank#include "parser.ih" SemVal *p_unequal(SemVal *lval, SemVal *rval) { p_bool2int(lval); /* convert boolean to i */ p_bool2int(rval); if (p_conflict(lval, rval, op_neq)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) { if (test_type(lval, e_int)) lval->evalue = (lval->evalue != rval->evalue); else { lval->evalue = strcmp ( gp_stringTable[lval->evalue].string, gp_stringTable[rval->evalue].string ) != 0; set_type(lval, e_int | e_const); } } else p_binOp(lval, rval, op_neq); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pcatstrings.c0000644000175000017500000000126513176557635017072 0ustar frankfrank#include "parser.ih" void p_catStrings(SemVal *lval, SemVal *rval) { char *cp; register unsigned l_len, r_len; l_len = strlen( gp_stringTable[ lval->evalue ].string ); r_len = strlen( gp_stringTable[ rval->evalue ].string ); cp = rss_realloc(NULL, l_len + r_len + 1); /* room for catenated string */ lval->evalue = p_findString ( strcat /* catenate two strings */ ( strcpy(cp, gp_stringTable[lval->evalue].string), gp_stringTable[rval->evalue].string ) ); free(cp); /* free intermediate memory */ } icmake-9.02.06/comp/parser/pshl.c0000644000175000017500000000116113176557635015472 0ustar frankfrank#include "parser.ih" SemVal *p_shl(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_shl, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_shl)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) lval->evalue <<= rval->evalue; else p_binOp(lval, rval, op_shl); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pcheckargumenttypes.c0000644000175000017500000000070113176557635020610 0ustar frankfrank#define msgx #include "parser.ih" void p_checkArgumentTypes(unsigned nParams, unsigned funIdx, SemVal *args) { register unsigned idx; msg("checking %d parameters", nParams); for (idx = 0; idx != nParams; ++idx, ++args) { if (symtab_funParameterType(funIdx, idx) != (args->type & e_typeMask)) util_semantic("Function `%s', argument %u: type mismatch", symtab_funName(funIdx), idx + 1); } } icmake-9.02.06/comp/parser/pstackframe.c0000644000175000017500000000062513176557635017030 0ustar frankfrank#include "parser.ih" static SemVal frame; SemVal *p_stackFrame(ExprType type) { frame.type = type; switch ((int)type) { case e_int | e_const: frame.evalue = atoi(util_string()); break; case e_str | e_const: frame.evalue = p_findString(gp_stringbuf); break; default: frame.evalue = 0; } return &frame; } icmake-9.02.06/comp/parser/pold.c0000644000175000017500000000060213176557635015461 0ustar frankfrank#include "parser.ih" SemVal *p_old(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_older, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_expr2stack(lval); /* convert to code */ p_expr2stack(rval); p_binOp(lval, rval, op_older); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pdivide.c0000644000175000017500000000155213176557635016154 0ustar frankfrank#include "parser.ih" SemVal *p_divide(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_div, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_div)) /* test type p_conflict */ return p_nullFrame(lval, rval); if (test_type(rval, e_const)) { if (!rval->evalue) /* expression / 0: not allowed */ { util_semantic("division by 0: undefined"); return p_nullFrame(lval, rval); } if (test_type(lval, e_const)) { lval->evalue /= rval->evalue; return lval; } } p_binOp(lval, rval, op_div); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/pthreeargs.c0000644000175000017500000000157113176557635016675 0ustar frankfrank#include "parser.ih" SemVal *p_threeArgs(ExprType type, SemVal *larg, SemVal *marg, SemVal *rarg) { register int ok; p_expr2stack(larg); /* arg to stack */ p_expr2stack(marg); /* arg to stack */ p_expr2stack(rarg); /* arg to stack */ switch ((FunNr)type) { case f_substr: ok = test_type(larg, e_str) && test_type(marg, e_int) && test_type(rarg, e_int); break; default: ok = 0; } if (ok) { p_catCode(rarg, marg); /* make one code vector */ p_catCode(rarg, larg); /* make one code vector */ p_callRss(rarg, type); return rarg; } util_semantic(gp_typeConflict, gp_funstring[type]); return p_nullFrame3(larg, marg, rarg); } icmake-9.02.06/comp/parser/paddpatch.c0000644000175000017500000000027513176557635016461 0ustar frankfrank#include "parser.ih" void p_addPatch(unsigned *list, unsigned len, register unsigned value) { register unsigned idx; for (idx = 0; idx < len; idx++) list[idx] += value; } icmake-9.02.06/comp/parser/ptwoargs.c0000644000175000017500000000365613176557635016405 0ustar frankfrank#define msgx #include "parser.ih" SemVal *p_twoArgs(ExprType type, SemVal *larg, SemVal *rarg) { register int ok; msg("start"); p_expr2stack(larg); /* arg to stack */ p_expr2stack(rarg); /* arg to stack */ switch ((FunNr)type) { case f_fgets: ok = test_type(larg, e_str) && test_type(rarg, e_list); break; case f_element: /* f_element */ /* first arg must be int */ if ( (ok = test_type(larg, e_int)) ) { /* second arg == list: ok */ if (!(ok = test_type(rarg, e_list))) { /* second arg == string: ok */ ok = test_type(rarg, e_str); type = f_str_el; /* string element requested */ } } break; case f_resize: ok = test_type(larg, e_str) && test_type(rarg, e_int); break; case f_listfind: ok = test_type(larg, e_list) && test_type(rarg, e_str); break; case f_listunion: ok = test_type(larg, e_list) && test_type(rarg, e_str | e_list); break; default: /* case f_strchr: case f_strtok: case f_c_ext: case f_c_base: case f_c_path: case f_strfind: */ ok = larg->type & rarg->type & e_str; } msg("types test %d, funstring: %x", ok, type); if (ok) { p_catCode(rarg, larg); /* make one code vector */ p_callRss(rarg, type); } else { util_semantic(gp_typeConflict, gp_funstring[type]); p_discard(larg); rarg = p_stackFrame(e_null); } msg("leaving"); return rarg; } icmake-9.02.06/comp/parser/paddition.c0000644000175000017500000000167613176557635016512 0ustar frankfrank#include "parser.ih" SemVal *p_addition(SemVal *lval, SemVal *rval) { register ExprType type; if (p_testBinOp(op_add, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_add)) /* test type p_conflict */ return p_nullFrame(lval, rval); type = lval->type; /* keep type for later */ if ((type & rval->type & (unsigned)~e_typeMask) == e_const) { if (test_type(lval, e_int)) lval->evalue += rval->evalue; else if (test_type(lval, e_str)) p_catStrings(lval, rval); /* create (cat) new string */ } else { p_binOp(lval, rval, op_add); set_type(lval, (type & e_typeMask) | e_stack); } return lval; /* return new expression */ } icmake-9.02.06/comp/parser/poutcode.c0000644000175000017500000000244713176557635016356 0ustar frankfrank /* #define msg */ #include "parser.ih" void p_outCode(SemVal *ep, int value, register unsigned size) { register unsigned codelen; union { char buffer[2]; int16_t int16; } u; codelen = ep->code ? /* use local codelen in register */ ep->codelen : 0; /* 0 if not yet any code */ msg(" begin"); if (size == sizeof(char)) /* p_assign char to write */ u.buffer[0] = (char)value; else /* use char[2] as intermediate */ u.int16 = (int16_t)value; /* to store int16_t value */ msg(" in between. ep is %p, code at %p, new codelen: %u", \ ep, ep->code, codelen + size); /* make room for new code */ ep->code = rss_realloc(ep->code, (codelen + size) * sizeof(char)); msg("reallocated"); msg("size = %u, buffer[0] = %x, [1] = %x", size, \ u.buffer[0], u.buffer[1]); /* append the new code */ memcpy(ep->code + codelen, u.buffer, size); ep->codelen = codelen + size; /* update the codelen-counter */ msg(" end"); } icmake-9.02.06/comp/parser/pfor.c0000644000175000017500000000062613176557635015477 0ustar frankfrank#include "parser.ih" SemVal *p_for(SemVal *init, SemVal *cond, SemVal *inc, SemVal *stmnt) { unsigned codelen = stmnt->codelen; p_patchupContinue(stmnt, codelen); p_catStmnts(stmnt, inc); /* catenate inc to stmt */ p_while(cond, stmnt, 0); /* create while-stmnt */ symtab_pop(); return p_catCode(init, cond); /* return final code */ } icmake-9.02.06/comp/parser/pcallfun.c0000644000175000017500000000254213176557635016334 0ustar frankfrank#define msgx #include "parser.ih" SemVal *p_callFunction(int funIdx, SemVal *e) { msg("calling function 0x%x", funIdx); register unsigned nParams; /* fprintf(stderr, "type: %d\n" "truelen: %d\n" "falselen: %d\n" "codelen: %d\n" "evalue: %d\n" "truelist: %p\n" "falselist: %p\n" "code: %p\n", e->type, e->truelen, e->falselen, e->codelen, e->evalue, e->truelist, e->falselist, e->code); */ if (funIdx == -1) /* function name not found ? */ return e; /* nothing to do here */ nParams = symtab_fun_nParams(funIdx); /* then check correct # of args */ if ((unsigned)e->type == nParams) p_checkArgumentTypes(nParams, funIdx, (SemVal *)e->code); else util_semantic("Function '%s()' requires %u arguments", symtab_funName(funIdx), nParams); p_catArgs(e); /* convert args to code */ /* call function and clean stack */ p_generateCode(e, op_call, symtab_funAddress(funIdx)); p_generateCode(e, op_asp, nParams); set_type(e, symtab_funType(funIdx)); return e; /* return called function code */ } icmake-9.02.06/comp/parser/pspecials.c0000644000175000017500000000105013176557635016504 0ustar frankfrank#include "parser.ih" SemVal *p_specials(ExprType type, SemVal *marg) /* array of arguments */ { register unsigned count; if ((FunNr)type == f_execute) return(p_execute(marg)); /* full list of arguments */ count = marg->type; /* count # of arguments */ p_catArgs(marg); /* catenate multiple args */ p_generateCode(marg, op_push_imm, count); /* # of arguments of fun */ p_callRss(marg, type, count + 1); /* call function */ return (marg); } icmake-9.02.06/comp/parser/ppatchup.c0000644000175000017500000000272513176557635016357 0ustar frankfrank#include "parser.ih" void p_patchup(int8_t *code, unsigned len, unsigned *list, unsigned listlen, int pos) { /* list, listlen: list of */ register unsigned idx; /* offsets to p_patchup */ register unsigned beyond_jump; char *cp; /* codepointer */ union { char jumpsize[2]; int16_t int16; } u; if (!listlen) /* done if nothing to p_patchup */ return; if (pos) pos = len; /* walk all elements to p_patchup */ for (idx = 0; idx < listlen; idx++) { beyond_jump = list[idx]; /* beyond-jump is the offset immediately beyond the jump to the end of the code. This is the position where the jump starts after having read the jump instruction. Hence, the jumpsize is determined by the distance 'pos - beyond-jump', whereas this jumpsize must be inserted 2 bytes earlier than beyond_jump, as part of the jump instruction. */ u.int16 = pos - beyond_jump; /* determine the size of the jmp */ cp = (char *)code + beyond_jump - 2;/* point to codebytes to patch */ *cp = u.jumpsize[0]; /* copy byte 0 */ *(cp + 1) = u.jumpsize[1]; /* copy byte 1 */ } free(list); } icmake-9.02.06/comp/parser/pexpr2stack.c0000644000175000017500000000275713176557635017006 0ustar frankfrank#define msgx /* Push an expression value on the stack */ #include "parser.ih" void p_expr2stack(SemVal *e) { SemVal pre; switch ( test_type ( e, e_const | e_var | e_bool | e_reg | e_pre_inc_dec | e_post_inc_dec ) ) { case e_const: p_generateCode(e, test_type(e, e_int) ? op_push_imm : op_push_strconst, e->evalue); break; case e_var: if (!e->codelen) p_generateCode(e, op_push_var, e->evalue); break; case e_bool: p_patchupTrue(e, 1); p_generateCode(e, op_push_1_jmp_end); p_patchupFalse(e, 1); p_generateCode(e, op_push_0); set_type(e, e_int); break; case e_reg: p_generateCode(e, op_push_reg); break; case e_post_inc_dec: pre = *p_stackFrame(0); p_generateCode(&pre, op_push_var, e->evalue); *e = *p_catCode(&pre, e); /* prefix push before var++, var-- */ break; case e_pre_inc_dec: /* append push after ++var, --var */ p_generateCode(e, op_push_var, e->evalue); break; } down_type(e, e_const | e_var | e_bool | e_reg | e_pre_inc_dec | e_post_inc_dec); up_type(e, e_stack); } icmake-9.02.06/comp/parser/pmultiply.c0000644000175000017500000000116613176557635016570 0ustar frankfrank#include "parser.ih" SemVal *p_multiply(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_mul, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_mul)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) lval->evalue *= rval->evalue; else p_binOp(lval, rval, op_mul); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/ppatchtrue.c0000644000175000017500000000065213176557635016707 0ustar frankfrank#include "parser.ih" void p_patchTrue(SemVal *e) { /* expand the truelist */ e->truelist = rss_realloc(e->truelist, (e->truelen + 1) * sizeof(unsigned)); /* room for the jump-backpatch */ e->code = rss_realloc(e->code, e->codelen += sizeof(int16_t)); e->truelist[e->truelen++] = e->codelen; /* store jumpstart location */ } icmake-9.02.06/comp/parser/pexecute.c0000644000175000017500000000442413176557635016353 0ustar frankfrank#include "parser.ih" /* process: execute(mode, cmd, chead, ahead, ..., atail, ctail) argnr: 1 2 3 4 count - 1, count argidx: 0 1 2 3 4 count - 2, count - 1 ... count-3 at least required: 6 arguments */ SemVal *p_execute(SemVal *arr) { register unsigned count; SemVal tmp, *argp, /* pointer to args */ e; count = arr->type; /* get argument count */ if (count < 6) /* to few arguments */ { util_semantic(gp_illegalArgCount, "execute"); return (arr); /* dummy args return */ } argp = codestruc(arr, 0); /* point to first arg */ e = *(argp + 2); /* cmd head info at e */ p_callRss(&e, f_cmd_head); /* code for cmd_head at e */ p_callRss(argp + 3, f_arg_head); /* code for arg_head */ p_catCode(&e, argp + 3); /* code appended to e*/ p_callRss(&argp[count - 2], f_arg_tail); /* code for arg_tail */ p_catCode(&e, &argp[count - 2]); /* code appended to e*/ p_callRss(&argp[count - 1], f_cmd_tail); /* code for cmd_tail */ p_catCode(&e, &argp[count - 1]); /* code appended to e*/ /* keep variable # of args */ memmove(argp + 2, argp + 4, (count - 2) * sizeof(SemVal)); arr->type -= 4; /* remove 4 arguments */ p_catCode(&e, p_specials(f_exec, arr)); /* catenate call-code */ free(gp_stringbuf); /* make sure empty string */ gp_stringbuf = rss_strdup(""); /* is pushed */ tmp = *p_stackFrame(e_str | e_const); /* empty string argument */ p_expr2stack(&tmp); p_catCode(&e, &tmp); /* empty string on the stack */ p_generateCode(&e, op_call_rss, f_cmd_tail); /* used with cmd_tail..cmd_head */ p_generateCode(&e, op_call_rss, f_arg_tail); p_generateCode(&e, op_call_rss, f_arg_head); p_callRss(&e, f_cmd_head); *arr = e; return arr; } icmake-9.02.06/comp/parser/pindexop.c0000644000175000017500000000246713176557635016364 0ustar frankfrank#include "parser.ih" SemVal *p_indexOp(SemVal *larg, SemVal *rarg) { register int ok; ExprType type = f_element; SemVal *tmp; p_expr2stack(larg); /* arg to stack */ p_expr2stack(rarg); /* arg to stack */ /* This follows the code of `p_twoArgs.c' to compute a list/string */ /* element */ /* first arg must be int */ if (!test_type(larg, e_int)) /* first expression is no int */ { tmp = larg; /* then swap */ larg = rarg; rarg = tmp; } if ( (ok = test_type(larg, e_int)) ) /* right arg must be int */ { /* second arg == list: ok */ if (!(ok = test_type(rarg, e_list))) { /* second arg == string: ok */ ok = test_type(rarg, e_str); type = f_str_el; /* string element requested */ } } if (ok) { p_catCode(rarg, larg); /* make one code vector */ p_callRss(rarg, type); } else { util_semantic(gp_typeConflict, gp_funstring[type]); p_discard(larg); } return (rarg); } icmake-9.02.06/comp/parser/pnegate.c0000644000175000017500000000104413176557635016147 0ustar frankfrank#include "parser.ih" SemVal *p_negate(SemVal *e) /* expression so far */ { if (p_testOperand(e, op_umin)) /* test types ok */ { util_semantic(gp_illegalType, gp_opstring[op_umin]); return (e); } if (e->type & e_const) /* immediate value */ e->evalue = -(int)e->evalue; else { p_expr2stack(e); /* convert to code */ p_generateCode(e, op_umin); /* generate instruction */ } return (e); } icmake-9.02.06/comp/parser/frame0000644000175000017500000000004313176557635015373 0ustar frankfrank#include "parser.ih" void ps_ { } icmake-9.02.06/comp/parser/pbnot.c0000644000175000017500000000112513176557635015646 0ustar frankfrank/* B N O T . C */ #include "parser.ih" SemVal *p_not(SemVal *e) /* expression so far */ { if (p_testOperand(e, op_bnot)) /* test types ok */ { util_semantic(gp_illegalType, gp_opstring[op_bnot]); return e; } if ((e->type & (unsigned)~e_typeMask) == e_const) /* immediate value */ e->evalue = ~e->evalue; else { p_expr2stack(e); /* convert to code */ p_generateCode(e, op_bnot); /* generate instruction */ } return e; } icmake-9.02.06/comp/parser/pmodulo.c0000644000175000017500000000152213176557635016204 0ustar frankfrank#include "parser.ih" SemVal *p_modulo(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_mod, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_mod)) /* test type p_conflict */ return p_nullFrame(lval, rval); if (test_type(rval, e_const)) { if (!rval->evalue) /* no "E / 0" */ { util_semantic("p_modulo 0: undefined"); return p_nullFrame(lval, rval); } if (test_type(lval, e_const)) { lval->evalue %= rval->evalue; return lval; } } p_binOp(lval, rval, op_mod); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/poptintspecial.c0000644000175000017500000000115013176557635017560 0ustar frankfrank#include "parser.ih" SemVal *p_optIntSpecial(ExprType type, SemVal *larg, SemVal *rarg) { SemVal tmp; p_expr2stack(larg); /* arg to stack */ if (!test_type(larg, e_int)) /* no first int arg */ { /* prefix the first argument */ rarg = p_insertArg(larg, rarg); /* make 0-argument */ tmp = *p_stackFrame(e_int | e_const); larg = &tmp; /* larg points to inserted arg */ } return p_specials(type, p_insertArg(larg, rarg)); } icmake-9.02.06/comp/parser/plaststmnt.c0000644000175000017500000000036313176557635016740 0ustar frankfrank/*#define msg */ #include "parser.ih" void p_lastStmnt(SemVal *lval) { p_patchupFalse(lval, 1); util_out(gp_bin, lval->code, lval->codelen); msg("write statement code of %u bytes", lval->codelen); p_discard(lval); } icmake-9.02.06/comp/parser/pclearoperands.c0000644000175000017500000000025113176557635017525 0ustar frankfrank//#include "parser.ih" // //void p_clearOperands(SemVal **lval, SemVal *rval) //{ // p_discard(rval); // p_discard(*lval); // *lval = p_stackFrame(e_null); //} icmake-9.02.06/comp/parser/pdefinevar.c0000644000175000017500000000030413176557635016645 0ustar frankfrank #define msgx #include "parser.ih" void p_defineVar() { VarIndex ret = symtab_defineVar(gp_varType); if (ret.idx == -1) util_semantic("%s p_multiply defined", util_string()); } icmake-9.02.06/comp/parser/pandboolean.c0000644000175000017500000000131313176557635017005 0ustar frankfrank/* A N D B O O L E . C */ #include "parser.ih" SemVal *p_andBoolean(SemVal *lexp, SemVal *rexp) { if (lexp->type & rexp->type & e_const) /* two constants: compute result */ { lexp->evalue = (test_type(lexp, e_str) || lexp->evalue) && (test_type(rexp, e_str) || rexp->evalue); set_type(lexp, e_const | e_int); } else /* at least one code-part */ { p_forceExpr2Bool(lexp); p_forceExpr2Bool(rexp); p_patchupTrue(lexp, 1); lexp->truelen = 0; lexp = p_catCode(lexp, rexp); set_type(lexp, e_bool | e_stack); } return lexp; } icmake-9.02.06/comp/parser/pbor.c0000644000175000017500000000115113176557635015465 0ustar frankfrank#include "parser.ih" SemVal *p_or(SemVal *lval, SemVal *rval) { if (p_testBinOp(op_bor, lval, rval)) return p_nullFrame(lval, rval); /* test for correct types */ p_bool2int(lval); /* convert pending booleans */ p_bool2int(rval); if (p_conflict(lval, rval, op_bor)) /* test type p_conflict */ return p_nullFrame(lval, rval); if ((lval->type & rval->type & (unsigned)~e_typeMask) == e_const) lval->evalue |= rval->evalue; else p_binOp(lval, rval, op_bor); return lval; /* return new expression */ } icmake-9.02.06/comp/parser/ppatchcontinue.c0000644000175000017500000000075013176557635017553 0ustar frankfrank#include "parser.ih" void p_patchContinue(SemVal *e) { e->continuelist = rss_realloc(e->continuelist, /* expand the continuelist */ (e->continuelen + 1) * sizeof(unsigned)); /* room for the jump-backpatch */ e->code = rss_realloc(e->code, e->codelen += sizeof(int16_t)); /* store jumpstart location */ e->continuelist[e->continuelen++] = e->codelen; } icmake-9.02.06/comp/parser/ppushdead.c0000644000175000017500000000054713176557635016510 0ustar frankfrank#include "parser.ih" static unsigned size = 1; void p_pushDead() /* dead_sp: lastused, dead[0] = 0 */ { if (++gp_dead_sp >= size) /* too few elements ? then 5 more */ gp_dead = rss_realloc(gp_dead, (size += 5) * sizeof(unsigned)); gp_dead[gp_dead_sp] = gp_dead[gp_dead_sp - 1]; /* copy former element */ } icmake-9.02.06/comp/parser/pnullframe3.c0000644000175000017500000000031513176557635016754 0ustar frankfrank#include "parser.ih" SemVal *p_nullFrame3(SemVal *e1, SemVal *e2, SemVal *e3) { if (e3) p_discard(e3); p_discard(e2); p_discard(e1); *e1 = *p_stackFrame(e_null); return e1; } icmake-9.02.06/comp/parser/pcatargs.c0000644000175000017500000000114713176557635016334 0ustar frankfrank#include "parser.ih" void p_catArgs(SemVal *arr) { register unsigned count; SemVal *ep; SemVal e; if (!(count = arr->type)) return; /* no arguments */ ep = (SemVal *)arr->code; /* local pointer to SemVals */ e = ep[--count]; /* e: code of last argument */ while (count--) p_catCode(&e, &ep[count]); /* catenate next argument(s) */ free(arr->code); /* memory of array is free again */ *arr = e; /* arguments changed to code */ } icmake-9.02.06/comp/parser/inc/0000755000175000017500000000000013176557635015132 5ustar frankfrankicmake-9.02.06/comp/parser/inc/varexpr.50000644000175000017500000000036013176557635016706 0ustar frankfrankvar_expr: enterid zeroframe /* no explicit initialization */ | enter_varid '=' expression { $$ = *p_expression(p_assign(&$1, &$3)); /* explicit initialization */ } ; icmake-9.02.06/comp/parser/inc/closebrace.50000644000175000017500000000023113176557635017316 0ustar frankfrankclosebrace: { gp_parse_error = err_closebrace_expected; symtab_pop(); } /* '{' for matching */ '}' ; icmake-9.02.06/comp/parser/inc/typeofvar.50000644000175000017500000000030113176557635017231 0ustar frankfrank_varType: INT | STRINGTYPE | LIST ; type_of_var: _varType { gp_parse_error = err_identifier_expected; gp_varType = $1.type; } ; icmake-9.02.06/comp/parser/inc/args.50000644000175000017500000000024213176557635016152 0ustar frankfrankargs: args comma err_expression { $$ = *p_multipleArgs(&$1, &$3); } | err_expression { $$ = *p_firstArg(&$1); } ; icmake-9.02.06/comp/parser/inc/yywrap.60000644000175000017500000000005013176557635016547 0ustar frankfrank %% int yywrap(void) { return 1; } icmake-9.02.06/comp/parser/inc/openpar.50000644000175000017500000000011613176557635016662 0ustar frankfrankopenpar: { gp_parse_error = err_openpar_expected; } '(' ; icmake-9.02.06/comp/parser/inc/pushdead.50000644000175000017500000000013213176557635017011 0ustar frankfrankpushdead: { p_pushDead(); /* set new dead-level */ } ; icmake-9.02.06/comp/parser/inc/function.50000644000175000017500000000612313176557635017047 0ustar frankfrank_zero_arg_funs: GETCH | GETPID | GETS ; _one_arg_funs: ASCII | EVAL | EXISTS | LISTLEN | ECHO_TOKEN | CMD_TAIL | CMD_HEAD | ARG_HEAD | ARG_TAIL | G_BASE | G_PATH | G_EXT | G_DEXT | PUTENV | GETENV | STRLEN | STRUPR | STRLWR | TRIM | TRIMLEFT | TRIMRIGHT ; _two_arg_funs: C_EXT /* string, string */ | C_BASE | C_PATH | ELEMENT /* int, list | int, string */ | FGETS /* list fgets(string, int) */ | FIELDS /* string, string */ | LISTFIND /* list, string */ | LISTUNION /* list, list | list, string */ | STRCHR /* string, string */ | STRFIND /* string, string */ | RESIZE /* string, int */ ; _optint_string: STAT | CHDIR | SYSTEM ; _comma_expr: ',' err_expression { $$ = $2; } | zeroframe ; _optint_special: EXEC /* optional int allowed */ | EXECUTE ; _comma_arglist: ',' args { $$ = $2; } | zeroframe ; _opt_arglist: args | zeroframe ; _funname: IDENTIFIER { $$.evalue = p_functionIdx(); } ; function: _zero_arg_funs /* getch() or gets() */ openpar { $$ = *p_zeroArgs($1.type); } | _one_arg_funs openpar err_expression { $$ = *p_oneArg($1.type, &$3); } | _two_arg_funs openpar err_expression comma err_expression { $$ = *p_twoArgs($1.type, &$3, &$5); } | SUBSTR /* three arg function */ openpar err_expression comma err_expression comma err_expression { $$ = *p_threeArgs($1.type, &$3, &$5, &$7); } | _optint_string /* CHDIR, SYSTEM, STAT */ openpar err_expression /* int inserted if string */ _comma_expr /* may be string if first == int */ { $$ = *p_optIntString($1.type, &$3, &$4); } | _optint_special /* EXEC, EXECUTE */ openpar /* alternatives: */ err_expression /* fun(int, string, ...) */ _comma_arglist /* fun(string, ...) */ { $$ = *p_optIntSpecial($1.type, &$3, &$4); } | PRINTF openpar args /* first may be anything */ { $$ = *p_specials(f_printf, &$3); } | FPRINTF openpar args /* argcount >= 2 required */ { $$ = *p_fprintf($1.type, &$3); } | STRFORMAT openpar args /* first may be anything */ { $$ = *p_specials(f_strformat, &$3); } | _funname openpar _opt_arglist { $$ = *p_callFunction($1.evalue, &$3); } | p_makeList ; icmake-9.02.06/comp/parser/inc/condition.50000644000175000017500000000006613176557635017210 0ustar frankfrankcondition: err_expression | typed_condition ; icmake-9.02.06/comp/parser/inc/expression.50000644000175000017500000001370013176557635017420 0ustar frankfrank_p_casttype: INT | LIST | STRINGTYPE ; _string: _string STRING { /* catenate the new string */ gp_stringbuf = rss_strcat(gp_stringbuf, util_string()); } | STRING { free(gp_stringbuf); /* free former string */ gp_stringbuf = rss_strdup(util_string()); /* duplicate initial string */ } ; _func_or_var: function closepar | IDENTIFIER { $$ = *p_fetchVar(); } ; _backtick: { gp_parse_error = err_backtick_expected; } '`' ; expression: expression '=' expression { $$ = *p_assign(&$1, &$3); } | expression '[' expression ']' { $$ = *p_indexOp(&$1, &$3); } | expression MUL_IS expression { $$ = *p_compoundAss(&$1, &$3, p_multiply, "*="); } | expression DIV_IS expression { $$ = *p_compoundAss(&$1, &$3, p_divide, "/="); } | expression MOD_IS expression { $$ = *p_compoundAss(&$1, &$3, p_modulo, "%="); } | expression PLUS_IS expression { $$ = *p_compoundAss(&$1, &$3, p_addition, "+="); } | expression MINUS_IS expression { $$ = *p_compoundAss(&$1, &$3, p_subtract, "-="); } | expression AND_IS expression { $$ = *p_compoundAss(&$1, &$3, p_and, "&="); } | expression OR_IS expression { $$ = *p_compoundAss(&$1, &$3, p_or, "|="); } | expression XOR_IS expression { $$ = *p_compoundAss(&$1, &$3, p_xor, "^="); } | expression SHL_IS expression { $$ = *p_compoundAss(&$1, &$3, p_shl, "<<="); } | expression SHR_IS expression { $$ = *p_compoundAss(&$1, &$3, p_shr, ">>="); } | expression OR expression { $$ = *p_orBool(&$1, &$3); } | expression AND expression { $$ = *p_andBoolean(&$1, &$3); } | expression EQUAL expression { $$ = *p_equal(&$1, &$3); } | expression NOT_EQUAL expression { $$ = *p_unequal(&$1, &$3); } | expression '?' expression ':' expression { $$ = *p_ternary(&$1, &$3, &$5); } | expression '<' expression { $$ = *p_smaller(&$1, &$3); } | expression '>' expression { $$ = *p_greater(&$1, &$3); } | expression SMALLER_EQUAL expression { $$ = *p_smEqual(&$1, &$3); } | expression GREATER_EQUAL expression { $$ = *p_grEqual(&$1, &$3); } | expression '+' expression { $$ = *p_addition(&$1, &$3); } | expression '&' expression { $$ = *p_and(&$1, &$3); } | expression '|' expression { $$ = *p_or(&$1, &$3); } | expression '^' expression { $$ = *p_xor(&$1, &$3); } | expression SHL expression { $$ = *p_shl(&$1, &$3); } | expression SHR expression { $$ = *p_shr(&$1, &$3); } | expression '-' expression { $$ = *p_subtract(&$1, &$3); } | expression '*' expression { $$ = *p_multiply(&$1, &$3); } | expression YOUNGER expression { $$ = *p_young(&$1, &$3); } | expression OLDER expression { $$ = *p_old(&$1, &$3); } | expression '/' expression { $$ = *p_divide(&$1, &$3); } | expression '%' expression { $$ = *p_modulo(&$1, &$3); } | '-' expression %prec '!' { $$ = *p_negate(&$2); } | INC expression { $$ = *p_incDec(pre_op, op_inc, &$2); } | expression INC { $$ = *p_incDec(post_op, op_inc, &$1); } | DEC expression { $$ = *p_incDec(pre_op, op_dec, &$2); } | expression DEC { $$ = *p_incDec(post_op, op_dec, &$1); } | '+' expression %prec '!' { $$ = $2; } | '~' expression %prec '!' { $$ = *p_not(&$2); } | '!' expression { $$ = *p_notBoolean(&$2); } | '(' _p_casttype ')' expression %prec '!' { $$ = *p_cast($2.type, &$4); } | _string { $$ = *p_stackFrame(e_str | e_const); } | NUMBER { $$ = *p_stackFrame(e_int | e_const); } | '(' expression closepar { $$ = $2; } | _func_or_var | '`' expression _backtick { $$ = *p_oneArg(f_backtick, &$2); } ; icmake-9.02.06/comp/parser/inc/zeroframe.50000644000175000017500000000014713176557635017214 0ustar frankfrankzeroframe: { $$ = *p_stackFrame(0); /* by default initializes a variable to 0 */ } ; icmake-9.02.06/comp/parser/inc/popdead.50000644000175000017500000000005413176557635016633 0ustar frankfrankpopdead: { p_popDead(); } ; icmake-9.02.06/comp/parser/inc/start.40000644000175000017500000000015013176557635016350 0ustar frankfrank %expect 1 /* Grammar Rules */ %% input: input def_var_or_fun | def_var_or_fun ; icmake-9.02.06/comp/parser/inc/breakok.50000644000175000017500000000005613176557635016637 0ustar frankfrankbreak_ok: { gp_breakOK++; } ; icmake-9.02.06/comp/parser/inc/makelist.50000644000175000017500000000510513176557635017032 0ustar frankfrank_p_makeList_expr: MAKELIST openpar err_expression { $$ = $3; } ; _p_makeList_normal: { $$ = *p_stackFrame(e_int | e_const); $$.evalue = IS_FILE; } ; _old_young: OLDER | YOUNGER ; _older_younger: { gp_parse_error = err_older_younger; } _old_young { $$ = $2; } ; p_makeList: _p_makeList_expr /* p_makeList(expr) */ _p_makeList_normal /* returns IS_FILE expression */ { $$ = *p_makeList ( p_multipleArgs ( p_firstArg(&$2), /* IS_FILE is passed */ &$1 /* expression is passed */ ), op_hlt /* not op_younger or op_older */ ); } | /* p_makeList(expr, expr) */ _p_makeList_expr comma err_expression { $$ = *p_makeList ( p_multipleArgs ( p_firstArg(&$1), /* fileattribute is passed */ &$3 /* expression is passed */ ), op_hlt /* not op_younger or op_older */ ); } | _p_makeList_expr /* p_makeList(expr, older, expr) */ comma _older_younger comma err_expression _p_makeList_normal { $$ = *p_makeList ( p_multipleArgs ( p_multipleArgs ( p_firstArg(&$6), /* IS_FILE is passed */ &$1 /* 1st expression is passed */ ), &$5 /* 2nd expression is passed */ ), $3.type /* older/younger */ ); } | _p_makeList_expr /* p_makeList(expr, expr, older, expr) */ comma err_expression comma _older_younger comma err_expression { $$ = *p_makeList ( p_multipleArgs ( p_multipleArgs ( p_firstArg(&$1), /* attribute is passed */ &$3 /* 2nd expression is passed */ ), &$7 /* 3rd expression is passed */ ), $5.type /* older/younger */ ); } ; icmake-9.02.06/comp/parser/inc/varcondition.50000644000175000017500000000035313176557635017720 0ustar frankfrankvar_condition: enter_varid { p_generateCode(&$1, op_push_imm, 0); $$ = $1; } | enter_varid '=' expression { $$ = *p_assign(&$1, &$3); /* explicit initialization */ } ; icmake-9.02.06/comp/parser/inc/returnstat.50000644000175000017500000000037313176557635017436 0ustar frankfrank_return_tail: err_expression | zeroframe ; _leave: RETURN { msg("saw return"); } | EXIT ; return_stat: _leave _return_tail { $$ = *p_return($1.type, &$2); msg("SAW return stmt"); } ; icmake-9.02.06/comp/parser/inc/exprcode.50000644000175000017500000000011513176557635017026 0ustar frankfrankexpr_code: err_expression { $$ = *p_expression(&$1); } ; icmake-9.02.06/comp/parser/inc/nesting.50000644000175000017500000000007413176557635016670 0ustar frankfranknesting: pushdead { gp_nestLevel++; } ; icmake-9.02.06/comp/parser/inc/defvarorfun.50000644000175000017500000000033713176557635017544 0ustar frankfrank_voidtype: VOID { gp_varType = 0; } ; def_var_or_fun: typed_varlist semicol { gp_init = *p_catCode(&gp_init, &$1); } | type_of_var funcdef | _voidtype funcdef ; icmake-9.02.06/comp/parser/inc/statements.50000644000175000017500000000016113176557635017405 0ustar frankfrankstatements: statements statement { $$ = *p_catStmnts(&$1, &$2); } | zeroframe ; icmake-9.02.06/comp/parser/inc/funcdef.50000644000175000017500000000163613176557635016640 0ustar frankfrank /* parameters are defined as local variables of the current function, while counting the number of parameters. At the end of a function definition head its symtab nParams fields holds the number of its parameters, which are represented by the initial nParams elements of symtab's local variables array. */ _partype: type_of_var enterid ; _pars: _pars comma _partype | _partype ; _opt_parlist: _pars | /* empty */ ; _funvars: openpar _opt_parlist ')' openbrace { symtab_setFunParams(); /* the # variables so far are the parameters */ } ; _funid: IDENTIFIER { p_beginFunction(); } ; funcdef: _funid /* name of the function */ _funvars /* returns init code */ statements closebrace { p_endFunction(&$3); } ; icmake-9.02.06/comp/parser/inc/typedcondition.50000644000175000017500000000012213176557635020247 0ustar frankfranktyped_condition: type_of_var var_condition { $$ = $2; } ; icmake-9.02.06/comp/parser/inc/semicol.50000644000175000017500000000013213176557635016647 0ustar frankfranksemicol: { gp_parse_error = err_semicol_expected; } ';' ; icmake-9.02.06/comp/parser/inc/enterid.50000644000175000017500000000027713176557635016660 0ustar frankfrankenterid: IDENTIFIER { p_defineVar(); /* the first n variables of a function, up to the end of the parameter list are the parameters. */ } ; icmake-9.02.06/comp/parser/inc/openbrace.50000644000175000017500000000025513176557635017160 0ustar frankfrankopenbrace: { gp_parse_error = err_openbrace_expected; } '{' /* } (for matching) */ { symtab_push(); } ; icmake-9.02.06/comp/parser/inc/closepar.50000644000175000017500000000012513176557635017026 0ustar frankfrankclosepar: { gp_parse_error = err_closepar_expected; } ')' ; icmake-9.02.06/comp/parser/inc/ifstat.50000644000175000017500000000051713176557635016515 0ustar frankfrank_if: IF nesting { symtab_push(); } ; _else: ELSE statement { $$ = $2; } | zeroframe ; if_stat: _if openpar condition closepar statement popdead pushdead _else popdead { $$ = *p_if(&$3, &$5, &$8); symtab_pop(); } ; icmake-9.02.06/comp/parser/inc/entervarid.50000644000175000017500000000010413176557635017356 0ustar frankfrankenter_varid: enterid { $$ = *p_fetchVar(); } ; icmake-9.02.06/comp/parser/inc/breakstat.50000644000175000017500000000007513176557635017202 0ustar frankfrankbreak_stat: BREAK { $$ = *p_break(); } ; icmake-9.02.06/comp/parser/inc/compound.50000644000175000017500000000012513176557635017042 0ustar frankfrankcompound: openbrace statements closebrace { $$ = $2; } ; icmake-9.02.06/comp/parser/inc/varexprlist.50000644000175000017500000000051113176557635017600 0ustar frankfrankvar_expr_list: var_expr_list comma var_expr { $$ = *p_catCode(&$1, &$3); /* catenate variable */ /* initialization code */ } | var_expr | error ok zeroframe /* Empty stmnt */ { $$ = $3; } ; icmake-9.02.06/comp/parser/inc/forstat.50000644000175000017500000000140213176557635016677 0ustar frankfrank_for: FOR nesting { symtab_push(); } ; _expr_list: _expr_list ',' expr_code { $$ = *p_catCode(&$1, &$3); } | expr_code ; _opt_init_expression: _expr_list | typed_varlist | zeroframe ; _opt_cond_expression: err_expression | { $$ = *p_stackFrame(e_int | e_const); $$.evalue = 1; } ; _opt_inc_expression: _expr_list | zeroframe ; for_stat: _for openpar _opt_init_expression /* $3: init */ semicol _opt_cond_expression /* $5: cond */ semicol _opt_inc_expression /* $7 inc */ closepar break_ok statement /* $10 stmnt */ popdead { $$ = *p_for(&$3, &$5, &$7, &$10); } ; icmake-9.02.06/comp/parser/inc/statement.50000644000175000017500000000047113176557635017226 0ustar frankfrank_stm: compound | ';' zeroframe { $$ = $2; } | expr_code semicol | while_stat | if_stat | for_stat | return_stat semicol | break_stat semicol | continue_stat semicol | error ok ; statement: _stm | typed_varlist semicol ; icmake-9.02.06/comp/parser/inc/ok.50000644000175000017500000000005313176557635015627 0ustar frankfrankok: ';' { yyerrok; } ; icmake-9.02.06/comp/parser/inc/preamble.10000644000175000017500000000007213176557635017002 0ustar frankfrank%{ /* #define msg */ #include "parser.ih" %} icmake-9.02.06/comp/parser/inc/errexpression.50000644000175000017500000000016613176557635020133 0ustar frankfrankerr_expression: { gp_parse_error = err_in_expression; } expression { $$ = $2; } ; icmake-9.02.06/comp/parser/inc/operators.30000644000175000017500000000074613176557635017243 0ustar frankfrank %right '=' AND_IS /* binary-p_assignment */ OR_IS XOR_IS SHL_IS SHR_IS DIV_IS /* arithmetic p_assignment */ MINUS_IS MUL_IS MOD_IS PLUS_IS %right '?' ':' %left OR %left AND %left '|' %left '^' %left '&' %left EQUAL NOT_EQUAL %left '<' '>' SMALLER_EQUAL GREATER_EQUAL OLDER YOUNGER %left SHL SHR %left '+' '-' %left '*' '/' '%' %right '!' INC DEC '~' %left '[' icmake-9.02.06/comp/parser/inc/continuestat.50000644000175000017500000000010613176557635017735 0ustar frankfrankcontinue_stat: CONTINUE { $$ = *p_continue(); } ; icmake-9.02.06/comp/parser/inc/tokens.20000644000175000017500000000124113176557635016516 0ustar frankfrank%token ARG_HEAD ARG_TAIL ASCII BREAK CHDIR CMD_HEAD CMD_TAIL CONTINUE C_BASE C_EXT C_PATH G_BASE G_EXT G_DEXT G_PATH ELEMENT ELSE EVAL EXEC EXECUTE EXISTS EXIT FGETS FIELDS FOR FPRINTF GETENV GETCH GETPID GETS IDENTIFIER IF INT LIST LISTFIND LISTLEN LISTUNION MAKELIST ECHO_TOKEN NUMBER PRINTF PUTENV RETURN STAT STRCHR STRING STRINGTYPE STRLEN STRLWR RESIZE STRUPR STRFIND STRFORMAT SUBSTR SYSTEM TRIM TRIMLEFT TRIMRIGHT VOID WHILE icmake-9.02.06/comp/parser/inc/comma.50000644000175000017500000000013213176557635016310 0ustar frankfrankcomma: { gp_parse_error = err_comma_expected; } ',' ; icmake-9.02.06/comp/parser/inc/typedvarlist.50000644000175000017500000000012113176557635017744 0ustar frankfranktyped_varlist: type_of_var var_expr_list { $$ = $2; } ; icmake-9.02.06/comp/parser/inc/whilestat.50000644000175000017500000000027013176557635017223 0ustar frankfrank_while: WHILE nesting ; while_stat: _while openpar condition closepar break_ok statement popdead { $$ = *p_while(&$3, &$6, 1); } ; icmake-9.02.06/comp/main.ih0000644000175000017500000000006613176557635014335 0ustar frankfrank#include "../rss/rss.h" #include "parser/parser.h" icmake-9.02.06/comp/icmconf0000644000175000017500000000157513176557635014436 0ustar frankfrank#define USE_ECHO ON #define MAIN "main.c" #define COMPILER "gcc" #define COMPILER_OPTIONS "-Wall -Werror -O2 -fdiagnostics-color=never" #define SOURCES "*.c" #define LINKER_OPTIONS "-s" #define ADD_LIBRARIES "icrss" #define ADD_LIBRARY_PATHS "../../tmp" #define REFRESH #define CLS #define SCANNER_DIR "scanner" #define SCANGEN "flex" #define SCANFLAGS "-o lexer.c" #define SCANSPEC "lexer" #define SCANOUT "lexer.c" #define PARSER_DIR "parser" #define PARSGEN "bison" #define PARSSPEC "grammar" #define PARSFLAGS "--defines=tokens.h -o parse.c" #define PARSOUT "parse.c" #define TMP_DIR "tmp" #define LIBRARY "modules" #define OBJ_EXT ".o" #define DEFCOM "program" icmake-9.02.06/comp/build0000755000175000017500000000005213176557635014107 0ustar frankfrank#!/bin/bash ./updategrammar icmbuild $1 icmake-9.02.06/comp/CLASSES0000644000175000017500000000001413176557635014100 0ustar frankfrankutil symtab icmake-9.02.06/comp/global.h0000644000175000017500000000047113176557635014500 0ustar frankfrank#ifndef INCLUDED_GLOBAL_H_ #define INCLUDED_GLOBAL_H_ /* all global variables defined by lower level directories (classes), that must be used by upper level directories */ extern int yynerrs; /* parser */ extern int yylineno; /* scanner */ extern char *yytext; #endif icmake-9.02.06/comp/util/0000755000175000017500000000000013232314221014011 5ustar frankfrankicmake-9.02.06/comp/util/string.c0000644000175000017500000000011313176557635015507 0ustar frankfrank#include "util.ih" char const *util_string() { return gu_lexstring; } icmake-9.02.06/comp/util/util.ih0000644000175000017500000000025113176557635015337 0ustar frankfrank#include "util.h" #include "../../rss/rss.h" #include #include #include "../global.h" extern char *gu_sourceName; extern char *gu_lexstring; icmake-9.02.06/comp/util/printf.c0000644000175000017500000000035113176557635015507 0ustar frankfrank#include "util.ih" int util_printf(char const *fmt, ...) { va_list marker; va_start(marker, fmt); char buffer[80]; int ret = vsnprintf(buffer, 80, fmt, marker); util_setString(buffer); return ret; } icmake-9.02.06/comp/util/util.h0000644000175000017500000000110613176557635015166 0ustar frankfrank#ifndef INCLUDED_UTIL_H_ #define INCLUDED_UTIL_H_ #include char const *util_sourceName(void); char const *util_string(void); int util_printf(char const *fmt, ...); /* fill gu_lexstring */ void util_catString(char const *txt); void util_out(FILE *bin, void const *source, unsigned sourceSizeInBytes); void util_resetSemErr(void); void util_semantic(char const *s, ...); void util_setSourceName(char const *txt); void util_setString(char const *txt); void util_scan(char const *fmt, char const *text); #endif icmake-9.02.06/comp/util/semantic.c0000644000175000017500000000026213176557635016011 0ustar frankfrank#define msgx #include "util.ih" void util_semantic(char const *fmt, ...) { va_list args; va_start(args, fmt); rss_errorList(gu_sourceName, yylineno, fmt, args); } icmake-9.02.06/comp/util/setstring.c0000644000175000017500000000017113176557635016227 0ustar frankfrank#include "util.ih" void util_setString(char const *txt) { free(gu_lexstring); gu_lexstring = rss_strdup(txt); } icmake-9.02.06/comp/util/charconst.c0000644000175000017500000000017013176557635016170 0ustar frankfrank#include "util.ih" void util_charConst() { yytext[0] = yytext[1]; yytext[1] = 0; util_setString(yytext); } icmake-9.02.06/comp/util/data.c0000644000175000017500000000007613176557635015122 0ustar frankfrank#include "util.ih" char *gu_sourceName; char *gu_lexstring; icmake-9.02.06/comp/util/sourcename.c0000644000175000017500000000012013176557635016340 0ustar frankfrank#include "util.ih" char const *util_sourceName() { return gu_sourceName; } icmake-9.02.06/comp/util/catstring.c0000644000175000017500000000015713176557635016207 0ustar frankfrank#include "util.ih" void util_catString(char const *txt) { gu_lexstring = rss_strcat(gu_lexstring, txt); } icmake-9.02.06/comp/util/out.c0000644000175000017500000000035313176557635015016 0ustar frankfrank#include "util.ih" void util_out(FILE *bin, void const *source, unsigned size) { if ( size && !fwrite(source, size * sizeof(int8_t), 1, bin) ) rss_fatal(0, 0, "can't write the bim-file"); } icmake-9.02.06/comp/util/scan.c0000644000175000017500000000024013176557635015126 0ustar frankfrank#include "util.ih" void util_scan(char const *fmt, char const *text) { unsigned value; sscanf(text, fmt, &value); util_printf("%u", value); } icmake-9.02.06/comp/util/setsourcename.c0000644000175000017500000000021413176557635017060 0ustar frankfrank#define msgx #include "util.ih" void util_setSourceName(char const *txt) { free(gu_sourceName); gu_sourceName = rss_strdup(txt); } icmake-9.02.06/comp/util/frame0000644000175000017500000000004313176557635015054 0ustar frankfrank#include "util.ih" void util_ { } icmake-9.02.06/comp/main.c0000644000175000017500000000117513176557635014161 0ustar frankfrank/* #define msg */ #include "main.ih" int main (int argc, char **argv) /* icm-comp source(txt) dest(bin) */ { if (argc != 3) { rss_copyright(rss_programName(argv[0])); printf("Usage: %s source dest\n" "where:\n" "\tsource: source file to compile\n" "\t (normally output from ICM-PP)\n" "\tdest: name of binary file to generate\n" , rss_programName(argv[0])); return 0; } parser(argv); yyparse(); /* parse the source */ return parser_backend(); } icmake-9.02.06/contributions/0000755000175000017500000000000013176557635015031 5ustar frankfrankicmake-9.02.06/contributions/solaris0000644000175000017500000000367613176557635016444 0ustar frankfrankDate: Sun, 16 Oct 2011 19:59:00 +0000 Subject: A few hoops for icmake to compile on Solaris From: "Johann 'Myrkraverk' Oskarsson" To: f.b.brokken@rug.nl Hi, Here is a short list of hoops I had to jump through in order to make icmake compile on Solaris. Specifically OpenIndiana 151a. Change to icm_bootstrap: The comp subdirectory does not build with gcc, but does with Solaris Studio 12.3 cc: echo Creating tmp/${LIBDIR}/icm-comp${EXTENSION} try cd comp try cc ${GLB} ${CFLAGS} \ -o ../tmp/${LIBDIR}/icm-comp${EXTENSION} *.c ../tmp/libicrss.a \ ${LDFLAGS} cd .. In the following three files, before #include , exec/string/string.ih, exec/virtual/virtual.ih, exec/list/list.ih: #undef getopt #undef getoptindex #undef getoptval I was unable to find a way to exclude these three symbols from the header file with a -Ddefine. If these symbols are not meant to be there in some Posix standard it should be. The reason: it conflicts with the ic_ definitions from earlier include files. Above, when comp is compiled with gcc, errors similar (or same as) the following spew out: In file included from /usr/include/stdio.h:81:0, from lexer.c:21: /usr/include/iso/stdio_iso.h:212:60: error: redefinition of parameter 'restrict' If you need more information to fix this for future versions of icmake, please just ask, Johann ---------------------------------------- Date: Tue, 22 Apr 2008 00:56:23 +0000 o Bitrot: I had to add -std=c99 to all gcc lines due to some macro defining the "restrict" keyword in my system header files. I suspect something defined in the icmake header files but I 'm not sure. o I had to change all getoptXXX calls to ic_getoptXXX becouse of some conflict with my system getopt/headers/macros or something. o In all build scripts, I had to change the shebang lines from #!tmp/icmake -qt/tmp/pp to #!/opt/myrkraverk/bin/icmake -qt/tmp/pp -- or at least, I had to change them due to something. icmake-9.02.06/dep/0000755000175000017500000000000013232314232012650 5ustar frankfrankicmake-9.02.06/dep/usage.c0000644000175000017500000000645413176557635014160 0ustar frankfrank#include "main.ih" void usage(char const *progname) { rss_copyright(progname = rss_programName(progname)); printf( "Usage: %s [options] [go]\n" "Where:\n" " [options] - optional arguments (short options between parentheses):\n" " --classes (-c) file - file defining the class-subdirectories (" "CLASSES)\n" " --gch - inspect/remove .gch precompiled headers,\n" " otherwise: don't handle precompiled " "headers.\n" " --help (-h) - provide this help (also if neither --dry\n" " nor --go was specified)\n" " --icmconf (-i) file - icmconf file to use (icmconf)\n" " --mainih (-m) ihfile - the top directory's main .ih file " "(main.ih)\n" " --no-gch - do not inspect .gch precompiled headers.\n" " --no-use-all - do not inspect USE_ALL files\n" " --use-all file - use 'file' as USE_ALL filename, and add " "implied\n" " 'file' files where necessary\n" " --verbose (-V) - show touched files; more info if " "specified \n" " multiple times\n" " --version (-v) - show version information and terminate\n" "\n" "When neither --gch nor --no-gch is specified icmonf's PRECOMP " "specification\n" "is used;\n" "When neither --use-all nor --no-use-all is specified icmonf's USE_ALL\n" "specification is used.\n" "\n" "Files are only changed if the program argument 'go' (without the " "quotes)\n" "is provided\n" "\n", progname); exit(0); } /**************************************** All directories mentioned in CLASSES and cwd are inspected for USE_ALL (defined in icmconf) files. If a directory contains a USE_ALL file then a USE_ALL file is also created in all directories including that directory's .h file. When the --precomp option is specified then all not yet visited directories in CLASSES (and the cwd) are scanned for files matching the comma-separated list of files. If the directory has already been visited then nothing happens in that directory. Otherwise the directory is marked as inspected. If no file matches the list of --precomp files then that directory has been processed. If the .gch file does not yet exist or if at least one of the comma separated patterns in --inspect is younger than the .gch file then this directory's .gch file must be (re)compiled If a gch file must be recompiled, then indicate that the gch files of classes depending on the gch file's class must also be recompiled. Once the list of gch files to recompile has been determined - show the files to recompile on stdout, - or rm the gch files if --rm was specified. ****************************************/ icmake-9.02.06/dep/vector/0000755000175000017500000000000013232314232014152 5ustar frankfrankicmake-9.02.06/dep/vector/add.c0000644000175000017500000000043313176557635015075 0ustar frankfrank#include "vector.ih" void add(Vector *vector, char const *txt) { if (find(vector, txt) != -1) return; vector->txt = rss_realloc(vector->txt, (vector->size + 1) * sizeof(char *)); vector->txt[vector->size++] = rss_strdup(txt); } icmake-9.02.06/dep/vector/vector.h0000644000175000017500000000123513176557635015655 0ustar frankfrank#ifndef INCLUDED_VECTOR_ #define INCLUDED_VECTOR_ typedef struct { int size; char **txt; } Vector; Vector *VectorCons(); void VectorDestructor(Vector *vector); void add(Vector *vector, char const *txt); // set operation: only once void assign(Vector *vector, int idx, char const *txt); void resize(Vector *vector, int newSize); void replaceN(Vector *vector, int idx, char const *txt, int size); void erase(Vector *vector, int idx); int find(Vector *vector, char const *target); inline char const *at(Vector const *vector, int idx) { return vector->txt[idx]; } inline int vSize(Vector const *vector) { return vector->size; } #endif icmake-9.02.06/dep/vector/vector1.c0000644000175000017500000000022513176557635015727 0ustar frankfrank#include "vector.ih" Vector *VectorCons() { Vector *ret = rss_realloc(0, sizeof(Vector)); memset(ret, 0, sizeof(Vector)); return ret; } icmake-9.02.06/dep/vector/vectorreplacen.c0000644000175000017500000000034113176557635017357 0ustar frankfrank#include "vector.ih" void replaceN(Vector *vector, int idx, char const *txt, int size) { free(vector->txt[idx]); char *cp = vector->txt[idx] = rss_realloc(0, size + 1); memcpy(cp, txt, size); cp[size] = 0; } icmake-9.02.06/dep/vector/erase.c0000644000175000017500000000016713176557635015450 0ustar frankfrank#include "vector.ih" void erase(Vector *vector, int idx) { free(vector->txt[idx]); vector->txt[idx] = NULL; } icmake-9.02.06/dep/vector/find.c0000644000175000017500000000035213176557635015265 0ustar frankfrank#include "vector.ih" int find(Vector *vector, char const *target) { for (int idx = 0, end = vector->size; idx != end; ++idx) { if (strcmp(vector->txt[idx], target) == 0) return idx; } return -1; } icmake-9.02.06/dep/vector/resize.c0000644000175000017500000000106013176557635015643 0ustar frankfrank#include "vector.ih" void resize(Vector *vector, int newSize) { int currentSize = vector->size; if (newSize == currentSize) return; if (newSize < currentSize) { for (int idx = newSize, end = vector->size; idx != end; ++idx) free(vector->txt[idx]); } vector->size = newSize; vector->txt = rss_realloc(vector->txt, newSize * sizeof(char *)); if (newSize > currentSize) memset(vector->txt + currentSize * sizeof(char *), 0, (newSize - currentSize) * sizeof(char *)); } icmake-9.02.06/dep/vector/vector.ih0000644000175000017500000000013213176557635016021 0ustar frankfrank#include "vector.h" #include #include #include "../../rss/rss.h" icmake-9.02.06/dep/vector/vectordestructor.c0000644000175000017500000000021213176557635017761 0ustar frankfrank#include "vector.ih" void VectorDestructor(Vector *vector) { for (int idx = vector->size; idx--; ) free(vector->txt[idx]); } icmake-9.02.06/dep/vector/frame0000644000175000017500000000006613176557635015220 0ustar frankfrank#include "vector.ih" void vector(Vector *vector) { } icmake-9.02.06/dep/vector/assign.c0000644000175000017500000000032413176557635015630 0ustar frankfrank#include "vector.ih" void assign(Vector *vector, int idx, char const *txt) { // printf("ASSIGN: %s, old = %p\n", txt, vector->txt[idx]); free(vector->txt[idx]); vector->txt[idx] = rss_strdup(txt); } icmake-9.02.06/dep/process/0000755000175000017500000000000013232314232014326 5ustar frankfrankicmake-9.02.06/dep/process/ptouch.c0000644000175000017500000000023213176557635016020 0ustar frankfrank#include "process.ih" void pTouch(char const *path) { if (sproc.d_go == GO) fclose(openFile(path, "w")); optMsg(1, "touch %s", path); } icmake-9.02.06/dep/process/processactions.c0000644000175000017500000000021213176557635017553 0ustar frankfrank#include "process.ih" void processActions() { if (sproc.d_use_all) pUseAll(); if (sproc.d_gch == GCH) pGch(); } icmake-9.02.06/dep/process/pgch.c0000644000175000017500000000064213176557635015444 0ustar frankfrank#include "process.ih" void pGch() { int *indicator = depGchIndicator(); int *toRm = initRow(sproc.d_size); for (int idx = 0; idx != sproc.d_size; ++idx) { if (indicator[idx]) pInspectGch(toRm, idx); } for (int idx = 0; idx != sproc.d_size; ++idx) { if (toRm[idx]) pUnlinkGch(idx); // try to unlink the gch file } free(toRm); } icmake-9.02.06/dep/process/puseall.c0000644000175000017500000000062313176557635016167 0ustar frankfrank#include "process.ih" void pUseAll() { int const *exists = depUseAllExists(); int *toTouch = initRow(sproc.d_size); for (int idx = 0; idx != sproc.d_size; ++idx) { if (exists[idx]) pInspectUseAll(toTouch, idx); } for (int idx = 0; idx != sproc.d_size; ++idx) { if (toTouch[idx]) pTouch(depUseAll(idx)); } free(toTouch); } icmake-9.02.06/dep/process/pinspectgch.c0000644000175000017500000000064613176557635017036 0ustar frankfrank#include "process.ih" void pInspectGch(int *toRm, int idx) { if (!toRm[idx]) optMsg(4, "(re)compile %s", depGch(idx)); int const *dep = depDependent(idx); // get classes depending on idx toRm[idx] = 1; for (idx = 0; idx != sproc.d_size; ++idx) { if (!dep[idx] || toRm[idx]) continue; optMsg(4, "(re)compile %s", depGch(idx)); toRm[idx] = 1; } } icmake-9.02.06/dep/process/process1.c0000644000175000017500000000031513176557635016257 0ustar frankfrank#include "process.ih" Process sproc; void ProcessCons() { sproc.d_size = depSize(); sproc.d_go = optGo(); sproc.d_gch = optGch(); sproc.d_use_all = optUseAll(); } icmake-9.02.06/dep/process/process.h0000644000175000017500000000015713176557635016207 0ustar frankfrank#ifndef INCLUDED_PROCESS_ #define INCLUDED_PROCESS_ void ProcessCons(); void processActions(); #endif icmake-9.02.06/dep/process/process.ih0000644000175000017500000000102213176557635016350 0ustar frankfrank#include "process.h" #include #include #include #include #include "../../rss/rss.h" #include "../util/util.h" #include "../options/options.h" #include "../dependencies/dependencies.h" typedef struct { int d_size; int d_go; int d_gch; char const *d_use_all; } Process; extern Process sproc; void pUseAll(); void pInspectUseAll(int *touch, int classIdx); void pTouch(char const *path); void pGch(); void pInspectGch(int *rm, int idx); void pUnlinkGch(int idx); icmake-9.02.06/dep/process/punlinkgch.c0000644000175000017500000000033013176557635016657 0ustar frankfrank#include "process.ih" void pUnlinkGch(int idx) { char const *path = depGch(idx); if (!rss_exists(path)) return; optMsg(1, "unlink(%s)", path); if (sproc.d_go == GO) unlink(path); } icmake-9.02.06/dep/process/pinspectuseall.c0000644000175000017500000000065013176557635017555 0ustar frankfrank#include "process.ih" void pInspectUseAll(int *toTouch, int classIdx) { int const *dep = depDependent(classIdx); for (int idx = 0; idx != sproc.d_size; ++idx) { if (!dep[idx] || toTouch[idx] == 1) continue; char const *useAll = depUseAll(idx); if ( !rss_exists(useAll) ) { optMsg(1, "touch %s", useAll); toTouch[idx] = 1; } } } icmake-9.02.06/dep/icm_bootstrap0000755000175000017500000000024113176557635015467 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/${LIBDIR}/icm-dep build icm-dep vector util options dependencies process icmake-9.02.06/dep/options/0000755000175000017500000000000013232314232014343 5ustar frankfrankicmake-9.02.06/dep/options/optscanner.c0000644000175000017500000000012013176557635016703 0ustar frankfrank#include "options.ih" char const *optScanner() { return sopts.d_scanner; } icmake-9.02.06/dep/options/oicmconf.c0000644000175000017500000000402113176557635016330 0ustar frankfrank#include "options.ih" static int accept(char const *label, char const *key, char const *value) { return strcmp(label, key) == 0 && value && strlen(value) > 0; } void oIcmconf(char *argv0) { FILE *in = openFile(sopts.d_icmconf, "r"); char *line; while ((line = getLine(in))) { Vector const *vector = regMatch(&sopts.d_icmconfRE, line); free(line); if (vector) // match { char const *key = at(vector, 1); char const *value = at(vector, 2); if (strcmp("PRECOMP", key) == 0) { if (sopts.d_gch == UNSPECIFIED) { optMsg(1, "inspecting precompiled headers (.gch files)"); sopts.d_gch = GCH; } } else if (accept("IH", key, value)) { optMsg(2, "used header extension: %s", value); sopts.d_ih = rss_strdup(value); } else if (accept("USE_ALL", key, value)) { if (sopts.d_use_all == (char *)UNSPECIFIED) { optMsg(1, "inspecting USE_ALL files: %s", value); sopts.d_use_all = rss_strdup(value); } } else if (accept("PARSER_DIR", key, value)) { optMsg(2, "implied parser dir.: %s", value); sopts.d_parser = rss_strdup(value); } else if (accept("SCANNER_DIR", key, value)) { optMsg(2, "implied scanner dir.: %s", value); sopts.d_scanner = rss_strdup(value); } } } fclose(in); if (sopts.d_go == UNSPECIFIED) usage(argv0); if (sopts.d_gch == UNSPECIFIED) { optMsg(1, "not inspecting .gch files"); sopts.d_gch = NO_GCH; } if (sopts.d_use_all == (char *)UNSPECIFIED) { optMsg(1, "not inspecting USE_ALL files"); sopts.d_use_all = NULL; } } icmake-9.02.06/dep/options/optgch.c0000644000175000017500000000010013176557635016011 0ustar frankfrank#include "options.ih" int optGch() { return sopts.d_gch; } icmake-9.02.06/dep/options/optgo.c0000644000175000017500000000007613176557635015671 0ustar frankfrank#include "options.ih" int optGo() { return sopts.d_go; } icmake-9.02.06/dep/options/optparser.c0000644000175000017500000000011713176557635016554 0ustar frankfrank#include "options.ih" char const *optParser() { return sopts.d_parser; } icmake-9.02.06/dep/options/optuseall.c0000644000175000017500000000011713176557635016545 0ustar frankfrank#include "options.ih" char const *optUseAll() { return sopts.d_use_all; } icmake-9.02.06/dep/options/options.h0000644000175000017500000000064413176557635016242 0ustar frankfrank#ifndef INCLUDED_OPTIONS_ #define INCLUDED_OPTIONS_ enum { DRY, GO, NO_GCH, GCH, UNSPECIFIED, }; void OptionsCons(int argc, char **argv); char const *optClasses(); char const *optParser(); char const *optScanner(); char const *optMainih(); char const *optIH(); char const *optUseAll(); int optVerbose(); int optGch(); int optGo(); void optMsg(int requiredLevel, char const *fmt, ...); #endif icmake-9.02.06/dep/options/optih.c0000644000175000017500000000010613176557635015656 0ustar frankfrank#include "options.ih" char const *optIH() { return sopts.d_ih; } icmake-9.02.06/dep/options/options.ih0000644000175000017500000000126513176557635016413 0ustar frankfrank#include "options.h" #include #include #include #include #include #include #include "../../rss/rss.h" #include "../util/util.h" typedef struct { regex_t d_icmconfRE; char *d_classes; char *d_icmconf; char *d_mainih; char *d_ih; int d_gch; // inspect gch files char *d_use_all; // inspect USE_ALL files int d_go; int d_verbose; char *d_parser; char *d_scanner; } Options; extern char version[]; extern char years[]; extern char author[]; extern Options sopts; void oIcmconf(char *argv0); void usage(char *progName); icmake-9.02.06/dep/options/optmsg.c0000644000175000017500000000036313176557635016051 0ustar frankfrank#include "options.ih" void optMsg(int requiredLevel, char const *fmt, ...) { if (sopts.d_verbose < requiredLevel) return; va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); putchar('\n'); } icmake-9.02.06/dep/options/optclasses.c0000644000175000017500000000012113176557635016710 0ustar frankfrank#include "options.ih" char const *optClasses() { return sopts.d_classes; } icmake-9.02.06/dep/options/frame0000644000175000017500000000004113176557635015402 0ustar frankfrank#include "options.ih" void { } icmake-9.02.06/dep/options/options1.c0000644000175000017500000000652413176557635016321 0ustar frankfrank#include "options.ih" static struct option longOpts[] = { {"classes", required_argument, NULL, 'c'}, {"gch", no_argument, NULL, 'G'}, // no -G option {"help", no_argument, NULL, 'h'}, {"icmconf", required_argument, NULL, 'i'}, {"mainih", required_argument, NULL, 'm'}, {"no-gch", no_argument, NULL, 'n'}, // no -n option {"no-use-all", no_argument, NULL, 'U'}, // no -U option {"use-all", required_argument, NULL, 'u'}, // no -u option {"verbose", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'v'}, {NULL} }; Options sopts; void OptionsCons(int argc, char **argv) { regComp(&sopts.d_icmconfRE, "^[ \t]*#define[ \t]*" "([^ \t]+)" // #1: key "[ \t]*\"" "([^\"]+)?" // #2: value (opt) "\""); sopts.d_classes = "CLASSES"; sopts.d_icmconf = "icmconf"; sopts.d_mainih = "main.ih"; sopts.d_ih = ".ih"; sopts.d_use_all = (char *)UNSPECIFIED; // by default: read icmconf sopts.d_gch = UNSPECIFIED; sopts.d_go = UNSPECIFIED; int showVersion = 0; int sawOptions = 0; while (1) { int opt = getopt_long(argc, argv, "cdimhvV", longOpts, NULL); sawOptions |= opt != -1; switch (opt) { case 'c': sopts.d_classes = rss_strdup(optarg); break; case 'G': sopts.d_gch = GCH; optMsg(2, "inspecting .gch files"); break; case 'h': usage(argv[0]); break; // usage exits case 'i': sopts.d_icmconf = rss_strdup(optarg); optMsg(2, "using icmconf `%s'", optarg); break; case 'm': sopts.d_mainih = rss_strdup(optarg); optMsg(2, "using main.ih `%s'", optarg); break; case 'u': sopts.d_use_all = rss_strdup(optarg); optMsg(2, "using USE_ALL filename `%s'", optarg); break; case 'U': sopts.d_use_all = NULL; optMsg(2, "not inspecting USE_ALL files"); break; case 'v': showVersion = 1; break; case 'V': ++sopts.d_verbose; break; case '?': printf("no option '-%c'\n", (char)opt); exit(1); break; case -1: if (showVersion) { printf("V %s\n", version); exit(0); } if (argc != optind) sopts.d_go = strcmp(argv[optind], "go") == 0 ? GO : DRY; else { if (!sawOptions) usage(argv[0]); sopts.d_go = DRY; } if (!rss_exists(sopts.d_classes)) { optMsg(2, "No file '%s'", sopts.d_classes); exit(0); } oIcmconf(argv[0]); return; } } } icmake-9.02.06/dep/options/optverbose.c0000644000175000017500000000011013176557635016716 0ustar frankfrank#include "options.ih" int optVerbose() { return sopts.d_verbose; } icmake-9.02.06/dep/options/optmainih.c0000644000175000017500000000011613176557635016524 0ustar frankfrank#include "options.ih" char const *optMainih() { return sopts.d_mainih; } icmake-9.02.06/dep/main.ih0000644000175000017500000000035213176557635014145 0ustar frankfrank#include #include "../rss/rss.h" #include "util/util.h" #include "options/options.h" #include "dependencies/dependencies.h" #include "process/process.h" extern char version[]; extern char years[]; extern char author[]; icmake-9.02.06/dep/icmconf0000644000175000017500000000102013176557635014231 0ustar frankfrank#define CLS #define MAIN "main.c" #define SOURCES "*.c" #define OBJ_EXT ".o" #define SHAREDREQ "" #define TMP_DIR "tmp" #define USE_ALL "a" #define USE_ECHO ON #define CXX "gcc" #define CXXFLAGS " -O2 -fdiagnostics-color=never " #define REFRESH #define LDFLAGS "" #define ADD_LIBRARIES "icrss" #define ADD_LIBRARY_PATHS "/home/frank/src/icmake/rss/tmp" #define DEFCOM "program" icmake-9.02.06/dep/build0000755000175000017500000000003213176557635013717 0ustar frankfrank#!/bin/bash icmbuild $1 icmake-9.02.06/dep/CLASSES0000644000175000017500000000005113176557635013713 0ustar frankfrankvector util options dependencies process icmake-9.02.06/dep/util/0000755000175000017500000000000013232314232013625 5ustar frankfrankicmake-9.02.06/dep/util/freetable.c0000644000175000017500000000022413176557635015747 0ustar frankfrank#include "util.ih" void freeTable(int **table, int size) { for (int idx = 0; idx != size; ++idx) free(table[idx]); free(table); } icmake-9.02.06/dep/util/util.ih0000644000175000017500000000030413176557635015150 0ustar frankfrank#include "util.h" #include #include #include #include #include "../../rss/rss.h" #include "../util/util.h" extern int s_cwd; extern Vector s_vector; icmake-9.02.06/dep/util/strcatn.c0000644000175000017500000000041513176557635015476 0ustar frankfrank#include "util.ih" static char sPath[MAX_PATHLEN]; char const *strcatN(int count, ...) { va_list args; va_start(args, count); sPath[0] = 0; for (; count--; ) strcat(sPath, va_arg(args, char const *)); va_end(args); return sPath; } icmake-9.02.06/dep/util/trychdir.c0000644000175000017500000000031413176557635015646 0ustar frankfrank#include "util.ih" void tryChdir(char const *subdir) { if (chdir(subdir) != 0) // change to requested dir { printf("can't cd to `%s'\n", subdir); exit(1); } } icmake-9.02.06/dep/util/utilinit.c0000644000175000017500000000014313176557635015657 0ustar frankfrank#include "util.ih" void UtilInit() { s_cwd = dirfd(opendir(".")); resize(&s_vector, 5); } icmake-9.02.06/dep/util/util.h0000644000175000017500000000125613176557635015006 0ustar frankfrank#ifndef INCLUDED_UTIL_H_ #define INCLUDED_UTIL_H_ #include #include #include #include #include "../vector/vector.h" void regComp(regex_t *regex, char const *pattern); Vector const *regMatch(regex_t *regex, char const *line); char *getLine(FILE *in); FILE *openFile(char const *name, char const *mode); // "r" or "w" void toCwd(); void tryChdir(char const *subdir); void UtilInit(); int **initTable(int size); int *initRow(int size); void freeTable(int **table, int size); char const *strcatN(int count, ...); // all char const *args are cat-ed and // the result is returned as a NTBS #endif icmake-9.02.06/dep/util/initrow.c0000644000175000017500000000017513176557635015516 0ustar frankfrank#include "util.ih" int *initRow(int size) { return memset(rss_realloc(0, size * sizeof(int)), 0, size * sizeof(int)); } icmake-9.02.06/dep/util/openfile.c0000644000175000017500000000045713176557635015627 0ustar frankfrank#include "util.ih" FILE *openFile(char const *name, char const *mode) { FILE *ret = fopen(name, mode); if (ret == NULL) { printf("can't %s `%s'\n", strcmp(mode, "r") == 0 ? "read" : "write", name); exit(1); } return ret; } icmake-9.02.06/dep/util/data.c0000644000175000017500000000006013176557635014725 0ustar frankfrank#include "util.ih" int s_cwd; Vector s_vector; icmake-9.02.06/dep/util/getline.c0000644000175000017500000000060613176557635015451 0ustar frankfrank#include "util.ih" char *getLine(FILE *in) { char buffer[100]; char *ret = 0; while (fgets(buffer, 100, in) != NULL) { int len = strlen(buffer); int stop = buffer[len - 1] == '\n'; if (stop) buffer[len - 1] = 0; ret = rss_strcat(ret, buffer); if (stop) return ret; } free(ret); return NULL; } icmake-9.02.06/dep/util/tocwd.c0000644000175000017500000000023113176557635015134 0ustar frankfrank#include "util.ih" void toCwd() { if (fchdir(s_cwd) != 0) { printf("can't return to the initial directory\n"); exit(1); } } icmake-9.02.06/dep/util/regmatch.c0000644000175000017500000000115613176557635015615 0ustar frankfrank#include "util.ih" enum { NSUB = 5 }; static regmatch_t subExpr[NSUB]; Vector const *regMatch(regex_t *regex, char const *line) { if (regexec(regex, line, NSUB, subExpr, 0) != 0) return NULL; for (int idx = 0; idx != NSUB; ++idx) { int begin = subExpr[idx].rm_so; //fprintf(stderr, " idx: $d, begin = %d\n", idx, begin); if (begin == -1) // not found { erase(&s_vector, idx); continue; } int length = subExpr[idx].rm_eo - begin; replaceN(&s_vector, idx, line + begin, length); } return &s_vector; } icmake-9.02.06/dep/util/inittable.c0000644000175000017500000000067713176557635016005 0ustar frankfrank#include "util.ih" int **initTable(int size) { int **table = rss_realloc(0, size * sizeof(int *)); for (int idx = 0; idx != size; ++idx) { table[idx] = initRow(size); memset(table[idx] = rss_realloc(0, size * sizeof(int)), 0, size * sizeof(int)); table[idx][idx] = 1; // indicate dependent on itself; } // used by closure return table; } icmake-9.02.06/dep/util/regcomp.c0000644000175000017500000000041013176557635015447 0ustar frankfrank#include "util.ih" void regComp(regex_t *regex, char const *pattern) { int regOut = regcomp(regex, pattern, REG_EXTENDED); if (regOut != 0) { char buffer[100]; regerror(regOut, regex, buffer, 100); exit(1); } } icmake-9.02.06/dep/dependencies/0000755000175000017500000000000013232314232015276 5ustar frankfrankicmake-9.02.06/dep/dependencies/dfinddependents.c0000644000175000017500000000106113176557635020625 0ustar frankfrank#include "dependencies.ih" void dFindDependents() { dIniTable(); dFillTable(); int size = sdep.d_size; int **reversed = initTable(size); dTranspose(reversed, sdep.d_dependent, size); if (optVerbose() > 3) dShowTable("Dependents (initial):", reversed); dImpliedDependencies(sdep.d_dependent, size); dTranspose(reversed, sdep.d_dependent, size); freeTable(sdep.d_dependent, size); sdep.d_dependent = reversed; if (optVerbose() < 3) return; dShowTable("Dependents:", sdep.d_dependent); } icmake-9.02.06/dep/dependencies/dependencies1.c0000644000175000017500000000433213176557635020202 0ustar frankfrank#include "dependencies.ih" Dependencies sdep; void DependenciesCons() { regComp(&sdep.d_includeRegex, "^[ \\t]*#include[ \\t]*\"" // #include " "(\\.\\./)?" // #1: ../ (opt) "(([^/\"]+)/)?" // #2, #3: ((class)/) (opt) "([^/\"]+)" // #4: (whatever) "\""); // " // #include "../class/whatever" - numbered sub-patterns // <1><--2-> // <-3-> <--4--> // #include "whatever" - include a local header -> toDo // (#1: NULL #2: NULL #3: NULL, #4) // #include "class/whatever" - include nested header (fm main) // (#1: NULL $2 #3 #4) // #include "../class/whatever" - include another class's header // (#1 #2 #3 #4) // #include "../whatever" - include a main-header // (#1 #2: NULL #3: NULL #4) dReadClasses(); // assigns 'size' sdep.d_gchPaths = VectorCons(); resize(sdep.d_gchPaths, sdep.d_size); sdep.d_gch = optGch(); if ((sdep.d_useAll = optUseAll())) { sdep.d_useAllPaths = VectorCons(); resize(sdep.d_useAllPaths, sdep.d_size); for (int idx = 0; idx != sdep.d_size; ++idx) assign(sdep.d_useAllPaths, idx, strcatN(3, depDir(idx), "/", sdep.d_useAll) ); } sdep.d_gchIndicator = initRow(sdep.d_size); sdep.d_useAllExists = initRow(sdep.d_size); dFindDependents(); } // printf("gch files must be compiled for: "); // for (int idx = 0, end = sdep.d_size; idx != end; ++idx) // { // if (sdep.d_gchIndicator[idx]) // printf("%s ", at(sdep.d_dirNames, idx)); // } // printf("\n"); // // printf("classes haing USE_ALL files: "); // for (int idx = 0, end = sdep.d_size; idx != end; ++idx) // { // if (sdep.d_useAllExists[idx]) // printf("%s ", at(sdep.d_dirNames, idx)); // } // printf("\n"); icmake-9.02.06/dep/dependencies/depsize.c0000644000175000017500000000010613176557635017131 0ustar frankfrank#include "dependencies.ih" int depSize() { return sdep.d_size; } icmake-9.02.06/dep/dependencies/depuseallexists.c0000644000175000017500000000013513176557635020706 0ustar frankfrank#include "dependencies.ih" int const *depUseAllExists() { return sdep.d_useAllExists; } icmake-9.02.06/dep/dependencies/dreadclasses.c0000644000175000017500000000151013176557635020123 0ustar frankfrank#include "dependencies.ih" void dReadClasses() { FILE *classes = openFile(optClasses(), "r"); sdep.d_dirNames = VectorCons(); add(sdep.d_dirNames, "."); char const *cp; if ((cp = optParser())) add(sdep.d_dirNames, cp); if ((cp = optScanner())) add(sdep.d_dirNames, cp); char *line; while ((line = getLine(classes))) // get line from CLASSES { char *class = strtok(line, " \t"); // pick the first word if ( class != NULL // accept lines not && // starting at #, / strchr("#/", *class) == NULL ) add(sdep.d_dirNames, class); free(line); } sdep.d_size = vSize(sdep.d_dirNames); fclose(classes); } icmake-9.02.06/dep/dependencies/dhandleinclude.c0000644000175000017500000000225013176557635020433 0ustar frankfrank#include "dependencies.ih" void dHandleInclude(int idx, Vector *toDo, char const *line, char const *hdr) { Vector const *vector = regMatch(&sdep.d_includeRegex, line); if (vector == NULL) return; // no match char const *class = at(vector, 3); if (at(vector, 1) == NULL) // local header, or main subhdr { if (class == NULL) // local header included { add(toDo, at(vector, 4)); return; } } if (idx == 0 && at(vector, 1) != NULL) return; // parent dirs of main are ignored if (class == NULL) // include a main header { // depending on a top level header: sdep.d_dependent[idx][0] = 1; return; } int classIdx = find(sdep.d_dirNames, class); if (classIdx < 0) { optMsg(4, "'%s' not in '%s' ('%s': `%s')", class, optClasses(), hdr, line); return; } // depending on a local header sdep.d_dependent[idx][classIdx] = 1; } icmake-9.02.06/dep/dependencies/dimplieddependencies.c0000644000175000017500000000060113176557635021624 0ustar frankfrank#include "dependencies.ih" void dImpliedDependencies(int **data, int size) { int indicator[size]; for (int row = 0; row != size; ++row) { memset(indicator, 0, size * sizeof(int)); dClosure(indicator, row, data, size); memcpy(data[row], indicator, size * sizeof(int)); } for (int idx = 0; idx != size; ++idx) data[idx][idx] = 0; } icmake-9.02.06/dep/dependencies/depdependent.c0000644000175000017500000000014313176557635020126 0ustar frankfrank#include "dependencies.ih" int const *depDependent(int idx) { return sdep.d_dependent[idx]; } icmake-9.02.06/dep/dependencies/dependencies.h0000644000175000017500000000044713176557635020131 0ustar frankfrank#ifndef INCLUDED_DEPENDENCIES_ #define INCLUDED_DEPENDENCIES_ void DependenciesCons(); int depSize(); char const *depDir(int idx); char const *depGch(int idx); char const *depUseAll(int idx); int const *depDependent(int idx); int const *depUseAllExists(); int *depGchIndicator(); #endif icmake-9.02.06/dep/dependencies/depuseall.c0000644000175000017500000000014713176557635017451 0ustar frankfrank#include "dependencies.ih" char const *depUseAll(int idx) { return at(sdep.d_useAllPaths, idx); } icmake-9.02.06/dep/dependencies/dfilltable.c0000644000175000017500000000070313176557635017573 0ustar frankfrank#include "dependencies.ih" void dFillTable() { // inspect all class-ih files for (int idx = 1, end = sdep.d_size; idx != end; ++idx) { optMsg(4, "Inspecting '%s/'", depDir(idx)); chdir(depDir(idx)); dInspectIH(idx, dIhFile(idx)); toCwd(); } optMsg(4, "Inspecting './'"); dInspectIH(0, optMainih()); optMsg(4, "Header inspection completed"); } icmake-9.02.06/dep/dependencies/dinspectgch.c0000644000175000017500000000134313176557635017765 0ustar frankfrank#include "dependencies.ih" void dInspectGch(int idx, char const *hdr) { if ( sdep.d_gch == NO_GCH // no gch tests || sdep.d_gchIndicator[idx] == 1 // or already decided to recomp. ) return; if (!rss_exists(hdr)) { printf("`%s' does not exist\n", hdr); exit(1); } if (!rss_exists(sdep.d_currentGch)) { optMsg(3, "compile non-existing %s", sdep.d_currentGch); sdep.d_gchIndicator[idx] = 1; } else if (rss_older(sdep.d_currentGch, hdr)) { optMsg(4, "%s older %s", sdep.d_currentGch, hdr); // recompile if gch is older than a req'd hdr sdep.d_gchIndicator[idx] = 1; } } icmake-9.02.06/dep/dependencies/dcheckuseall.c0000644000175000017500000000026413176557635020122 0ustar frankfrank#include "dependencies.ih" void dCheckUseAll(int idx) { if (sdep.d_useAll == NULL) return; if (rss_exists(sdep.d_useAll)) sdep.d_useAllExists[idx] = 1; } icmake-9.02.06/dep/dependencies/depgch.c0000644000175000017500000000014113176557635016717 0ustar frankfrank#include "dependencies.ih" char const *depGch(int idx) { return at(sdep.d_gchPaths, idx); } icmake-9.02.06/dep/dependencies/dinspectfile.c0000644000175000017500000000077113176557635020147 0ustar frankfrank#include "dependencies.ih" void dInspectFile(int idx, Vector *toDo, int toDoIdx) { char const *hdr = toDo->txt[toDoIdx]; if (!rss_exists(hdr)) { optMsg(4, "%s does not exist: skipped", hdr); return; } optMsg(4, "%s...", hdr); dInspectGch(idx, hdr); FILE *file = openFile(toDo->txt[toDoIdx], "r"); char *line; while ((line = getLine(file))) { dHandleInclude(idx, toDo, line, hdr); free(line); } fclose(file); } icmake-9.02.06/dep/dependencies/dinspectih.c0000644000175000017500000000136113176557635017624 0ustar frankfrank#include "dependencies.ih" void dInspectIH(int idx, char const *ihFile) { char *ih = rss_strdup(ihFile); Vector *toDo = VectorCons(); add(toDo, ih); sdep.d_currentGch = rss_strdup(strcatN(2, ih, ".gch")); assign(sdep.d_gchPaths, idx, // create gch file path names strcatN(3, depDir(idx), "/", sdep.d_currentGch)); dCheckUseAll(idx); int next = 0; while (next < vSize(toDo)) // as long as there are files to { // inspect included headers, dInspectFile(idx, toDo, next); // and possibly .d_gch files ++next; } VectorDestructor(toDo); free(sdep.d_currentGch); free(ih); } icmake-9.02.06/dep/dependencies/dtranspose.c0000644000175000017500000000032513176557635017653 0ustar frankfrank#include "dependencies.ih" void dTranspose(int **dest, int **src, int size) { for (int row = 0; row != size; ++row) for (int col = 0; col != size; ++col) dest[col][row] = src[row][col]; } icmake-9.02.06/dep/dependencies/depdir.c0000644000175000017500000000014113176557635016734 0ustar frankfrank#include "dependencies.ih" char const *depDir(int idx) { return at(sdep.d_dirNames, idx); } icmake-9.02.06/dep/dependencies/dshowtable.c0000644000175000017500000000177413176557635017636 0ustar frankfrank#include "dependencies.ih" static void line(int nBlanks, int nMinuses) { if (nBlanks) printf("%*c", nBlanks, ' '); for (int idx = 0; idx != nMinuses; ++idx) putchar('-'); putchar('\n'); } static void numberLine(int size) { for (int col = 0; col != size; ++col) printf("%2d ", col + 1); putchar('\n'); line(0, 20 + size * 3); } void dShowTable(char const *label, int *const *const indices) { printf("\n%s\n", label); int size = sdep.d_size; line(0, 20 + size * 3); printf("%15c depending classes:\n", ' '); line(20, size * 3); printf(" class: "); numberLine(size); for (int row = 0; row != size; ++row) { printf("%15s %2d ", at(sdep.d_dirNames, row), row + 1); for (int col = 0; col != size; ++col) printf(indices[row][col] ? " x " : " "); putchar('\n'); } line(0, 20 + size * 3); printf("%19c", ' '); numberLine(size); putchar('\n'); } icmake-9.02.06/dep/dependencies/inspectcomp.cc0000644000175000017500000000016213176557635020157 0ustar frankfrank#include "dependencies.ih" void inspectComp(Dependencies *dep { dep->inspect; dep->nInspect = 0 } icmake-9.02.06/dep/dependencies/depgchindicator.c0000644000175000017500000000012713176557635020620 0ustar frankfrank#include "dependencies.ih" int *depGchIndicator() { return sdep.d_gchIndicator; } icmake-9.02.06/dep/dependencies/dclosure.c0000644000175000017500000000130613176557635017311 0ustar frankfrank#include "dependencies.ih" void dClosure(int *indicator, int row, int **data, int size) { for (int idx = 0; idx != size; ++idx) // visit row elements { if ( data[row][idx] == 0 // no dep. for element idx || indicator[idx] == 1 // or aloready marked ) continue; // then try the next one indicator[idx] = 1; // dependent on element idx dClosure(indicator, idx, data, size); // add closure of elem. idx } } icmake-9.02.06/dep/dependencies/dihfile.c0000644000175000017500000000015213176557635017073 0ustar frankfrank#include "dependencies.ih" char const *dIhFile(int idx) { return strcatN(2, depDir(idx), optIH()); } icmake-9.02.06/dep/dependencies/dinitable.c0000644000175000017500000000016613176557635017427 0ustar frankfrank#include "dependencies.ih" void dIniTable() { int size = sdep.d_size; sdep.d_dependent = initTable(size); } icmake-9.02.06/dep/dependencies/frame0000644000175000017500000000005713176557635016344 0ustar frankfrank#include "dependencies.ih" Dependencies:: { } icmake-9.02.06/dep/dependencies/dependencies.ih0000644000175000017500000000301513176557635020274 0ustar frankfrank#include "dependencies.h" #include #include #include "../../rss/rss.ih" #include "../util/util.h" #include "../vector/vector.h" #include "../options/options.h" #include "../vector/vector.h" typedef struct { regex_t d_includeRegex; Vector *d_dirNames; // names of directories, first is main's dir. as "." Vector *d_gchPaths; // paths to gch files, from the project's base dir. Vector *d_useAllPaths;// paths to gch files, from the project's base dir. int d_size; int d_gch; // rm old or implied gch files char const *d_useAll; // touch useAll files char *d_currentGch; int *d_gchIndicator; // indicators of gch files to recompile int *d_useAllExists; // indicators of existing useAllFiles int **d_dependent; // X-table of dependencies: the column classes depend // on the row classes. } Dependencies; extern Dependencies sdep; char const *dIhFile(int idx); void dCheckUseAll(int idx); void dClosure(int *indicator, int row, int **data, int size); void dFillTable(); void dFindDependents(); void dHandleInclude(int idx, Vector *toDo, char const *line, char const *hdr); void dImpliedDependencies(int **data, int size); void dIniTable(); void dInspectFile(int idx, Vector *toDo, int toDoIdx); void dInspectGch(int idx, char const *hdr); void dInspectIH(int idx, char const *ihFile); void dReadClasses(); void dShowTable(char const *label, int *const *const indices); void dTranspose(int **dest, int **src, int size); icmake-9.02.06/dep/frame0000644000175000017500000000002313176557635013707 0ustar frankfrank#include "main.ih" icmake-9.02.06/dep/main.c0000644000175000017500000000025613176557635013772 0ustar frankfrank#include "main.ih" int main(int argc, char **argv) { UtilInit(); OptionsCons(argc, argv); DependenciesCons(); ProcessCons(); processActions(); } icmake-9.02.06/doc/0000755000175000017500000000000013232306464012655 5ustar frankfrankicmake-9.02.06/doc/icmake.ps0000644000175000017500000075326213176557635014510 0ustar frankfrank%!PS-Adobe-2.0 %%Creator: dvips 5.516 Copyright 1986, 1993 Radical Eye Software %%Title: ai.dvi %%CreationDate: Tue Mar 1 13:06:35 1994 %%Pages: 53 %%PageOrder: Ascend %%BoundingBox: 0 0 596 842 %%EndComments %DVIPSCommandLine: dvips -o icmake.ps ai %DVIPSSource: TeX output 1994.03.01:1304 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR matrix currentmatrix dup dup 4 get round 4 exch put dup dup 5 get round 5 exch put setmatrix}N /@landscape{/isls true N}B /@manualfeed{ statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]N df-tail}B /E{ pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get} B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 add]{ ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{cc 1 add D }B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore showpage userdict /eop-hook known{eop-hook}if}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 -.1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 -.1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail} B /c{-4 M}B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{ 3 M}B /k{4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{ 3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet TeXDict begin 39158280 55380996 1000 300 300 (/home/karel/latex/ai/1994/1/ai.dvi) @start /Fa 2 63 df<00000400001C000070000380000E0000380001C0000700003C0000F000003800000E 000003C00000F000001C000007800001E000003800000C16137E911B>60 D<800000E000003C000007000001C000007800000E000003800000F000001C0000780001 C0000700003C0000E0000380001E0000700000C0000016137D911B>62 D E /Fb 3 111 df<020002000200C218F2783AE00F800F803AE0F278C2180200020002 000D0E7E8E12>3 D106 D110 D E /Fc 20 122 df<00600000600000F00000 F00000F80001F80001F80003FC0003FC00033C00073E00073E000E1F000E1F000FFF001F FF801C0F801807803807C03807C07003E07003E0F807F014177F9617>65 D69 D<01FC0007FF000FFF801F0FC03E07C03C03E07C03E07801F0F801F0F801F0 F801F0F801F0F801F0F801F0F801F0F801E07C03E07C03C03E07C03F0F801FFF000FFE00 03F80014177E9618>79 D<0FC07FF07FF8707C003C007C03FC0FFC3E3C783CF07CFFFC7F BC3F3E0F0E7F8D12>97 D<07E01FF83E387C387800F800F800F800F800FC007E0C7FFC3F F00FC00E0E7F8D10>99 D<007E001E001E001E001E001E001E001E001E001E001E001E07 DE1FFE3E3E7C1E781EF81EF81EF81EF81EFC1E7E3E7FFE3FDE1F9F101A7F9913>I<07C0 1FF03FF87C78783CFFFCFFFCF800F800F8007C047E0E3FFC0FE00F0E7F8D12>I<0FC03F FE78FEF078F078F078F078F8F07FE07F807FF0FFF8FFFCFFFC401EC00EC00EC00EC00CE0 1C78383FF00FC00F177F8D11>103 D<183C3C180000003C7C3C3C3C3C3C3C3C3C3C3C3C FF0815809409>105 D<7C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CFF 081A809909>108 D<19F000FBF8007FFC007C3C00781E00781E00781E00781E00781E00 781E00781E00781E00781E00FC3F80110E7F8D13>110 D<07E01FF83E7C7C3E7C1EF81F F81FF81FF81F783E7C3E3E7C1FF807E0100E7F8D13>I<19F8FBFC7FFE7C7E783F781F78 1F781F781F781E783E7C7C7FF87BE078007800780078007800780078007800FE0010177F 8D13>I<0F86003FCE007E3E007C1E00F81E00F81E00F81E00F81E00F81E00FC1E007E3E 007FFE003FDE000F9E00001E00001E00001E00001E00001E00001E00001E00001E00003F 8011177F8D13>I<19F0FBF87CF878F8787878007800780078007800780078007C00FE00 0D0E7F8D0E>I<0FF03FF87878780078007FE03FF01FF800FC003CE03CF87CFFF83FE00E 0E7F8D10>I<06001E001E001E001E001E00FFF8FFF81E001E001E001E001E001E001E00 1E001E081F1C0FF803E00E1481930E>I<787EF81E781E781E781E781E781E781E781E78 1E7C3E7FFE3FDE1F9F100E7F8D13>I119 D121 D E /Fd 3 74 df<03E00FF81C1C380C300C70006000E000E000E000E000E000E0007000 700078003C061FFC07E00F137E9211>67 D69 D73 D E /Fe 81 126 df33 DI<0C600C6008400840 084018C018C018C07FF07FF018C018C0108010801080318031803180FFE0FFE031803180 2100210021006300630063000C1C7D9612>I<038007C00E600E600E600E600E600FC007 800F803FC07BCC71CCE1E8E1E8E0F8E0F0E0F0707078F83FB81F1C0E167E9512>38 DI<007001F007800E001C00180030003000600060 006000C000C000C000C000C000C000C000C000C0006000600060003000300018001C000E 00078001F000700C1F7D9712>II<060006000600C630E67070E00B000B0070E0E670C630060006 0006000C0E7D8F12>I<06000600060006000600FFF0FFF0060006000600060006000600 0C0D7D8E12>I<60F0F070606040C0800409788312>III<00300030002000600060004000C000C0018001800180030003000300 0600060006000C000C000C00180018001800300030002000600060004000C000C0000C1F 7D9712>I<0F801FC038E03060707060306038E038E038E038E038E038E038E038E038E0 3060307070306038E01FC00F800D167E9512>I<008003800F803F80F380438003800380 03800380038003800380038003800380038003800380038003800380038009177F9612> I<0F803FC071E060E00070007000700070007000E000E001C001C0038007000E001C0038 006000FFF0FFF0FFE00C167D9512>I<1F807FE060F00070007000700070007000E00F00 0FE000E000700070007000700070007000E0C1E0FFC07F000C167D9512>I<0100038003 00070006000E300C701C70187018703070307070706070E070C070FFFEFFFE0070007000 7000700F167E9512>I<7FE07FE07FE0600060006000600060007F807FC001E000E00070 0070007000700070007000E0C1E0FFC07F000C167D9512>I<07E01FE038007000700060 00E000E7E0EFF0F870F038E038E038E038E038E03860386038707038F01FE00F800D167E 9512>I<7FF8FFF8FFF800380070006000E000C001C00180038003000700070006000E00 0E001C001C001C00380038000D167E9512>I<0FC03FF07838701870187018701878383C 701FE01FE03DF070786038C01CC01CC01CC01C603870783FF00FC00E167E9512>I<0F80 3FC078E07070E030E030E038E038E038E038E078607870F83FB81F380038003000700070 00E03FC03F000D167E9512>I<60F0F060000000000000000060F0F0600410788F12>I<60 F0F060000000000000000060F0F070606040C0800415788F12>I<00180038006001C003 8006001C003800E000E00038001C000600038001C00060003800180D127D9112>II<03C003C003C007E007E006 E006F00C700C700C701C78183818381FFC3FFC301C301C701E600E600EE00FE00F10167F 9512>65 DI<07C01FF03C18780870087000F000E000 E000E000E000E000E000E000E000E00070007000780C3C1C1FF007C00E167E9512>IIII72 DI75 DIII<0FC03FF078787038 703CE01CE01CE01CE01CE01CE01CE01CE01CE01CE01CE01CE01CF038703878783FF00FC0 0E167E9512>II 82 D<1F803FE078E0706070007000700078003C003E001F800FC003E001E000F0007000 70C070C070F0E0FFC01F000C167D9512>IIII<780E380C3C1C1C181E 380E700F60076007C003C003C003E007E006F00EF00C781C78383C381C701E600EE00F10 167F9512>88 D91 DII95 D<3020604040C0E0E0E00409789212>I<0FC07FE070E060 700070007000F003F00F703C707070E070E070F0F07FF03E700C107E8F12>II<0F803FE078607020F000E000E000E000E000E000E0 00F000700078303FE01F800C107D8F12>I<003800380038003800380038003800381FB8 3FF878787038F038E038E038E038E038E038E038F038703878783FF80F380D187E9712> I<0F803FE078707030E018E018FFF8FFF8E000E000E000F0007008781C3FF80FE00E107E 8F12>I<07E00FE01E001C003C00380038003800FFE0FFE0380038003800380038003800 380038003800380038003800380038000B187B9712>I<1F983FF878787038F038E038E0 38E038E038E038E038F038703878783FF80FB800380030007040E07FC07F000D167E8F12 >II<07070707000000FFFF070707070707 070707070707070708177D9612>I<00E000E000E000E00000000000003FE03FE000E000 E000E000E000E000E000E000E000E000E000E000E000E000E001C001C001C00380FF00FE 000B1D7E9612>IIIII<07C01FF038787038 703CE01CE01CE01CE01CE01CE01CF038703878703FE00F800E107E8F12>II<1F983FF878787038F038E038E038E038E038E038E038F0387038 78783FF80FB80038003800380038003800380D167E8F12>II<1FC03FE078607000 700078003E001FC007E000F0007000700070C0F0FFE03F800C107D8F12>I<0C001C001C 001C00FFF8FFF81C001C001C001C001C001C001C001C001C001C001C040E1C07F803E00E 147E9312>IIII<783838303C701EE01EC00FC00780078007C00FC00D E01CE038F030787078E03C0E107E8F12>II<7FF07F F0007000F001E003C007800F000F001E003C007800F000E000FFF0FFF00C107D8F12>I< 01F003F00600060004000C000C000C000C000C000C000C000C001C00F800E00038001C00 1C000C000C000C000C000C000C000E000E000600070003F001F00C1F7D9712>III E /Ff 2 46 df<6006F00FF00FF00FF00FF00F60066006600660066006100B7D9816>34 D45 D E /Fg 31 122 df<1C383C381C38183030206060C0C080 800D087C9412>34 D<003000F003C007800F001E001C003C0038003800700070007000E0 00E000E000E000E000E000E000E000E000700070007000380038001C000E0006000C1E7D 960B>40 D<06000700038001C001C000E000E000E0007000700070007000700070007000 70007000E000E000E001C001C003C0038007800F001E003C00F000C0000C1E81960B>I< 0E0E0E0C0C18102040C0070A80830B>44 DI I<0FE00380038003800300070007000700070007000E000E000E000E000E000E001E001C 001C001C003C003C00FF000B177D960D>73 D84 D<0C08101030306060E0E0E0E0 E0E00D077B9112>92 D<03FC1FFE1C1F180F000F001F00FF07EE1F0E7C0EF01CF07CFF9C 7E1F100E7F8D12>97 D<1F000F000E000E000E001E001E001C001C001C001C003C003CFC 3BFE3E1E380F3807780778077807700E700E701EF87CEFF8C7E0101A7D9914>I<07E01F F83E387C187800F800F000F000F000F000F00078607FC03F000D0E7D8D0F>I<03F00FFC 1C1E380E700E7FFEFFFEE000E000E000F008783C3FF80FC00F0E7D8D12>101 D<007C00FC01CC018003800380078007800700070007000F003FF03FF00E000E000E001E 001E001E001E001C003C003C003C00FE000E1A7F990B>I<03F8000FFFC01F0FC03E0700 3C07003C07003C0F003E1E001FFC001FF0003800003FFC007FFE003FFF00300F00600700 C00700C00700C00600E00E00783C003FF8000FC00012177F8D11>I<07C0000380000380 000380000380000780000700000700000700000700000700000E00000E3E000EFF000F8F 800E07800E07801E07801E07801E07001C07001C0F003C0E003C0E003C0E00FE3F80111A 7F9914>I<0707070000001F3E0E0E0E1E1E1E1C1C1C3C3CFE08147F930A>I<07C00003C0 000380000380000380000780000780000780000700000700000700000F00000F1FC00F0F 000E1C000E78000EE0001FE0001E70001E78001C38001C3C003C1E003C0E003C0F00FE1F C0121A7F9913>107 D<07C003C00380038003800780078007800700070007000F000F00 0F000E000E000E001E001E001E001E001C003C003C003C00FE000A1A7F990A>I<0E3F0F 803EFFBFC00F87E1E00E0380E00E0380E01E0380E01E0380E01E0781E01E0781C01C0701 C01C0701C03C0701C03C0F03C0FE3F8FE01B0E7F8D1E>I<0E3E003EFF000F8F800E0780 0E07801E07801E07801E07001C07001C0F001C0E003C0E003C0E00FE3F80110E7F8D14> I<03F00FFC1C1E380F70077007E007E007E00EE00EF01C78383FF00FC0100E7D8D14>I< 071F801F7FC007C3C00701E00700E00700E00F00E00F00E00E01C00E01C00E03C00F0F80 1DFF001CFC001C00001C00001C00001C0000380000380000380000380000FF0000131780 8D14>I<0EF83FFC0F3C0E1C0E001E001E001E001E001C001C003C003C00FE000E0E7F8D 0E>114 D<03F00FF81E381C001C001E000FE003F000780038E038F078FFF03FC00D0E7F 8D0F>I<06001E001E001C001C001C00FFE0FFE038003800380038003800700070007000 700078C03FC01F000B147E930D>I<7C3EF80E380E380E380E381C781C701C701C701870 1878783FB81F3E0F0E7D8D14>III<1F87E007830003C60003CC0001F80001F000 00F00001F00003F8000738000F3C000E1C003C1E00FE3F80130E808D11>I<3F87F00E01 C00E0180060380070700070E00070E00039C0003B80003B80003F00001E00001E00001C0 000380000380000700000600000E00001C0000180000380000FC000014177F8D12>I E /Fh 65 127 df<00000C0071FC0FF3FC1C370C18360C383E00380E00380E00380E0038 0E00380E00380E00FFFFF0FFFFF0380E00380E00380E00380E00380E00380E00380E0038 0E00380E00380E00380E00FE3F80161A7F9915>11 D<07E0000FF0001C70001800001800 00380000380000380000380000380000380000380000FFFE00FFFE00380E00380E00380E 00380E00380E00380E00380E00380E00380E00380E00380E00FE3F80111A7F9914>I33 D<3E0180630380C1FF00C18200C18600C18C00C18800C198006330003E30000060000040 0000C000018000010000030000061F000631800C60C00860C01860C03060C02060C06060 C0C03180C01F00121A7E9915>37 D<007E0001FF0003C380038180038180038180038180 01C38001CF0000FE0007F8001E701E383818701C10E00E30E00F30E007E0E003E07001C0 7803E03E0EE01FF87007E07C17177E9619>II<018003 8006000C001800180030003000600060006000C000C000C000C000C000C000C000C00060 006000600030003000180018000C00060003800180091E7E960B>II<00400000400000400000400000 4000004000004000004000FFFFC000400000400000400000400000400000400000400000 400000400012127B901B>43 D<60F0F07060606040C08080040B7D830B>III<00060006000C000C0008001800100030002000600040 00C000C001800180030003000600060004000C000800180010003000200060006000C000 C0000F1E7F9611>I<010003000F003F00E7008700070007000700070007000700070007 00070007000700070007000700070007000F807FF00C187D9712>49 D<0F803FE078F070786038603800380078007000F001E003C007800E001C003800300070 006008E008FFF8FFF0FFF00D177E9612>I<1FC07FF07078603860380038003800300060 0F800FE000F00070003800380038003800380030C070E0E0FFC03F000D177E9612>I<00 400000E00000C00001C000018000038000030C00061C00061C000C1C001C1C00181C0038 1C00301C00701C00601C00FFFF80FFFF80001C00001C00001C00001C00007F0011177F96 12>I<7FF07FF07FF0601060106000600060007FC07FE000F00070007800380038003800 3800380070C070E0E0FFC03F000D177E9612>I<03F80FF81C18380030007000600063F0 EFF8F83CF01CF01EE00EE00EE00EE00EE00E600E701C301C38381FF007C00F177E9612> I<60F0F0600000000060F0F060040C7D8B0A>58 D61 D<001800001800003C00003C0000 7E00007E00006E0000EF0000CF0001C7800187800183800383C00303C007FFE00601E00E 01F00C00F00C00F01C00F818007838007CFE00FF1817819617>65 D<01F80007FF000F07801C0380380180300180700000700000E00000E00000E00000E000 00E00000E00000E00000F000007000007000003800003C00C01F03800FFF0003F8001217 7E9615>67 DIII 73 D<3F8007800380038003800380038003800380038003800380038003800380038003 800380038003800380038003800300C700E6007C00091B80960E>I<2000002030000060 380000E0380000E03C0001E03E0003E03E0003E03F0007E037800EE037800CE033C01CE0 31E038E031E030E030F070E03078E0E03038C0E0303DC0E0301F80E0300F00E0300F00E0 300600E0300000E0FC0003F81D177D9623>77 D<2000FC3000303800303C00303E00303F 00303F803037C03033E03031E03030F030307830303C30301E30301F30300FB03007F030 03F03001F03000F0300070300030FC001016177D961B>I<00FC0003FF800F07C01C01E0 3800F0300070700070700038E00038E00038E00038E00038E00038E00038E00038E00070 7000707000607800E03C01C01F07800FFE0001F80015177E9619>I<07E01FF838787018 70007000700078003C003F001F800FE001F000780038001C001C001CC01CE03CF878FFF0 1FC00E177E9612>83 DII87 D<7F00F81E00E00F01C00F018007838003C70003C60001EE0000FC 0000F800007800007800007C0000FE0001CE00038F000307800703800E03C00C01E01800 E03800F0FC03FC16177F9617>I<0E001F00318060C080200B0580950B>94 D<20204040C0E0E0E003087D920A>96 D<0FE07FF0707060380038007801F80FB83E3870 38E038E0F8FFB87E3E0F0E7F8D12>II<0F803FE078E07060E000E000E000E000E000E000700078303FE00F800C0E7E8D0F> I<007C001C001C001C001C001C001C001C001C001C001C001C0FDC3FFC783C701CE01CE0 1CE01CE01CE01CE01C701C783C3FFC1F9F101A7E9914>I<0F803FE078307010F018FFF8 FFF8E000E000E000700078183FFC0FE00E0E7E8D12>I<07C00FC01CC018001800380038 0038003800380038003800FFC0FFC0380038003800380038003800380038003800380038 00FE000A1A7F990B>I<0FC03FFE707EE038E038E038E038F0707FE07F806000FFF0FFF8 7FFC601C400EC006C006C006E00E783C3FF80FE00F177E8D11>II<38383800000038F83838383838383838383838FE07147F930A>I107 DI<18F87E00FBFEFF003E1F8700380E0380380E0380380E0380380E0380380E 0380380E0380380E0380380E0380380E0380380E0380FE3F8FE01B0E7F8D1E>I<18F800 FBFC003E1C00380E00380E00380E00380E00380E00380E00380E00380E00380E00380E00 FE3F80110E7F8D14>I<07E01FF8381C700E6006E007E007E007E0076006700E381C1FF8 07E0100E7E8D14>I<18F8FBFC3C1E380E380738073807380738073807380E3C1E3FFC3B F038003800380038003800380038003800FF0010177F8D14>I<0FCC003FFC00783C0070 1C00E01C00E01C00E01C00E01C00E01C00E01C00701C00787C003FDC001F9C00001C0000 1C00001C00001C00001C00001C00001C00001C00007F8011177E8D14>I<1BE0FFF03CF0 38F0380038003800380038003800380038003800FE000C0E7F8D0E>I<0FC03FE078E070 0070007C003FC00FE000F00070C070F0F0FFE03F800C0E7F8D0F>I<1800380038003800 38003800FFE0FFE03800380038003800380038003800380038003C301FF00FC00C147F93 0D>I<383E00F80E00380E00380E00380E00380E00380E00380E00380E00380E00380E00 3C3E001FFE000FCF80110E7F8D14>IIII I123 DI<7020FC208E2087E081C00B05 80960B>126 D E /Fi 10 58 df<05800BC011C020E060E04070C070C030C030C030C030 C030E020E060706078C03F801E000C127E9011>48 D<047CFC1C1C1C1C1C1C1C1C1C1C1C 1C1C1C1C06127C9111>I<07C00FE030F02070007000700060006000C000C00180030006 000C00080010003FF8FFF80D127F9111>I<0F001F8061C000C000C00080018000000700 1FE001F000F000700070006080E0E1807E000C127E9111>I<00C001C003C006C004C008 C018C010C020C060C0C0C0FFF800E000E000E000E000800D117F9011>I<7FE07FE04000 4000400040005F8061E000E00070007000700070006080E0C1807E000C117E9011>I<00 F003000400180030002000600063C0EFE0F0F0E070E030E030F020706038401F000C117E 9011>I<7FF8FFF000300060004000C0008001000200020004000C000800180030003000 70000D117E9011>I<078018C030603060306038C01F800F000FC031F06078C038C038C0 38E07070E01F800D117E9011>I<078030E06070E030E030E030F02078E03E4000C00180 0100020006000C001C0018000C117E9011>I E /Fj 10 58 df<0F801FC038E070707070 6030E038E038E038E038E038E038E038E03860307070707038E01FC00F800D147E9310> 48 D<0E003E00FE008E000E000E000E000E000E000E000E000E000E000E000E000E000E 000E001F00FFE00B147D9310>I<0F803FE070F0607060700070007000E001C001800700 0C001800300070006000E010FFF0FFF0FFE00C147E9310>I<3F807FE070F04070007000 70007000E00F800FE000E00070007000700070007000F0C1E0FFC07F000C147E9310>I< 0180018003000300060004300C700870187010703070207060704070FFFEFFFE00700070 007001FC0F147F9310>I<7FE07FE07FE060006000600060007F807FC001E000E0007000 7000700070007000E0C1E0FFC07F000C147E9310>I<07E01FE03860700070006000E7C0 EFE0F8F0F070E038E038E038E03860387078707038F01FE00F800D147E9310>I<7FF8FF F8FFF080200060004000C000800180030003000600060006000C000C001C001800380038 000D147E9310>I<0F803FE0787070307030703078703CE01FC01FC039E06070C038C038 C038C038E07870F03FE00F800D147E9310>I<0F803FC078E07070E030E030E038E038E0 38F078707878F83FB81F3800300070007030E03FC03F000D147E9310>I E /Fk 49 122 df<00FC000003FF800007FFC00007FFC0000FE3C0000FE3C0000FC00000 1FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC00000 1FC000001FC00000FFFFFF80FFFFFF80FFFFFF801FC03F801FC03F801FC03F801FC03F80 1FC03F801FC03F801FC03F801FC03F801FC03F801FC03F801FC03F801FC03F801FC03F80 1FC03F801FC03F801FC03F807FF0FFF07FF0FFF01C2781A61C>12 D<387C7C7C7C3C383830306060C0C0060E7C9F0E>39 D<3C7EFFFFFF7F7E3E1E1C1C1838 307060C0C08008137C870F>44 DI<3C7EFFFFFFFF7E3C08 087B8712>I<000600001E00007E0001FE000FFE003FFE00FFFE00F8FE0040FE0000FE00 00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00 00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0001FF00 1FFFF01FFFF014247DA31B>49 D<01FC000FFF003FFF807FFFC07E1FE07C0FE07807F078 07F00007F00007F00007F0000FF0000FE0001FE0003FC0007F80007F0000FE0001FC0003 F00007E0000FC0001F80001F00003E00003E00007C00107C0030FC0030FFFFF0FFFFE0FF FFE0FFFFE0FFFFE0FFFFE014237CA21B>I<03F8003FFF007FFF807FFFC07C3FC0781FE0 700FE0700FE0000FE0000FE0000FC0001FC0001F80003F0003FC0003FE0003FF8003FFC0 001FE0000FE0000FE00007F00007F00007F00007F00007F00007F0000FF0000FE0001FE0 F03FC0FFFF80FFFF00FFFC001FF00014237CA21B>I<00300000003C0000007C00000078 000000F8000000F0000000F0000001F0000001E0180003E0780003C1F80007C3F8000783 F8000783F8000F83F8000F03F8001F03F8001E03F8003E03F8003C03F8003C03F8007803 F8007803F800FFFFFFC0FFFFFFC0FFFFFF80FFFFFF800003F8000003F8000003F8000003 F8000007FC00001FFF00001FFF001A227FA11B>I<7FFFC07FFFC07FFFC07FFFC07FFFC0 7FFFC07800C07800407800407800007800007800007FFC007FFF007FFF807FFFC0003FC0 001FE0000FE0000FF00007F00007F00007F00007F00007F00007F00007F0000FE0000FE0 001FC0F03FC0FFFF80FFFF00FFFC001FF00014237CA21B>I<003FC000FFE003FFE007FF E00FC0001F80001F00003F00003F00007E00007E00007E1F807E7FE0FEFFF0FFFFF0FF87 F8FF03F8FF03FCFE01FCFE01FCFE01FCFE01FCFE01FCFE01FC7E01FC7E01FC7E01FC3E01 F83F03F81F03F01F87F00FFFE007FFC003FF8000FC0016237DA21B>I<7FFFF87FFFF87F FFF87FFFF87FFFF0FFFFE0C001E0C003C0800380000780000700000F00000E00001E0000 3C00003C00007C0000780000F80000F00000F00001F00001E00003E00003E00007E00007 C00007C0000FC0000FC0001FC0001F80001F80003F80003F800015237CA21B>I<0001C0 00000001C000000003E000000003E000000007F000000007F000000007F00000000FF800 00000FF80000001FFC0000001FFC0000001EFC0000003CFE0000003C7E0000007C7F0000 00787F000000787F000000F83F800000F03F800001F03FC00001E01FC00001E01FC00003 FFFFE00003FFFFE00007FFFFF000078007F000078007F0000F8007F8000F0003F8001F00 03FC001E0003FC001E0001FC003E0001FE00FF0003FF80FF0003FF80212380A222>65 DI<000FF000007FFE0001FFFF8003FFFFC007F83FC00FE00FC01FC007C01F8003C0 3F8000003F0000007F0000007F0000007F000000FE000000FE000000FE000000FE000000 FE000000FE000000FE000000FE000000FE000000FE0000007F0000007F0000007F000000 3F8000003F8000C01FC001E01FE003C00FF80F8007FFFF0003FFFE0000FFF800003FC000 1B237EA21F>I69 D73 D75 DI<38000000000E003C00000000 1E003E000000003E003E000000003E003F000000007E003F80000000FE003FC0000001FE 003FE0000001FE003FE0000003FE003FF0000007FE003FF800000FFE003FFC00001FFE00 3FFE00001FFE003FFE00003EFE003DFF00007CFE003CFF8000FCFE003C7FC000F8FE003C 7FE001F0FE003C3FE003E0FE003C1FF007E0FE003C0FF807C0FE003C07FC0F80FE003C07 FE1F00FE003C03FE3F00FE003C01FF7E00FE003C00FFFC00FE003C00FFF800FE003C007F F800FE003C003FF000FE003C001FE000FE003C000FC000FE003C000FC000FE003E000780 00FE00FF80000003FF80FF80000003FF8031237DA238>I<000FF000007FFE0001FFFF80 03FFFFC007F83FE00FE00FF01FC007F01F8003F83F8003F83F0001FC7F0001FC7F0001FC 7E0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FE FE0000FEFE0000FC7F0001FC7F0001FC7F0001F83F8003F83F8003F01FC007F01FE00FE0 0FF83FC007FFFF8003FFFF0000FFFC00001FE0001F237EA223>79 DI<01FF0007FFE00FFFF01FFFF03F83F03F01F07F00007F00007F00007F00007F80 003F80003FC0001FE0001FF8000FFC0007FF0003FF8001FFC0007FE0003FE0001FF0000F F00007F80003F80003F80003F80003F8F003F8F807F0FE0FF0FFFFE0FFFFC03FFF0007FC 0015237EA21A>83 DII<0C0C183830707070F8F8F8F870060D7B9C0E>96 D<00FF000FFFE03FFFF03FFFF83E03F83801FC0001FC0003FC000FFC007FFC01FFFC07FD FC1FE1FC3F81FC7E01FCFC03FCFC0FFCFFFEFC7FFCFC3FF8FF0FE0FF18157F941A>II<007F8003FFF00FFFF81FFFF83FE0F87F8078 7F0000FF0000FE0000FE0000FE0000FE0000FE0000FF00007F00007F80183FE07C1FFFF8 0FFFF003FFC000FE0016157E9418>I<0001FE000001FE000000FE000000FE000000FE00 0000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE00 0000FE000000FE000000FE000000FE0003F8FE000FFEFE001FFFFE003FFFFE007FC1FE00 7F80FE007F00FE00FF00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FF00FE00 7F00FE007F80FE007FC3FE003FFFFE001FFF7E000FFE7F8003F87F8019277EA61D>I<00 FF0003FFE00FFFF01FFFF83FC3F83F81FC7F00FC7FFFFCFFFFFCFFFFFCFE0000FE0000FE 0000FF00007F00007F80083FE07C1FFFFE0FFFFC03FFF000FF0017157E941A>I<007E00 01FF8003FF8007FF8007E3800FE0000FC0000FC0001FC0001FC0001FC0001FC0001FC000 1FC0001FC0001FC0001FC0001FC000FFFF80FFFF80FFFF801FC0001FC0001FC0001FC000 1FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC000 7FF8007FF800112781A611>I<03FE001FFFFE3FFFFE7F07FE7E03FEFC01F8FC01F8FC01 F8FC01F8FC01F87E03F07F07F03FFFE03FFF803BFE007800007FFFC0FFFFF0FFFFF8FFFF FC7FFFFC3800FC70007EF0003EF0003EF0003EF0003EF8003E7C007C7F01FC3FFFF81FFF F007FFC001FF0017227E941A>II<0F001F 801F801F801F800F00000000000000004007C07FC07FC01FC01FC01FC01FC01FC01FC01F C01FC01FC01FC01FC01FC01FC01FC01FC01FC0FFF8FFF80D1F7F9E0E>I107 D<7FC07FC01FC01FC01FC01FC01FC01FC01FC01FC01F C01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01FC01F C01FC01FC01FC01FC01FC01FC01FC01FC0FFF8FFF80D277FA60E>I<0300000000001F07 E01FC000FF1FF87FF000FF3FFCFFF8003F7FFFFFFC003FE1FFC3FC003F80FF01FE003F80 7F00FE003F807F00FE003F807F00FE003F807F00FE003F807F00FE003F807F00FE003F80 7F00FE003F807F00FE003F807F00FE003F807F00FE003F807F00FE003F807F00FE003F80 7F00FE00FFE1FFC3FFC0FFE1FFC3FFC02A167E952B>I<030000001F07C000FF1FF000FF 3FF8003F7FFC003FE1FC003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F 80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE00FFE3FFC0FF E3FFC01A167E951C>I<00FF0003FFC00FFFF01FFFF83FC3FC7F81FE7F00FE7F00FFFE00 7FFE007FFE007FFE007FFE007FFF00FE7F00FE7F81FE3FC3FC1FFFF80FFFF003FFC000FF 0018157E941C>I<030000001F0FE000FF3FF800FF7FFC003FFFFE003FE1FF003F80FF00 3F807F003F807F803F803F803F803F803F803F803F803F803F803F803F807F803F807F00 3F80FF003FC1FF003FFFFE003FFFFC003FBFF8003F8FE0003F8000003F8000003F800000 3F8000003F8000003F8000003F8000003F8000003F8000003F8000003F800000FFF80000 FFF8000019237E951D>I<01F80E000FFE1E001FFF7E003FFFFE007FC1FE007F80FE007F 00FE00FF00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FF00FE007F00FE007F 80FE007FC3FE003FFFFE001FFEFE000FFCFE0003F0FE000000FE000000FE000000FE0000 00FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000003FFE000 03FFE01B227E941D>I<0300001F1FC0FF3FE0FF7FE03FFFE03FC7E03F87E03F87C03F80 003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F8000FFF0 00FFF00013167E9516>I<03FF801FFFF03FFFF07FFFF07F03F07E00007E00003F00003F FF001FFFC00FFFE003FFF00003F00001F80001F8F801F8FE03F8FFFFF8FFFFF0FFFFE00F FF0015157F9418>I<00600007E0000FE0000FE0000FE0000FE0000FE0000FE0000FE000 FFFFE0FFFFE0FFFFE00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE000 0FE0000FE0000FE0000FF00007F83007FFF803FFF801FFE0007F00151E819D15>I<0080 00000F81FE00FF81FE00FF80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80 FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE001FC3FE001FFF 7E000FFF7E0007FE7F8001F87F8019167F951C>II<7FF1FE007FF1FE001FE0F8000FF1F00007F3E00007FBC00003FF800001FF0000 01FF000000FF0000007F800000FFC00001FFC00003FFE00003DFF000078FF8000F87F800 1F03FC003E03FE00FF87FF80FF87FF8019157F941A>120 DI E /Fl 3 63 df<70F8F8F87005057D830C>58 D<000000C0000003C000000E00000038000000E0 0000078000001E00000078000001E00000070000003C000000F00000003C0000000F0000 0003C0000000F00000003C0000000700000001E0000000780000001E0000000780000001 C0000000401A187E951F>60 D62 D E /Fm 44 122 df<003F80000000FFF0000001FFFC000003FFFC000003FFFC 000007F8FC000007F87C000007F00000000FF00000000FF00000000FF00000000FF00000 000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF0000000 0FF00000000FF0000000FFFFFFFC00FFFFFFFC00FFFFFFFC00FFFFFFFC000FF003FC000F F003FC000FF003FC000FF003FC000FF003FC000FF003FC000FF003FC000FF003FC000FF0 03FC000FF003FC000FF003FC000FF003FC000FF003FC000FF003FC000FF003FC000FF003 FC000FF003FC000FF003FC000FF003FC001FF807FE003FFC0FFF803FFC0FFF80212F81AE 21>12 D<0000400001C00007C0001FC0007FC001FFC007FFC01FFFC0FFFFC07F3FC0783F C0203FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003F C0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003FC0003F C0003FC0003FC0003FC0003FC0003FC0007FE001FFF80FFFFF0FFFFF182C7EAB21>49 D<00FF000003FFC0000FFFF0003FFFF8007FFFFC007F07FE007E03FE007C03FF007C01FF 007C01FF000001FF000001FF000001FF000003FE000003FE000007FC000007FC00000FF8 00001FF000003FE000007FC00000FF000001FE000001F8000003F0000007E000000FC000 000F8000001F8000003F0000003F0000007E0001807E0001807E000380FFFFFF80FFFFFF 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFE00FFFFFE00192A7CA921>I<01FF001F FFC07FFFF07FFFF87FFFFC7F07FC7C03FE7803FE7801FE0001FE0001FE0001FE0001FC00 01FC0003F80003F00007E001FF8001FF0001FFC001FFF001FFF80007FC0003FC0001FE00 01FE0000FF0000FF0000FF0000FF0000FF0000FF0001FF0001FE0003FEF007FCFC1FFCFF FFF8FFFFF0FFFFE03FFF8007FC00182A7CA921>I<00180000001F0000001F0000003E00 00003E0000007E0000007C0000007C000000F8000000F8038001F8078001F01F8001F07F 8003F07F8003E07F8003E07F8007C07F8007C07F800FC07F800F807F800F807F801F007F 801F007F803F007F803E007F803E007F807C007F807C007F80FFFFFFFEFFFFFFFEFFFFFF FEFFFFFFFCFFFFFFFC00007F8000007F8000007F8000007F8000007F800000FFE00003FF F00003FFF01F297FA821>I<000038000000003C000000007C000000007E00000000FE00 000000FE00000001FF00000001FF00000001FF80000003FF80000003FF80000007FFC000 0007FFC0000007BFE000000FBFE000000F1FE000001F1FF000001F1FF000003E0FF80000 3E0FF800003E0FFC00007C07FC00007C07FC0000FC03FE0000F803FE0000F801FF0001FF FFFF0001FFFFFF0003FFFFFF8003FFFFFF8007E000FFC007E000FFC007C0007FC00FC000 7FE00F80003FE01F80003FF01F80003FF03F00001FF83F00001FF87F00001FFCFF80003F FEFF80003FFE272A80A929>65 DI<0003FE0000000FFFC000003FFFF00000FFFFFC0001FFFFFE0003FF 03FE0007FC00FE000FF8007E000FF0003E001FF0003E001FE00000003FE00000003FC000 00007FC00000007FC00000007FC00000007F80000000FF80000000FF80000000FF800000 00FF80000000FF80000000FF80000000FF80000000FF80000000FF80000000FF80000000 7FC00000007FC00000007FC00000003FC00000003FE00000001FE00000001FF00003000F F80007800FFC001F8007FF00FF0003FFFFFC0001FFFFF80000FFFFE000003FFF80000007 FC0000212A7DA925>III I<0001FF0000000FFFE000003FFFF80000FFFFFE0001FFFFFF0003FF81FF0007FE007F00 0FFC003F000FF8001F001FF0001F001FF00000003FE00000003FE00000007FC00000007F C00000007FC00000007F80000000FF80000000FF80000000FF80000000FF80000000FF80 000000FF80000000FF8001FFE0FF8001FFE0FF8000FFC0FF80003FC07FC0003FC07FC000 3FC07FC0003FC03FE0003FC03FF0003FC01FF0003FC01FF8003FC00FFC003FC00FFE003F C007FF80FFC003FFFFFFC001FFFFFFC000FFFFFFC0003FFFC7C00007FE07C0232A7DA928 >III75 D<3C00000000000F003E000000 00001F003F00000000001F003F00000000003F003F80000000007F003FC000000000FF00 3FE000000001FF003FE000000001FF003FF000000003FF003FF800000007FF003FFC0000 000FFF003FFE0000000FFF003FFE0000001FFF003FFF0000003FFF003FFF8000007F7F00 3EFFC000007E7F003EFFE00000FC7F003E7FE00001FC7F003E7FF00003F87F003E3FF800 03F0FF003E1FFC0007E0FF003E0FFC000FE0FF003E0FFE001FC0FF003E07FF001F80FF00 3E03FF803F00FF003E01FFC07F00FF003E00FFC0FE00FF003E00FFE0FC00FF003E007FF1 F800FF003E003FF3F800FF003E001FFBF000FF003E000FFFE000FF003E000FFFC000FF00 3E0007FFC000FF003E0003FF8000FF003E0001FF0000FF003E0001FE0000FF003E0000FE 0000FF003E00007C0000FF007F0000000001FF80FFC000000003FFC0FFC000000003FFC0 3A2A7CA943>77 D<3C00001FF83E00001FF83F000007F03F800003E03FC00003E03FC000 03E03FE00003E03FF00003E03FF80003E03FFC0003E03FFE0003E03FFF0003E03FFF8003 E03FFFC003E03EFFC003E03E7FE003E03E7FF003E03E3FF803E03E1FFC03E03E1FFE03E0 3E0FFF03E03E07FF83E03E03FFC3E03E01FFC3E03E00FFE3E03E007FF3E03E003FF3E03E 001FFBE03E001FFFE03E000FFFE03E0007FFE03E0003FFE03E0001FFE03E0000FFE03E00 007FE03E00003FE03E00001FE03E00001FE03E00000FE07F000007E0FFC00003E0FFC000 01E0252A7CA92E>I<0001FE0000000FFFC000003FFFF00000FFFFFC0001FFFFFE0003FF 07FF0007FC01FF800FF800FFC00FF0007FC01FF0003FE01FE0003FE03FE0001FF03FC000 1FF07FC0001FF07FC0001FF07F80000FF87F80000FF8FF80000FF8FF80000FF8FF80000F F8FF80000FF8FF80000FF8FF80000FF8FF80000FF8FF80000FF8FF80000FF0FF80000FF0 7FC0001FF07FC0001FF07FC0001FE07FC0003FE03FE0003FC03FE0007FC01FF0007F801F F800FF800FFC01FF0007FF07FE0003FFFFFC0001FFFFF800007FFFE000001FFF80000003 FC0000252A7DA92B>I<00FF800007FFF8000FFFFE001FFFFE003FFFFE003FE0FE007FC0 3E007F8000007F8000007F8000007F8000007F8000007FC000007FC000003FE000003FF0 00001FFC00001FFE00000FFF800007FFE00003FFF00001FFF800007FFC00001FFE00000F FE000003FF000001FF000000FF800000FF8000007F8000007F8000007F8000007F80F800 7F80FC007F00FE00FF00FF81FF00FFFFFE00FFFFFC007FFFF8000FFFE00001FF8000192A 7DA91F>83 D II<003FC00001FFF0000FFFFC001FFFFE001FFFFF001FFFFF001F81FF801C007F800000 3FC000003FC000003FC00000FFC00007FFC0001FFFC0007FFFC001FF3FC007F83FC01FE0 3FC03F803FC07F003FC0FF007FC0FF81FFC0FFFFDFC0FFFF9FC0FFFF9FE07FFF1FF03FFE 1FF007F800001C1C7E9A20>97 DI<001FE00000FFFC 0003FFFF0007FFFF800FFFFF801FF83F803FE01F803FC00F807F8000007F800000FF8000 00FF000000FF000000FF000000FF000000FF000000FF000000FF0000007F8000007F8000 007FC001803FE007C03FF81FC01FFFFF800FFFFF0007FFFC0001FFF000007F80001A1C7D 9A1D>I<00007FE000007FE000003FE000001FE000001FE000001FE000001FE000001FE0 00001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE0 00001FE000001FE0007E1FE001FF9FE007FFDFE00FFFFFE01FFFFFE03FF87FE03FE01FE0 7FC01FE07F801FE07F801FE0FF801FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0 FF001FE0FF001FE0FF001FE07F801FE07F801FE07FC01FE03FE07FE03FFFFFE01FFFEFF0 0FFFCFF807FF8FF801FE00001D2F7DAD22>I<007FC00001FFF00007FFFC000FFFFE001F FFFF003FE07F003FC03F807FC03F807F801F807F801FC0FFFFFFC0FFFFFFC0FFFFFFC0FF FFFFC0FF000000FF000000FF000000FF000000FF8000007F8000007FC001803FE003C03F F80FE01FFFFFE00FFFFFC007FFFF0001FFFC00003FE0001B1C7D9A20>I<001FE0007FF8 00FFF801FFF803FFF803FC7807F80007F80007F0000FF0000FF0000FF0000FF0000FF000 0FF0000FF0000FF0000FF0000FF0000FF0000FF000FFFFF8FFFFF8FFFFF8FFFFF80FF000 0FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF000 0FF0000FF0000FF0000FF0000FF0000FF0001FF8003FFE003FFE00152F81AE14>I<007F 800003FFF0000FFFFFF01FFFFFF03FFFFFF07FC1FFF07F80FF00FF007F80FF007F80FF00 7F80FF007F80FF007F80FF007F007F80FF007FC1FE003FFFFC001FFFF8001FFFE0001CFF 00003C0000003C0000007FFFFC007FFFFF00FFFFFF80FFFFFFC0FFFFFFC07FFFFFE01FFF FFE038001FF070000FF0700007F0F00003F0F00003F0F00003F0F00003F0F00003E07800 07E07C000FC03F803F801FFFFF000FFFFE0003FFF800007FC0001C2B7D9A1F>II<07800FC01FE01FE01FE00FC007800000000000000000006003E07FE0 FFE07FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE0 1FE01FE01FE03FF0FFFCFFFC0E267FA511>I107 D<7FE07FE03FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01F E01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01FE01F E01FE01FE01FE01FE01FE01FE01FE03FF0FFFCFFFC0E2E7FAD11>I<00C1FE003F800007 C7FFC0FFE000FFCFFFE1FFF000FFDFFFF3FFF8007FDFFFF7FFF8001FFFFFFFFFFC001FFC 1FFF07FC001FF00FFC03FE001FE00FF803FE001FE007F801FE001FE007F801FE001FE007 F801FE001FE007F801FE001FE007F801FE001FE007F801FE001FE007F801FE001FE007F8 01FE001FE007F801FE001FE007F801FE001FE007F801FE001FE007F801FE001FE007F801 FE001FE007F801FE001FE007F801FE003FF00FFC03FF007FF81FFE07FFC07FF81FFE07FF C0321B7F9A33>I<00C0FE0007C7FF80FFCFFFC0FFDFFFE07FDFFFE01FFFFFF01FFC1FF0 1FF00FF81FE00FF81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F8 1FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F83FF00FFC 7FF81FFF7FF81FFF201B7F9A22>I<001FE00000FFFC0003FFFF0007FFFF800FFFFFC01F E0FFE03FC03FE03F801FF07F800FF07F800FF87F0007F8FF0007F8FF0007F8FF0007F8FF 0007F8FF0007F8FF0007F8FF0007F0FF800FF07F800FF07FC00FE03FE01FE03FF83FC01F FFFF800FFFFF0007FFFE0001FFF800003FC0001D1C7D9A22>I<00C1FE0007C7FF80FFCF FFC0FFDFFFE07FFFFFF01FF81FF01FE00FF81FE007F81FE007F81FE003FC1FE003FC1FE0 03FC1FE003FC1FE003FC1FE003FC1FE003FC1FE003FC1FE007FC1FE007F81FE007F81FE0 0FF81FE01FF01FF87FF01FFFFFE01FFFFFC01FEFFF801FE7FE001FE1F8001FE000001FE0 00001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE0 00001FE000003FF800007FFE00007FFE00001E2B7F9A22>I<007E000001FF80E007FFC3 E00FFFE7E01FFFFFE03FF87FE03FE01FE07FC01FE07F801FE07F801FE0FF801FE0FF001F E0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE07F801FE07F801F E07FC03FE03FE0FFE03FFFFFE01FFFFFE00FFFDFE007FF9FE001FE1FE000001FE000001F E000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001F E000001FE000003FF800007FFE00007FFE1F2B7D9A22>I<00C1F807C7FEFFCFFFFFDFFF 7FDFFF1FF8FF1FF0FF1FE0FF1FE0FF1FE07E1FE0001FE0001FE0001FE0001FE0001FE000 1FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0003FF0007FFC007FFC00181B7F 9A1A>I<01FF800007FFF8001FFFFE003FFFFE007FFFFE007FC0FE007F803E007F800000 7F8000007F8000003FC000003FFFC0001FFFF8000FFFFC0007FFFE0000FFFF000003FF00 0000FF0000007F8000007F80F8007F80FE00FF80FF81FF80FFFFFF80FFFFFF00FFFFFE00 3FFFF80003FFC000191C7E9A1D>I<0018000001F8000007F8000007F8000007F8000007 F8000007F8000007F8000007F8000007F80000FFFFFC00FFFFFC00FFFFFC00FFFFFC0007 F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007 F8000007F8000007F8000007F8000007F8000007F8000007F8000007FC020003FE0F0003 FFFF8001FFFF0000FFFE00007FF800000FE000192581A319>I<0060000003E01FF87FE0 1FF8FFE00FF87FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FE0 07F81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FE007F81FF0 0FF81FF83FF80FFFFFF80FFFFBF807FFF3FC03FFE3FE01FFC3FE007F00001F1C7F9A22> I119 D<7FFC1FF07FFC1FF01FF81FC00FF8 3F8007FC3F0007FE7E0003FFFC0001FFF80001FFF80000FFF000007FE000007FE000003F F000003FF000003FF800007FFC0000FFFC0001FBFE0003F3FE0003E1FF0007E0FF800FC0 FF801F807FC03F807FE0FFC0FFF8FFC0FFF81D1A7F991F>II E /Fn 61 124 df<03F80007FE000FFE 000FCE000F8E001F80001F80001F80001F80001F80001F80001F80001F80001F8000FFFF F8FFFFF81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81 F81F81F81F81F81F81F87FE7FE7FE7FE1720809F17>12 D<007FF001FFF803FFF807E1F8 0FC1F80FC1F80F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F8FFFFF8FFFFF8 1F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F81F8 1F81F81F81F87FE7FE7FE7FE1720809F17>I<381C7C3E7C3E7C3E3C1E381C381C301860 306030C0600F0B7E9914>34 D<00C06000C06001C0E001C0E001C0E001C0E00180C00180 C00381C00381C00381C00381C03FFFF83FFFF83FFFF83FFFF80703800703800703800603 000603000E07000E07000E07000E0700FFFFE0FFFFE0FFFFE0FFFFE01C0E001C0E001C0E 00180C00180C00381C00381C00381C00381C00381C0030180030180015297E9E18>I<00 4001E003E007C00F800F001E001E003C003C00780078007800F000F000F000F000F000F0 00F000F000F000F000F0007800780078003C003C001E001E000F000F8007C003E001E000 400B257E9C0E>40 D<4000F000F8007C003E001E000F000F000780078003C003C003C001 E001E001E001E001E001E001E001E001E001E001E003C003C003C0078007800F000F001E 003E007C00F800F00040000B25809C0E>I<003800003800003800003800003800003800 003800003800003800FFFFFCFFFFFCFFFFFC003800003800003800003800003800003800 00380000380000380000380000380016177B941F>43 D<3C7E7E7E7E3C1C1C1818303060 40C0070F7D850D>II<7CFEFEFEFE7C07067C850F>I<03F0 000FFC001FFE003F3F003E1F007E1F807E0F807C0F807C0FC0FC0FC0FC0FC0FC0FC0FC0F C0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0F807C0F807C1F807E1F803E1F 003F3F001FFE000FFC0003F000121D7E9C17>48 D<00180000780001F80007F8001FF800 FFF800F9F80041F80001F80001F80001F80001F80001F80001F80001F80001F80001F800 01F80001F80001F80001F80001F80001F80001F80001F80001F80001F80003FC001FFF80 1FFF80111E7F9D17>I<07F0001FFC007FFE007FFF007C3F00781F80701F80001F80001F 80001F80003F00003F00007E0000FC0001F80003F00007C0000F80001F00001E00003C00 007C0000780080780180FFFF80FFFF00FFFF00FFFF00FFFF00111D7D9C17>I<0FF0007F FC007FFE00787F00703F00703F00003F00003F00003E00007E0000FC0007F00007F80007 FC00007E00003F00003F00001F80001F80001F80001F80001F80003F80003F00F07F00FF FE00FFFC00FFF8001FC000111D7D9C17>I<00C00001E00001E00003C00003C000038000 0781800787800F1F800F1F800E1F801E1F801E1F803C1F803C1F80381F80781F80701F80 F01F80FFFFFCFFFFFCFFFFFC001F80001F80001F80001F80007FE0007FE0161C7F9B17> I<7FFE007FFE007FFE007FFE007FFE007002007002007000007000007000007FF0007FFC 007FFE00007F00003F00003F00001F80001F80001F80001F80001F80001F80001F80003F 00E03F00F07E00FFFC00FFF8001FC000111D7D9C17>I<01FE0007FE000FFE001F8E003F 00003E00007E00007E00007C00007C7E00FDFF00FFFF80FF1F80FE0F80FE0FC0FC0FC0FC 0FC0FC0FC0FC0FC0FC0FC0FC0FC07C0FC07C0F807C0F803C0F003E1F001FFE000FFC0003 F000121D7E9C17>I<7FFFC07FFFC07FFFC07FFF80FFFF80C00700800E00000E00001C00 001C0000380000780000700000F00000E00001E00001C00003C00003C000038000078000 0780000F80000F00001F00001F00001F00003F00003F0000121D7D9C17>I<07F8001FFE 003FFF003F07007E03807E03807E03807E03807E03803F07003F8F001FFE000FF80007FC 001FFE003EFF00783F80701F80E00FC0E00FC0E00FC0E00FC0E00FC0E00FC0701F80783F 803FFF001FFE0007F800121D7E9C17>I<03F0000FFC001FFE003E1F007C0F007C0F80FC 0F80FC0F80FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC0FC07C0FC07E1FC07FFFC03F EFC01F8F80000F80001F80001F80001F00003F001C7E001FFC001FF8001FE000121D7E9C 17>I<00060000000F0000000F0000001F8000001F8000001F8000003FC000003FC00000 7FE0000077E0000077E00000E3F00000E3F00001E3F80001E1F80001C1F80003C1FC0003 C0FC000780FE0007FFFE0007FFFE000F007F000E003F001E003F801E003F803C001FC03C 001FC0FE003FF0FE003FF01C1D809C1C>65 D<007F8001FFF007FFF80FE0FC1F807C3F00 3C3F003C7E00007E00007E0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC00 00FC00007E00007E00007E00003F00003F800C1FE03E0FFFFC07FFF801FFE0007F00171D 7E9C1A>67 D69 DI73 D75 DI<380000000E003C000000 1E003C0000001E003E0000003E003F0000007E003F800000FE003FC00000FE003FC00001 FE003FE00003FE003FF00007FE003FF80007FE003BF8000F7E003BFC001E7E0039FE003E 7E0038FF003C7E00387F80787E00387F80F07E00383FC1F07E00381FE1E07E00380FF3C0 7E003807F7807E003807FF807E003803FF007E003801FE007E003800FC007E0038007C00 7E00380078007E00FE000001FF80FE000001FF80291D7E9C2F>I<38000FE03C000FE03E 0003803F0003803F8003803FC003803FC003803FE003803FF003803FF803803BFC03803B FE038039FF038038FF8380387FC380383FE380381FF380380FFB803807FB803803FF8038 01FF803800FF8038007F8038007F8038003F8038001F8038000F80FE000780FE0003801B 1D7E9C20>I<007F800001FFE00007FFF8000FC1FC001F807E003F003F003F003F007E00 1F807E001F807E000F80FC000FC0FC000FC0FC000FC0FC000FC0FC000FC0FC000FC0FC00 0FC0FC000FC0FC000FC07C001F807E001F807E001F803F003F003F003F001F807E000FE0 FC0007FFF80001FFE000007F80001A1D7E9C1E>II<03FC000FFF801FFF803F0F803E07807E00007E00007E00007E00007F00 003F80003FE0001FF0000FFC0007FE0003FF0000FF80007F80003FC0001FC0000FC0000F C0000FC0F00FC0F01F80FC3F80FFFF003FFE0007F800121D7E9C16>83 DII<7FE01FE07FE01FE00FC00F0007E01E0007F03E0003F03C0003F878 0001FCF00000FDF00000FDE000007FC000007FC000003F8000001F8000001FC000001FE0 00003FE000007BF00000FBF80000F3F80001E1FC0003C1FE0003C0FE000780FF000F007F 800F003F801E003FC0FF007FF0FF007FF01C1D7F9C1D>88 D<03F8001FFE003FFF003FFF 80381F80000FC0000FC0003FC000FFC003FFC00F8FC03E0FC0780FC0F83FC0FFFFC0FFF7 C07FE7E01F87F014127F9116>97 DI<01FC000FFF001FFF803F0F807E07807E0000FC0000FC0000FC00 00FC0000FC0000FE00007E00007F00803F83C01FFF800FFE0003F80012127E9114>I<00 0FE0000FE00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E000 07E00007E007E7E01FF7E03FFFE07F0FE07E07E07E07E0FC07E0FC07E0FC07E0FC07E0FC 07E0FC07E0FE07E07E07E07F0FE03FFBE01FFBF007E3F815207E9F18>I<03F8000FFE00 1FFF003F1F807E0F807E07C0FC07C0FFFFC0FFFFC0FC0000FC0000FC00007E00007F00C0 3F81E01FFFE00FFF8003FC0013127E9116>I<01F803FC07FC0FCC0F800F801F801F801F 801F801F801F801F801F80FFFCFFFC1F9C1F801F801F801F801F801F801F801F801F801F 801F801F801F807FE07FE00E20809F0E>I<07F0001FFFE03FFFE07C1FE0780F80F80F80 F80F80F80F80F80F00FC1F007FFE003FFC003FF0007000007FFF00FFFF80FFFFC07FFFC0 7007E06003E0E001E0E001E0E001E0E001E07003C07C0FC03FFF801FFF0003F800131D7E 9116>II<1C 003E003E003E001C0000000000000001000F00FF00FF003F003F003F003F003F003F003F 003F003F003F003F003F003F00FFC0FFC00A1B7F9A0C>I107 DI<061F01F000FE7FC7FC00FEFFEFFE003F FFFFFE003F87F87F003F03F03F003F03F03F003F03F03F003F03F03F003F03F03F003F03 F03F003F03F03F003F03F03F003F03F03F003F03F03F003F03F03F00FFCFFCFFC0FFCFFC FFC022127F9124>I<061F00FE7FC0FEFFE03FFFE03F87F03F03F03F03F03F03F03F03F0 3F03F03F03F03F03F03F03F03F03F03F03F03F03F0FFCFFCFFCFFC16127F9117>I<01F8 000FFF001FFF803F0FC07E07E07E07E0FC03F0FC03F0FC03F0FC03F0FC03F0FC03F07E07 E07E07E03F0FC01FFF800FFF0001F80014127E9118>I<061F00FE7FC0FEFFE03F87F03F 03F03F03F83F01F83F01F83F01F83F01F83F01F83F01F83F03F03F03F03F87F03FFFE03F 7FC03F3F003F00003F00003F00003F00003F00003F00003F00003F00003F0000FFE000FF E000151D7F9118>I<03F0600FF9E01FFFE03F0FE07E07E07E07E0FC07E0FC07E0FC07E0 FC07E0FC07E0FC07E0FE07E07E07E07F0FE03FFFE01FF7E007C7E00007E00007E00007E0 0007E00007E00007E00007E00007E00007E0001FFC001FFC161D7E9118>I<067EFEFFFF FF3F9F3F1F3F0F3F003F003F003F003F003F003F003F003F003F00FFC0FFC010127F9112 >I<0FFC003FFF807FFF807E0F807C00007C00003E00003FFC001FFF000FFF80001F8000 07C00007C0F007C0FC0FC0FFFF80FFFF001FF80012127F9114>I<00C0000FC0000FC000 0FC0000FC0000FC0000FC000FFFF00FFFF000FC7000FC0000FC0000FC0000FC0000FC000 0FC0000FC0000FC0000FC0000FC0000FC00007E08007FFC003FF8000FE001219819811> I<0100000F07F0FF07F0FF03F03F03F03F03F03F03F03F03F03F03F03F03F03F03F03F03 F03F03F03F03F03F87F01FFFF01FFDF00FFDFC03F1FC16137F9217>III<7FE3F87FE3F80FC3C007E78007FF0003FE0001FE0001FC0000FC0000FE 0001FF0003FF0003DF80079FC00F0FC01E07E0FF1FFCFF1FFC1612809116>II<7FFFC07FFFC07FFFC0601F80603F00007E00 00FC0001FC0003F80007F0000FE0000FC0001F80003F00607E0060FFFFE0FFFFC0FFFFC0 13127F9113>II E /Fo 7 111 df<018001800180018041 82F18F399C0FF003C003C00FF0399CF18F4182018001800180018010127E9215>3 D<0003FE0000000FFF8000003C01E00000F000780001C0001C0003000006000600000300 0C0000018018000000C018000000C0300000006030000000606000000030600000003060 00000030C000000018C000000018C000000018C000000018C000000018C000000018C000 000018C000000018C0000000186000000030600000003060000000303000000060300000 006018000000C018000000C00C000001800600000300030000060001C0001C0000F00078 00003C01E000000FFF80000003FE000025277E9D2A>13 D<03C00FF01FF83FFC7FFE7FFE FFFFFFFFFFFFFFFF7FFE7FFE3FFC1FF80FF003C010107E9115>15 D<003C00E001C00180038003800380038003800380038003800380038003800380038003 0007001C00F0001C00070003000380038003800380038003800380038003800380038003 800380018001C000E0003C0E297D9E15>102 D I106 D110 D E /Fp 73 124 df<000FC0003FF00070F000E07000E00001C00001C00003C00003C000 0380000380000380000780000780001FFFFC1FFFFC07003C07003C0F00380F00780E0078 0E00780E00781E00781E00F81E00F01C00F01C00F01C00F03C01F03C01F0FF07FC16207F 9F19>12 D<000FFE003FFF00781F00F00F01E00F01E00F03C01F03C01E03C01E03801E07 801E07801E07803E07803E1FFFFC1FFFFC07003C0F003C0F007C0F007C0E00780E00780E 00781E00F81E00F81E00F81C00F01C00F01C00F03C01F03C01F0FF07FC18207F9F19>I< 0700078007800F000F000F000F000E000E000E001E001E001C001C001C001C0038003800 38003800000000000000000000006000F000F0006000091D7A9C11>33 D<0E071E0F1E0F0C061C0E180C30186030C06010097B9916>I<000C06000C0600180C00 180C00180C0030180030180030180020100060300060300060300FFFFE0FFFFE0FFFFE01 80C00180C00180C0030180030180030180020100060300060300060300FFFFC0FFFFC0FF FFC0180C00180C00180C00301800301800301800201000603000603000603000C06000C0 6000C0600017297D9E19>I<0001F0000007F800000F0C00001E0600001C0600003C0600 003C0600003C0600003C0C00003C1C00003E7800001FF000007FC00003FF00000FFF807C 1FE780E03F83C0E07E03C0C07C01E1C0F801F1C0F800F380F8007B80F8007F00F8003E00 7C007E007F01FF003FFFEF801FFF8FC007FC07E01E1D7D9C1F>38 D<0E1E1E0C1C183060C007097B990D>I<000C003C00F801E003C007800F000E001E001C 003C0038007800700070007000F000E000E000E000E000E000E000E000E000E000600070 0070007000380038001C001C000E00070002000E257C9C0E>I<0100038001C000E000E0 007000700038003800380018001C001C001C001C001C001C001C001C001C003C00380038 00380078007000F000E001E001C003C007800F001E007C00F000C0000E25819C0E>I<00 6000006000006000006000006000006000006000006000006000006000FFFFF0FFFFF000 60000060000060000060000060000060000060000060000060000060001416789421>43 D<07000F800F800F800F000E000E001C00180030006000C000090C7F840E>II<60F0F0F06004057B840F>I<00000100000300000700000600000C00001C 0000180000300000700000600000C00000C0000180000300000300000600000E00000C00 00180000380000300000600000E00000C0000180000380000300000600000E00000C0000 180000380000300000600000600000C000008000001825809C16>I<001C00FC07FC1FFC 0C7C00780078007800F800F800F000F000F000F001F001F001E001E001E001E003E003E0 03C003C003C007C007C00FE0FFFC0E1D7C9C17>49 D<003F8000FFE003FFF003C3F00781 F80700F80600F80000F80000F80001F00001F00003E00007C0000F80001E00003C0000F0 0001C0000300000600000C00001800003800003000407000C07FFFC0FFFF80FFFF80FFFF 80151D7D9C17>I<007F0003FFC003C3E00781F00700F00600F00600F00000F00001E000 01E00003C0000F8000FC0000FF80000FC00007C00003E00003E00003E00003E00003E000 07E00007C0000FC0001F80E07F00FFFE00FFF8001FE000141D7D9C17>I<000300000380 000700000F00000E00001C00003C000038300070F000E1F000E1E001C1E00381E00381E0 0703E00E03E00E03C01C03C03803C03807C07007C4FFFFFCFFFFF8000780000780000F80 000F80001FC0007FE0161D7E9C17>I<03FFF003FFF003FFF003FFF00700100700000700 000700000600000600000E00000FFE000FFF800007C00003C00003E00001E00001E00001 E00001E00001E00003C00003C0000380000780E00F00F03E00FFF8001FE000141D7D9C17 >I<003FC001FFC003C1C00780C00F00000F00001E00003E00003E00003C7E007DFF007F 0F807E07807C03C0FC03C0F803C0F803C0F803C0F003C0F003C0F00780F00780F0078070 0F00780F00781E003C3C001FF80007C000121D7C9C17>I<00F80007FE000F0F001E0780 3C03803C03807803C07803C07803C0F003C0F003C0F007C0F007C0F007C0F00FC0F00F80 781F807C3F803FF7801F8700000F00000F00001E00001C00003C00C07800F1F000FFE000 FF0000121D7B9C17>57 D<1C3E3E1C00000000000060F0F0F060070F7C8E0D>I<000030 0000007000000070000000F0000000F8000001F8000001F8000003780000077C0000067C 00000E3C00000C3C00001C3C0000383E0000303E0000701E0000601E0000E01F0000FFFF 0001FFFF0003800F0003000F0007000F8006000F800C0007801C000780180007C0380007 C0FE001FF01C1D7F9C1C>65 D<07FFE001FFF801E07C01E03E01C01E01C01E03C01E03C0 1E03C03C03C03C0380780781F007FF8007FFF00780F807807C0F003C0F003E0F003E0F00 3E0F003E0F003E1E007C1E007C1E00FC1E01F83E07F03FFFE0FFFF00171D7C9C1C>I<00 0FE0007FFC01F83F03E01F07C00F0F80071F00061F00003E00003E00003C00007C00007C 0000780000F80000F80000F80000F80000F80000F80000F80000FC00007C00007E00003F 000C3FC07C1FFFF00FFFC003FE00181D7C9C1B>I<07FFFE0001FFFF8001FFFFC001E01F E001E007E001E003F003C001F003C001F803C000F803C000F803C000F807C000F8078000 F8078000F8078000F8078000F00F8001F00F8001F00F0001E00F0003E00F0003C00F0007 C01F0007801F000F001E001E001E003C003E01F0003FFFE000FFFF00001D1D7C9C21>I< 0FFFFE07FFFE03E00203C00203C00003C00003C00007C00007C000078000078000078000 07FFE00FFFE00F80200F80000F80000F00000F00000F00001F00001F00001F00001E0000 1E00081E00183FFFF03FFFF0FFFFF0171D7C9C19>I<0FFFFF07FFFF03E00103E00103E0 0003E00003C00007C00007C00007C00007C0000780000780000F80000FFFE00FFFE00F80 200F00000F00000F00001F00001F00001E00001E00001E00001E00003E00003F0000FF80 00181D7C9C19>I<000FF000007FFE0001F81F0003E00F8007C007800F8003801F000300 1F0000003E0000003E0000003C0000007C0000007C00000078000000F8000000F8000000 F8007F80F8001F00F8001F00F8001F00F8001E00FC001E007C003E007E003E003F003E00 3FC0FC001FFFFC000FFFDC0003FE0C00191D7C9C1D>I<0FF801FF07E000FC03E0007C03 C0007803C0007803C0007803C0007807C000F807C000F8078000F0078000F0078000F007 FFFFF00FFFFFF00F8001F00F8001F00F0001E00F0003E00F0003E00F0003E01F0003E01F 0003E01E0003C01E0007C01E0007C01E0007C03E0007C03F000FE0FF801FF0201D7C9C23 >I<0FF807E003E003C003C003C003C007C007C007800780078007800F800F800F800F00 0F000F000F001F001F001E001E001E001E003E003F00FF800D1D7C9C11>I<0FF80FF007 E003C003E0078003C00F0003C01C0003C0380003C0700007C1E00007C3C00007C7800007 8F0000079E000007BE00000FFF00000FFF00000FEF80000FC780000F8780000F03C0000F 03C0001F01E0001F01E0001F00F0001E00F0001E0070001E0078003E0038003E003C00FF 00FF001C1D7C9C1D>75 D<07FC0001F00001E00001E00001E00001C00003C00003C00003 C00003C00003C00007C0000780000780000780000780000F80000F80000F00000F00000F 00000F00001F00001F00001E00101E00103E00203FFFE0FFFFE0141D7C9C18>I<010000 0006018000000E018000001E03C000001E03C000003C03E000007C03E00000FC03F00001 FC03F00003FC07F80007FC0778000778067C000E78063C001E78063E003C780E1E0078F8 0E1F00F0F80E0F00E0F00C0F81C0F00C078380F00C07C780F01C03CF01F01C03FE01F018 01FC01F01801F801E01800F001E01800E001E038006003E03C000003E0FF00000FF0271D 7C9C2C>I<018000FF01C0003C01C0001C03E0001803F0001803F0001803F8001803FC00 38037E0038073E0030073F0030061F8030060F8070060FC0700607E0600E03F0600E01F0 600C01F8600C00FCE00C007CE01C007EC01C003FC018001FC018000FC018000FC0180007 C0380003803C000380FF000180201D7C9C22>I<0007F000003FFC0000783F0001E00F80 03C007C0078003C00F0003E01F0003E01E0001F03E0001F03E0001F07C0001F07C0001F0 7C0001F0F80001F0F80003E0F80003E0F80003E0F80007C0F80007C0F80007807C000F80 7C000F003C001E003E003C001F0078000FC1E00003FFC00000FE00001C1D7C9C20>I<07 FFF00001FFFC0001E03E0001E01F0001C00F0001C00F8003C00F8003C00F8003C00F8003 C00F0003801F0007801E0007803E0007807C000781F80007FFE0000FFF80000F0000000F 0000000F0000000F0000000F0000001E0000001E0000001E0000001E0000003E0000003F 000000FF800000191D7C9C1C>I<07FFF80001FFFE0001E03F0001E01F8001C00F8001C0 0F8003C00F8003C00F8003C00F8003C01F0003801F0007803E0007807C0007FFF00007FF C000078380000F83C0000F03C0000F01E0000F01E0000F00E0000F00F0001E00F0001E00 78001E0078001E003C003E003C003F001E00FF801F00191D7C9C1D>82 D<001FE000FFFC01E0FC03C03C03801C07800007800007800007800007C00003E00003F0 0001FC0000FE00007F00003F80000FC00007C00003E00001E00001E00001E00001E06001 C0F003C0F80780FE1F007FFE000FF000161D7E9C17>I<7FFFFEFFFFFE803C02803C0200 3C00007C0000780000780000780000780000F80000F00000F00000F00000F00001F00001 F00001E00001E00001E00003E00003E00003C00003C00003C00007C00007C0000FE0003F F000171D7B9C19>IIII<03FC00FE00F80078007800F0007C01E0003C03C0003E038000 1E0700001F0E00000F1E00000FBC00000FB8000007F0000007E0000003E0000003E00000 07E000000EF000001CF000003CF8000078780000F07C0001E03C0001C03E0003801E0007 001E000E001F001C000F003C000F80FF001FE01F1D7F9C1D>II<03FF8003FF800300000700000700000600000600000600000600000E00000C 00000C00000C00000C00001C000018000018000018000018000038000038000030000030 0000300000300000700000600000600000600000600000E00000C00000C00000C00000C0 0000FFE000FFE00011257B9C14>91 D<03FF8003FF800001800001800001800003800003 00000300000300000300000700000600000600000600000600000E00000C00000C00000C 00000C00000C00001C000018000018000018000018000038000030000030000030000030 00007000007000006000006000FFE000FFE0001125809C14>93 D<00FE000FFF001FFF80 1E07801803C00003C00003C0000FC0007FC001FF800FC7803E0780700780E00F00E03F00 FFE7007FC7003F0FC012127D9116>97 D<1FC0000780000780000780000780000780000F 00000F00000F00000F00000F00001F00001E00001E00001E3F801EFFC01FFFE03F83E03E 01F03E00F03E00F03C00F03C00F07C00F07C00E07C01E07801E07803C07807C0FC1F80E3 FF00C1FC0014207C9F19>I<00FC03FF0F0F1E073C073C007C007800F800F800F800F800 F800FC007E0C7FFC3FF00FC010127D9113>I<0000FE00003C00003C00003C00003C0000 3C0000780000780000780000780000780000F00000F00000F003F8F00FFEF01FC3E03F01 E03E01E07C01E07C01E07803E0F803C0F803C0F803C0F803C0F803C0FC03807E0F807FFF 803FFB801FC7E017207D9F19>I<00FC0003FF000FFF801F83803E01C03C01C07801C07F FFC0FFFFC0F80000F80000F80000F800007801007C03803E0F001FFE0007F00012127D91 16>I<001F80007F8000F38000E18001E00001E00003E00003C00003C00003C00003C000 07C00007C0000780001FFE001FFE000780000F80000F80000F00000F00000F00000F0000 1F00001F00001F00001E00001E00001E00003E00003E0000FF800011207F9F0E>I<007E 0003FFFC0787FC0F03E00F01E01E01E01E01E01E01E01E03C01F03C00F87800FFF000DF8 001800003800003FFF007FFF803FFFC03003C06001E0E001E0C001E0C001E0C003C0E007 C0781F803FFF001FFC0007F000161D7F9116>I<07F00001E00001E00001E00001E00001 E00003E00003C00003C00003C00003C00003C00007C00007C0000787E0079FF007FFF00F C0F80F00780F00780F00780E00780E00781E00781E00F81E00F01E00F01C00F01C00F03C 01F03C01F0FF07FC16207E9F19>I<00C001E001E000C0000000000000000003C00FC003 C003C003C00380078007800780078007800F800F000F000F000F001F00FFC00B1A7F990D >I<07F00001E00001E00001E00001E00001E00003C00003C00003C00003C00003C00003 C0000780000780000783F80781F00783C00F0F000F1E000F78000FF8000FFC000F3C001F 3E001E1E001E0F001E0F801E07801E07C03E03C03E03E0FF07F815207E9F17>107 D<03F800F000F000F000F000F001F001E001E001E001E001E003E003C003C003C003C003 C007C007C007800780078007800F800F800F000F000F001F001F00FFC00D207F9F0D>I< 038FE0FC001FBFF3FE0007FFF7FE0007C1FC1F000700F00F000700F00F000F00F00F000E 00E00F000E00E00F000E00E00F000E01E01F001E01E01E001E01E01E001C01C01E001C01 C01E001C03C03E003C03C03E00FF0FF0FF8021127E9125>I<0387E01FBFF007FFF007C0 F80700780700780F00780E00780E00780E00780E00F81E00F01E00F01C00F01C00F01C01 F03C01F0FF07FC16127E9119>I<00FF0003FFC00FC1E01F00F03E00703C00787C00787C 0078F80078F80078F800F0F800F0F800E07801E07C03C03E0F801FFE0007F80015127D91 19>I<00E3F807EFFC01FFFE01F83E01E01F01E00F03E00F03C00F03C00F03C00F03C00E 07C01E07801E07803C07807C07C1F80FBFF00F0FC00F00000F00000F00001F00001F0000 1E00001E00001E00001E00003E0000FFC000181D809119>I<03F8300FFC701FC3F03F01 F03E01E07C01E07C03E07803E0F803E0F803E0F803C0F803C0F807C0FC07C07E1FC07FFF C03FF7801F8780000780000F80000F80000F80000F80000F00000F00001F00001F00001F 00007FE0141D7D9119>I<03BF001FFF80079F80078F800787000700000F00000F00000F 00000F00000F00001F00001E00001E00001E00001E00003E0000FF800011127E9111>I< 01FE0007FF800F0F801E03801E00001E00001F00000FF00007FC0001FE00007F00001F00 000F00E00F00F00F00FC1E00FFFC001FF00011127E9113>I<03000F000F000E000E001E 00FFFCFFFC1E001C003C003C003C003C003C003800780078007800780078107C303FE01F 800E187C9711>I<3C07E0FC01E03C01E03C01C03801C07803C07803C07803C078038070 0380F00380F00780F00780F00700F81F00FFF7007FE7003F8FC013127B9119>III<0FE0FE03E07801E0F001F1E000F3C000FF80007F00007E0000 3E00007E0000FF0001EF0003CF800787800F07C01E03C03E03E0FF07F81712809115>I< 1FE07F07801C07801803803003C03003C06003C0E001E0C001E18001E38001F30000F700 00F60000FC0000FC0000780000700000700000E00000E00001C000018000038000030000 0600000E00000C00001C0000FF0000181D7F9117>I<0FFFC01FFFC0180F80101F00003E 00007E0000FC0001F80001F00003E00007E0000FC0001F80001F01003E01007C0200FFFE 00FFFE0012127F9111>II E /Fq 77 123 df<00000070001E1FF007FE3FF00FFE78701F0EF0701E06F0701E06E0003C01E0003C01 E0003C01E0003C01E0003C01E0003C01E0003C01E000FFFFFF80FFFFFF803C01E0003C01 E0003C01E0003C01E0003C01E0003C01E0003C01E0003C01E0003C01E0003C01E0003C01 E0003C01E0003C01E0003C01E0003C01F000FF07FC001C207F9F1A>11 D<03F80007FE000F1E000E0E001E00001C00001C00003C00003C00003C00003C00003C00 003C00003C0000FFFFE0FFFFE03C01E03C01E03C01E03C01E03C01E03C01E03C01E03C01 E03C01E03C01E03C01E03C01E03C01E03C01E03C01F0FF07FC16207F9F19>I<00FFC003 FFE00783E00F01E00E01E01E01E01C01E03C01E03C01E03C01E03C01E03C01E03C01E03C 01E0FFFFE0FFFFE03C01E03C01E03C01E03C01E03C01E03C01E03C01E03C01E03C01E03C 01E03C01E03C01E03C01E03C01E03C01F0FF07FC16207F9F19>I<000001F000001E3FF0 0007FE7FF0000FFEF870001F0EF030001E06F030001E07E000003C01E000003C01E00000 3C01E000003C01E000003C01E000003C01E000003C01E00000FFFFFFFF00FFFFFFFF003C 01E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01 E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01E0 0F80FF07F83FE023207F9F25>I33 D<6030F078F0787038603060304020C060804080400D 0A7C9916>I<00C06000C06000C0600080400180C00180C00180C00180C00180C00180C0 0100800301803FFFF83FFFF83FFFF8030180020100060300060300060300060300060300 0603000402000C0600FFFFE0FFFFE0FFFFE00C0600080400180C00180C00180C00180C00 180C00180C0010080030180030180030180030180015297E9E19>I<001F0000007FC000 00F8E00000F0600001E0300001E0300001E0300001E0300001F0600000F0E00000FBC000 007F800001FE000007FC00001F9E01F03E0F03807C0F83807807C300F003C300F001E700 F001F600F000FE00F0007C0078003C007C007E003F01FF001FFFEF8007FF87C001FC03F0 1C1D7E9C1F>38 D<60F0F070606040C08080040A7C990D>I<006001E003C007800F000E 001C001C0038003800780070007000F000E000E000E000E000E000E000E000E000E000F0 00700070007000380038001C001C000E000F00078003C001E000600B257E9C0E>II<0030000030000030000030000030000030000030000030000030000030 00FFFFFCFFFFFC0030000030000030000030000030000030000030000030000030000030 0016167A9421>43 D<3078787838303030202060404080050E7C840D>II<60F0F0F06004057B840F>I<0000400000C00000C00001800001800003000003 00000600000600000C00000C00001C0000180000180000300000300000600000600000C0 0000C0000180000180000300000300000700000600000E00000C00000C00001800001800 00300000300000600000600000C0000040000012257F9C16>I<03F0000FFC001E1E003C 0F003807007807807807807003807003C0F003C0F003C0F003C0F003C0F003C0F003C0F0 03C0F003C0F003C0F003C0F003C0F003807003807807807807803807003C0F001E1E000F FC0003F000121D7E9C17>I<004001C003C00FC03FC0F3C043C003C003C003C003C003C0 03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C007E07FFE 0F1E7D9D17>I<07F0001FFC007FFE007C1F00780F007007807007800007800007800007 80000F00000F00001E00003C0000780000E00003C0000700000E00001C00001800003800 00700000700080700080FFFF80FFFF00FFFF00FFFF00111D7D9C17>I<0FF0007FFC0078 3E00701F00600F00600F00000F00000F00000F00000E00001E00007C0007E00007FC0000 1E00000F00000F00000780000780000780000780000780000F80000F00C01F00F07E00FF FC00FFF0001FC000111D7D9C17>I<00300000380000700000700000E00000E00000E000 01C18001C7800387800387800707800707800E07800E07801C07801C0780380780380780 700780700780FFFFF8FFFFF8000780000780000780000780000FC0003FF0151D7F9C17> I<7FFE007FFE007FFE007FFE007002007002007000007000007000007000007000007FF0 007FFC00003E00001F00000F00000F80000780000780000780000780000780000780000F 00C00F00E01E00F07C00FFF8001FC000111D7D9C17>I<01FE0007FE000E0E001C060038 000038000078000070000070000071F800F7FE00FE1F00FC0F80F80780F80780F003C0F0 03C0F003C0F003C0F003C0F003C07003C07003807807803807003C0F001E1E000FFC0003 F000121D7E9C17>I<7FFFC07FFFC07FFF80FFFF80800300800600000600000C00001C00 00180000380000300000700000600000E00000C00001C000018000038000038000070000 0700000F00000F00000E00001E00001E00003E00003C0000121D7D9C17>I<07F8001FFE 003E07003C03007801807801807801807801807801803C03003E06001F9C000FF00003F8 000FFE001E7F00381F80700F806007C0C003C0C003C0C003C0C003C0C003C0600780700F 803C3F001FFE0007F800121D7E9C17>I<03F0000FFC001E1E003C0F00780700780780F0 0380F00380F003C0F003C0F003C0F003C0F003C0F003C07807C07807C07C0FC03E1FC01F FBC007E380000380000380000780000700000700180E001C1C001FF8001FE000121D7E9C 17>I<60F0F06000000000000060F0F0F060040F7C8E0D>I<307878300000000000003078 78783830303020206040408005187D8E0D>I<000200000007000000070000000F800000 0F8000000F8000001FC000001BC000003BE0000031E0000071F0000071F0000060F00000 E0F80000E0780001C07C0001C07C0001803C0003FFFE0003FFFE0007001F0007001F000E 000F800E000F800E000F801C0007C01C0007C03C0007E0FE000FF81D1D809C1C>65 DI<007F8001FFF007C1F80F007C1E 003C3C001C3C001C780000780000780000F00000F00000F00000F00000F00000F00000F0 0000F00000F000007800007800007C00003C00003E00001F00060FC03E07FFF801FFE000 7F00171D7E9C1B>IIII<003FC000 00FFF80003E0FC0007803E000F001E001E000E003C000E003C0000007800000078000000 78000000F0000000F0000000F0000000F0000000F0000000F0007F80F0001F00F0000F00 78000F0078000F007C000F003C000F003E000F001F000F000FC03F0007FFFF0001FFE700 007F8300191D7E9C1D>III75 DI<30000000C030000001C0380000 01C03C000003C03C000003C03E000007C03F00000FC03F00000FC03F80001FC03FC0003F C03BC0003BC03BE00073C039F000F3C038F000E3C038F801C3C0387C03C3C0383C0383C0 383E0703C0381F0F03C0380F8E03C038079C03C03807FC03C03803F803C03801F003C038 01F003C03800E003C038004003C03C000003C0FF00000FF0241D7C9C2C>I<30001FE038 0007803C0003803E0003803E0003803F0003803F8003803FC003803BE0038039F0038039 F8038038F80380387C0380383E0380381F0380380F83803807C3803803E3803803F38038 01F3803800FB8038007F8038003F8038001F8038000F8038000F80380007803C000380FF 0001801B1D7C9C22>I<007F800001FFE00007C0F8000F003C001E001E003C000F003C00 0F00780007807800078078000780F00003C0F00003C0F00003C0F00003C0F00003C0F000 03C0F00003C0F00003C0F00003C07800078078000780780007803C000F003C000F001E00 1E000F003C0007C0F80001FFE000007F80001A1D7E9C1F>II82 D<03FC000FFF801E1F803C07803803807800007800007800007800007C00003E00003F80 001FC0000FF00007FC0001FE00007F00001F80000F800007C00003C00003C00003C0E003 C0F00380F80780FE0F007FFE000FF800121D7E9C17>III87 D<7F800FC01F000F000F801E0007801C0007C03C0003E0780003E0700001F0E00000F8E0 0000F9C000007D8000003F8000003F0000001F0000001F8000001F8000003BC000007BC0 000071E00000E1F00001E0F00003C0780003807C0007003C000F001E000E001E001C000F 003C000F80FE003FE01B1D7F9C1D>I<100830183018603060306030E070F078F0786030 0D0A7C9716>92 D<103030606060E0F0F060040A7C970D>96 D<03FC001FFE003FFF003C 1F00300F80000780000780000F80007F8003F7800F87803E0780780780F00F80F83F80FF F7807FE7801F87E013127E9116>II<07E01FFC3C3C781C780CF000F000F000F000F000F000F800F800 7C007E0E3FFE1FF807E00F127E9112>I<000FC00003C00003C00003C00003C00003C000 03C00003C00003C00003C00003C00003C00003C00003C007E3C01FFBC03F0FC07C03C078 03C07803C0F003C0F003C0F003C0F003C0F003C0F803C0F803C07C03C07E0FC03FFFC01F FBC007E3F014207E9F19>I<03F8000FFE001FFF003E0F007C0780780380FFFF80FFFF80 F00000F00000F00000F00000F800007800007C00803F03C01FFF0007F80012127E9116> I<07F00FF01E701C301C003C003C003C003C003C003C003C003C003C00FFF0FFF03C003C 003C003C003C003C003C003C003C003C003C003C003C003C003E00FF800C207F9F0E>I< 07F0001FFFC03C3FC0781E00700F00F00F00F00F00F00F00F00E00F81E007C3C003FF800 3FE000600000600000FFFC00FFFF007FFF806007804003C0C001C0C001C0C001C0C001C0 400180600380380F001FFE0003F000121D7E9116>II<0C001E001E000C0000000000000002000E007E 005E001E001E001E001E001E001E001E001E001E001E001E001E001E003F00FFC00A1A7F 990D>I<0300078007800300000000000000008003801F80178007800780078007800780 07800780078007800780078007800780078007800780078007800780078007000F000F00 DF00FE00FC00092580990D>II<7E001E001E001E001E001E001E001E001E001E001E001E001E001E00 1E001E001E001E001E001E001E001E001E001E001E001E001E001E001E001E003F00FFC0 0A207F9F0D>I<04000000001C3F01F800FCFFC7FC00BFFFFFFE003F07F83E003C03E01F 003C01E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01E00F003C01E00F00 3C01E00F003C01E00F003C01E00F003C01E00F003C01E00F80FF07F83FE023137E9225> I<0400001C3F00FCFF80BFFFC03F07C03C03E03C01E03C01E03C01E03C01E03C01E03C01 E03C01E03C01E03C01E03C01E03C01E03C01F0FF07FC16137E9219>I<01F8000FFF001E 0F803C03C07801E07801E0F000F0F000F0F000F0F000F0F000F0F000F07801E07801E03C 03C01F07800FFF0001F80014127E9118>I<0400001C7E00FDFF80BFFFC03F07E03C03E0 3C01F03C01F03C00F03C00F03C00F03C00F03C00F03C01E03C01E03C03E03F0FC03DFF80 3C7E003C00003C00003C00003C00003C00003C00003C00003C00003C00003E0000FFC000 141E7E9219>I<07E0C01FF9C03F0FC07C03C07803C07803C0F003C0F003C0F003C0F003 C0F003C0F803C0F803C07C03C07E0FC03FFFC01FFBC007C3C00003C00003C00003C00003 C00003C00003C00003C00003C00003C00003E0000FFC161D7E9119>I<04001CF8FDFCBE 7C3C7C3C7C3C3C3C003C003C003C003C003C003C003C003C003C003E00FF800E137E9211 >I<0FF03FFC7C3C781C780078007C003FE01FF80FFC00FE003E001EE01EF01EFC3CFFF8 1FE00F127E9113>I<06001E001E001E001E001E00FFF8FFF81E001E001E001E001E001E 001E001E001E001E001E001E000F040F8E07FC01F00F187F9710>I<0400001C07E0FC01 E0BC01E03C01E03C01E03C01E03C01E03C01E03C01E03C01E03C01E03C01E03C01E03E01 E01F07E01FFFE00FF9E007E1F815137E9219>III<7F83 F01F03C00F878007870007CE0003FE0001FC0001F80000F80000FC0001FC0003FE00079F 00070F800E07801C03C03C03E0FE0FF81512809115>II<7FFE7FFE403C407800F801F001E003E007C007C00F800F001F003E 013C017803FFFFFFFE10127F9111>I E /Fr 6 110 df73 D<00001FFE0000000003FFFFC00000001FFFFFF0000000FFFFFFFC000003FFFFFFFE0000 07FFFFFFFF000007FFFFFFFF800007FFFFFFFFC00007FFFFFFFFC00007FF807FFFE00007 FC000FFFE00007F00007FFF00007C00003FFF00000000003FFF00000000001FFF8000000 0001FFF80000000001FFF8000000000FFFF8000000003FFFF800000001FFFFF800000007 FFFFF80000003FFFFFF8000000FFFFFFF8000003FFFFFFF800000FFFFDFFF800003FFFE1 FFF800007FFF81FFF80001FFFE01FFF80007FFF001FFF8000FFFC001FFF8001FFF8001FF F8003FFE0001FFF8007FFC0001FFF8007FF80003FFF800FFF80007FFF800FFF8001FFFF8 00FFFC00FE7FF800FFFFFFFE7FF800FFFFFFFC7FF8007FFFFFFC7FF8007FFFFFF87FFC00 3FFFFFF07FFF001FFFFFE07FFF8007FFFF807FFF8001FFFE007FFF00003FF00000000031 2E7DAC36>97 D<00000FFE00000000FFFFE0000007FFFFFC00001FFFFFFF00003FFFFFFF C000FFFFFFFFE001FFFFFFFFE003FFFFFFFFE007FFFE03FFE00FFFF800FFE00FFFE0007F E01FFFC0003FE01FFF80001FE03FFF000000003FFF000000007FFE000000007FFE000000 007FFE00000000FFFE00000000FFFC00000000FFFC00000000FFFC00000000FFFC000000 00FFFC00000000FFFC00000000FFFC00000000FFFC00000000FFFC000000007FFE000000 007FFE000000007FFE000000007FFF000000003FFF000000003FFF800000C01FFFC00001 E01FFFE00007F00FFFF8001FF80FFFFF00FFF807FFFFFFFFF003FFFFFFFFE001FFFFFFFF 8000FFFFFFFF00003FFFFFFC00000FFFFFF0000003FFFF800000007FF800002D2E7CAC32 >99 D<00003FFC00000001FFFFC0000007FFFFF000001FFFFFFC00007FFFFFFE0000FFFF FFFF0001FFFFFFFF8003FFFFFFFFC007FFF80FFFC00FFFE003FFE00FFFC001FFE01FFF80 00FFE01FFF8000FFF03FFF0000FFF03FFF00007FF07FFE00007FF07FFE00007FF87FFFFF FFFFF87FFFFFFFFFF8FFFFFFFFFFF8FFFFFFFFFFF8FFFFFFFFFFF8FFFFFFFFFFF8FFFC00 000000FFFC00000000FFFC00000000FFFC00000000FFFE00000000FFFE000000007FFE00 0000007FFF000000007FFF000000007FFF800000003FFFC00000603FFFE00000F01FFFF0 0003F80FFFFC000FFC0FFFFF807FFE07FFFFFFFFFE03FFFFFFFFFC01FFFFFFFFF000FFFF FFFFC0003FFFFFFF00000FFFFFFC000003FFFFE00000003FFC00002F2E7CAC37>101 D107 D<00038007FC00000FF80000001F803FFF80007FFF000001FF80FFFFE001FFFFC0001FFF 83FFFFF807FFFFE000FFFF87FFFFFC0FFFFFF000FFFF8FFFFFFE1FFFFFF8007FFF9FFFFF FF1FFFFFFC007FFF9FFFFFFF3FFFFFFC0007FFFFFFFFFFBFFFFFFE0007FFFFC1FFFFFF83 FFFE0007FFFE007FFFFC00FFFF0007FFF8003FFFF0007FFF0007FFF0001FFFE0003FFF00 07FFE0001FFFC0003FFF8007FFE0001FFFC0003FFF8007FFE0000FFFC0001FFF8007FFE0 000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFF C0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001F FF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007 FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE000 0FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0 001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF 8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FFE0000FFFC0001FFF8007FF E0000FFFC0001FFF800FFFF0001FFFE0003FFFC07FFFFE00FFFFFC01FFFFFE7FFFFE00FF FFFC01FFFFFE7FFFFE00FFFFFC01FFFFFE7FFFFE00FFFFFC01FFFFFE572D7DAC59>109 D E /Fs 27 118 df<7CFEFEFEFEFE7C0707798616>46 D<000018000000001800000000 3C000000003C000000007E000000007E000000007E00000000FF00000000FF00000001FF 80000001DF80000001DF800000038FC00000038FC00000078FE000000707E000000707E0 00000F03F000000E03F000001E03F800001E01F800001C01F800003C00FC00003800FC00 0078007E00007FFFFE00007FFFFE0000FFFFFF0000F0003F0001F0003F8001E0001F8001 E0001F8003C0000FC003C0000FC007C0000FE007800007E007800007E00F000003F00F00 0003F01F000003F8FFC0000FFFFFC0000FFF282A80A929>65 DI<0003FE0000000FFFC000003FFFF000 00FFFFFC0001FF03FE0003FC00FE0007F0007E000FE0003E000FC0001E001F80001E001F 800000003F000000003F000000007E000000007E000000007E000000007E00000000FC00 000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC0000 0000FC00000000FC000000007E000000007E000000007E000000003F000000003F000000 001F800000001F800000000FC00001000FE000078007F8001F0003FE00FE0001FFFFFC00 00FFFFF000003FFF80000007FC0000212A7CA927>I69 DI73 D75 D<180000000001801C0000000003801C0000000003801E0000000007801F00000000 0F801F000000000F801F800000001F801FC00000003F801FE00000003F801FE00000007F 801FF0000000FF801FF8000000FF801FF8000001FF801EFC000003EF801EFE000003CF80 1E7E000007CF801E7F0000078F801E3F80000F0F801E1F80001E0F801E1FC0001E1F801E 0FE0003C1F801E07F000781F801E07F000781F801E03F800F01F801E01FC01E01F801E01 FC01E01F801E00FE03C01F801E007F07801F801E007F07801F801E003F8F001F801E001F 8E001F801E001FDE001F801E000FFC001F801E0007F8001F801E0007F8001F801E0003F0 001F801E0001E0001F801E0001E0001F801E0000C0001F801F000000001F80FFE0000000 FFF0FFE0000000FFF0342A7BA93F>77 D80 D84 D<003FC00003FFF0000FFFF8003FFFFC003F81FC003E00FE0038007E 0030007F0000003F0000003F0000003F000000FF000007FF00001FFF00007FFF0001FE3F 0007F03F001FC03F003F003F007C003F00F8003F00F8007F00F800DF00FC03DF00FFFF9F 007FFF1FE03FFC1FE00FF000001B1C7D9A20>97 DI< 007F0001FFC007FFF00FFFF81FE1F83F80F83F00787E00787E00007E0000FC0000FC0000 FC0000FC0000FC0000FC0000FC0000FC0000FE00007E00007E00007F00003F80183FE07C 1FFFF80FFFF007FFC000FE00161C7C9A1B>I<00007FC000007FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000FE0FC003FF8FC007FFEFC00F FFFFC01FF07FC03FC01FC03F800FC07F000FC07F000FC07E000FC0FE000FC0FC000FC0FC 000FC0FC000FC0FC000FC0FC000FC0FC000FC0FC000FC0FE000FC07E000FC07E000FC07F 000FC03F801FC03FE0FFC01FFFF7C00FFFE7F807FF87F801FE00001D2F7CAD24>I<007F 800001FFE00007FFF8000FFFFC001FE0FE003F803E003F001F007E001F007E000F807C00 0F80FFFFFF80FFFFFF80FFFFFF80FC000000FC000000FC000000FC000000FC0000007E00 00007E0000007F0000003F8001803FC003801FF01FC00FFFFF8007FFFE0001FFF800007F C0001A1C7C9A20>I<01FE000007FF80001FFFFFC03FFFFFC07F83FFC07E00FFC0FC007C 00FC003E00F8003E00F8003E00F8003E00F8003E00F8007E007C007C007E00FC003F83F8 001FFFF0001FFFC0001DFE00003800000038000000780000007FFFF000FFFFFC00FFFFFE 00FFFFFF007FFFFF001FFFFF8038003F8070000FC0700007C0F00003C0F00003C0F00003 C0F00003C0F00003C0780007807C000F803F807F001FFFFE000FFFFC0003FFF000007F80 001A2B7C9A1F>103 DI<07800FC00FC00FC00FC00780000000 0000000000004003C01FC07FC05FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00F C00FC00FC00FC00FC00FC00FC00FC00FC00FC0FFFCFFFC0E257EA412>I107 D<7FC07FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00F C00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00F C00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0FFFCFFFC0E2E7EAD12>I<0101 FC00070FFF003F1FFF80FF3FFF80BF783FC01FE01FC01F800FE01F800FE01F8007E01F80 07E01F8007E01F8007E01F8007E01F8007E01F8007E01F8007E01F8007E01F8007E01F80 07E01F8007E01F8007E01F8007E01F8007E01F8007E01F8007F0FFF03FFEFFF03FFE1F1B 7D9A23>110 D<001FC00000FFF80003FFFE0007FFFF000FE07F801F801FC03F000FC03E 0007E07E0007E07E0007F07C0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC 0003F0FC0003E0FE0007E07E0007E07E0007C03F000FC03F801F801FE07F000FFFFE0007 FFFC0001FFF000003F80001C1C7C9A23>I<010FC0073FF03F7FF8FF7FF8DFE3F81FC3F8 1F83F81F83F81F81F01F80001F80001F80001F80001F80001F80001F80001F80001F8000 1F80001F80001F80001F80001F80001F80001F8000FFF800FFF800151B7D9A19>114 D<01FE000FFFC01FFFF03FFFF07F07F07E01F07C00F07C00007C00003E00003F00001FE0 000FFF0007FFC000FFE0000FF00001F80000F800007C00007CF0007CF8007CFE00FCFF83 F8FFFFF8FFFFF03FFFC003FF00161C7D9A1B>I<01C0000FC0000FC0000FC0000FC0000F C0000FC0000FC0000FC0000FC000FFFFF0FFFFF0FFFFF00FC0000FC0000FC0000FC0000F C0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000F E00007E00807F01C07F83C03FFF801FFF000FFC0003F0016257FA318>I<008000000780 3FE03F803FE0FF8007E0BF8007E01F8007E01F8007E01F8007E01F8007E01F8007E01F80 07E01F8007E01F8007E01F8007E01F8007E01F8007E01F8007E01F8007E01F8007E01F80 07E01FC007E01FC007E00FE01FE00FF07BE00FFFF3E007FFE3FC03FF83FC00FE00001E1C 7E9A23>I E /Ft 7 117 df<00000000000700000000000000000F80000000000000000F 80000000000000001F80000000000000001F80000000000000003F80000000000000003F C0000000000000007FC000000000000000FFC000000000000000FFC000000000000001FF E000000000000001FFE000000000000003FFE000000000000003FFE000000000000007FF E00000000000000FFFF00000000000000FFFF00000000000001FFFF00000000000001FFF F00000000000003F9FF80000000000003F9FF80000000000007F1FF8000000000000FF1F F8000000000000FE1FF8000000000001FE1FFC000000000001FC0FFC000000000003FC0F FC000000000003F80FFC000000000007F00FFE00000000000FF00FFE00000000000FE007 FE00000000001FE007FE00000000001FC007FE00000000003FC007FF00000000003F8007 FF00000000007F0003FF0000000000FF0003FF0000000000FE0003FF8000000001FE0003 FF8000000001FC0001FF8000000003FC0001FF8000000003F80001FF8000000007F00001 FFC00000000FF00001FFC00000000FE00000FFC00000001FFFFFFFFFC00000001FFFFFFF FFE00000003FFFFFFFFFE00000003FFFFFFFFFE00000007FFFFFFFFFE0000000FF000000 7FE0000000FE0000007FF0000001FE0000003FF0000001FC0000003FF0000003FC000000 3FF0000003F80000003FF8000007F80000001FF800000FF00000001FF800000FF0000000 1FF800001FE00000001FF800001FC00000000FFC00003FC00000000FFC00003F80000000 0FFC00007F800000000FFC0000FF000000000FFE0000FF0000000007FE0001FE00000000 07FE0001FE0000000007FE0003FC0000000007FF0007FC0000000007FF001FFC00000000 0FFF80FFFF800000007FFFF8FFFF800000007FFFF8FFFF800000007FFFF8454A7FC947> 65 D<00FFFFFF00FFFFFF00FFFFFF000FFFF00003FFE00001FFE00001FFC00001FFC000 01FFC00001FFC00001FF800001FF800001FF800003FF800003FF800003FF800003FF0000 03FF000003FF000007FF000007FF000007FE000007FE000007FE000007FE00000FFE0000 0FFE00000FFC00000FFC00000FFC00000FFC00001FFC00001FF800001FF800001FF80000 1FF800001FF800003FF800003FF000003FF000003FF000003FF000003FF000007FE00000 7FE000007FE000007FE000007FE00000FFC00000FFC00000FFC00000FFC00000FFC00000 FFC00001FF800001FF800001FF800001FF800001FF800001FF800003FF000003FF000003 FF000003FF000003FF000007FF000007FF000007FF80000FFFE000FFFFFE00FFFFFE00FF FFFE00204875C729>73 D<0000003FF80000000FFFFE0000007FFFFF800003FFFFFFC000 1FFFFFFFE0003FFFFFFFF0003FFFFFFFF0003FFE01FFF8007FE0007FF8007F80003FF800 7E00001FFC007C00001FFC007000000FFC000000000FFC000000000FFC000000000FFC00 0000000FFC000000000FFC000000007FFC00000003FFF80000001FFFF8000000FFFFF800 0007FFFFF800001FFFFFF80000FFFF1FF80003FFF83FF0000FFFE03FF0003FFF003FF000 FFF8003FF003FFE0003FF00FFF00003FE01FFC00007FE03FF000007FE07FE000007FE07F C00000FFE0FFC00001FFE0FFC00007FFC0FFE0003F7FC0FFF801FE7FC0FFFFFFFC7FC07F FFFFF87FC07FFFFFF0FFE03FFFFFE0FFFC1FFFFF80FFFE07FFFC00FFFE00FFC00000002F 2E7BAC38>97 D<000007FE0000007FFFC00001FFFFF00007FFFFFC000FFFFFFE003FFFFF FF007FFE0FFF00FFF803FF01FFE001FF03FFC000FF03FF8000FE07FF00007E0FFE00001E 0FFE0000001FFC0000001FFC0000003FF80000003FF80000003FF80000007FF00000007F F00000007FF00000007FF0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0 000000FFE0000000FFE0000000FFE0000000FFE0000000FFF00000007FF00000007FF000 00007FF80000003FF80000C03FFC0001E01FFE0007F01FFF807FF00FFFFFFFE007FFFFFF 8003FFFFFE0001FFFFF800007FFFC000000FFC0000282E77AC2E>99 D<00003F0000007F800000FFC00000FFC00000FFC00000FFC00000FFC00000FFC000007F 8000003F0000000000000000000000000000000000000000000000000000000000000000 000000018000003F80000FFF0000FFFF0000FFFF00007FFF000007FF000007FF000007FE 000007FE000007FE000007FE00000FFE00000FFC00000FFC00000FFC00000FFC00000FFC 00001FFC00001FF800001FF800001FF800001FF800001FF800003FF000003FF000003FF0 00003FF000003FF000003FF000007FE000007FE000007FE000007FE000007FE000007FC0 0000FFC00000FFC00000FFC00000FFC00001FFC00003FFE000FFFFFF80FFFFFF80FFFFFF 801A3F7CBE20>105 D<00000FFF00000000FFFFF8000003FFFFFF00000FFFFFFFC0001F FFFFFFC0003FFFFFFFC0007FF80FFFC0007FE001FFC000FFC0007F8000FF80001F8001FF 0000078001FF0000000001FF0000000001FF0000000001FF0000000001FF8000000000FF C000000000FFF0000000007FFE000000007FFFE00000003FFFFC0000001FFFFF0000000F FFFFC0000003FFFFE00000007FFFF000000007FFF800000000FFF8000000003FFC000000 000FFC0000000007FE0000000003FE0000000003FE0000000003FE0000000003FE007800 0003FE007E000007FE007F800007FC007FE0000FFC00FFF8003FF800FFFE00FFF800FFFF FFFFF000FFFFFFFFE0007FFFFFFFC0000FFFFFFF000001FFFFF80000000FFF8000002A2E 7BAC2F>115 D<00003000000001F00000001FF00000003FF00000003FE00000003FE000 00007FE00000007FE00000007FE00000007FC00000007FC00000007FC0000000FFC00000 00FFC0000000FFC0000000FF80000000FF800000FFFFFFFFC0FFFFFFFFC0FFFFFFFFC0FF FFFFFFC0FFFFFFFF8001FF00008003FF00000003FF00000003FF00000003FF00000003FE 00000007FE00000007FE00000007FE00000007FE00000007FC00000007FC0000000FFC00 00000FFC0000000FFC0000000FFC0000000FF80000001FF80000001FF80000001FF80000 001FF80000001FF80000003FF00000003FF00000003FF00000003FF00000003FF0000000 3FF00000003FF00000003FF80008001FF8001C001FFC003E001FFE00FE000FFF83FE000F FFFFFC0007FFFFF80003FFFFE00001FFFF8000007FFE0000001FF00000223E76BC29>I E end %%EndProlog %%BeginSetup %%Feature: *Resolution 300dpi TeXDict begin %%PaperSize: a4 %%EndSetup %%Page: 0 1 0 0 bop 382 255 a Ft(Act)n(a)31 b(Ic)n(cis)302 541 y Fs(The)19 b(ICCE)e(Pr)o(oc)o(eedings)437 996 y Fr(Icmak)o(e)127 1282 y Fs(Fr)o(ank)g(B.)h(Br)o(okk)o(en)f(and)i(K)o(ar)o(el)e(Kubat)542 1686 y Fq(1994-1)p eop %%Page: 1 2 1 1 bop -59 626 a Fp(Act)o(a)16 b(Ic)o(cis)e Fq(is)h(published)f(b)o(y) h(the)h(ICCE)f(\(Int)o(er)o(disciplinar)o(y)h(Centr)o(e)g(for)g(the)-59 676 y(de)o(v)o(elopment)e(of)e(Comput)o(er)i(Coaches)f(and)f(Expert)h (s)o(yst)o(ems\).)-59 843 y(Cop)o(yright)159 842 y(c)148 843 y Fo(\015)i Fq(1994)g(ICCE)h(and)f(the)h(author\(s\))h(of)f(all)f (articles)i(her)o(ein.)27 b(All)-59 893 y(right)o(s)12 b(r)o(eser)o(v)o(ed;)j(r)o(epr)o(oduction)f(in)e(part)i(or)g(in)e (whole)g(without)h(permission)-59 943 y(is)f(pr)o(ohibit)o(ed.)-59 1111 y(ICCE)i(does)g(not)h(mak)o(e)g(any)f(r)o(epr)o(esent)o(ation)j (or)e(warr)o(ant)o(y,)h(e)o(xpr)o(ess)e(or)h(im-)-59 1161 y(plied)j(with)g(r)o(espect)i(t)o(o)g(any)e(c)o(ode)i(or)f(other)h (information)e(her)o(ein.)35 b(ICCE)-59 1211 y(disclaims)14 b(any)h(liabilit)o(y)f(what)o(soe)o(v)o(er)j(for)e(any)f(use)h(of)g (such)f(c)o(ode)j(or)f(other)-59 1260 y(information.)-59 1428 y(All)10 b(c)o(orr)o(espondenc)o(e)j(r)o(egar)o(ding)d(c)o(op)o (yright)o(s,)i(r)o(eprint)o(s)e(or)h(any)f(other)h(matt)o(er)-59 1478 y(c)o(onc)o(erning)i(this)f(public)o(ation)g(c)o(an)h(be)g(dir)o (ect)o(ed)h(t)o(o:)377 1570 y(ICCE)377 1620 y(P)n(.O.)g(Bo)o(x)e(335) 377 1670 y(9700)g(AH)26 b(Gr)o(oningen)377 1719 y(The)13 b(Netherlands)377 1769 y(phone:)k(+31)12 b(50)g(63)g(36)g(36)p eop %%Page: 2 3 2 2 bop -59 -127 a Fn(2)p -24 -127 960 2 v 984 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -10 y Fm(Cont)o(ent)o(s)-59 122 y Fn(ICMAKE)1142 b(5)3 173 y Fq(1)73 b(Intr)o(oduction)13 b(t)o(o)h(ICMAKE)k Fl(:)i(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g (:)h(:)f(:)g(:)g(:)h(:)f(:)63 b Fq(6)99 223 y(1.1)72 b(Legal)12 b(c)o(onsider)o(ations)34 b Fl(:)21 b(:)f(:)g(:)h(:)f(:)g(:) g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)63 b Fq(6)99 273 y(1.2)72 b(Obt)o(aining)11 b(ICMAKE)25 b Fl(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)63 b Fq(7)3 323 y(2)73 b(The)12 b(pr)o(ogr)o(ams)i(of)e(ICMAKE)31 b Fl(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)63 b Fq(7)99 373 y(2.1)72 b(The)12 b(t)o(op-le)o(v)o(el)h(pr)o (ogr)o(ams)42 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)63 b Fq(8)232 423 y(The)12 b(ICMAKE)g(pr)o(ogr)o(am)34 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) 63 b Fq(8)232 473 y(The)12 b(ICMUN)g(pr)o(ogr)o(am)17 b Fl(:)k(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) 40 b Fq(11)99 523 y(2.2)72 b(The)12 b(`dependent')g(pr)o(ogr)o(ams,)i (used)e(int)o(ernally)21 b Fl(:)f(:)h(:)f(:)40 b Fq(13)232 573 y(The)12 b(pr)o(epr)o(oc)o(essor)j(ICM-PP)20 b Fl(:)h(:)f(:)g(:)g (:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(13)232 623 y(The)12 b(c)o(ompiler)i(ICM-COMP)24 b Fl(:)d(:)f(:)g(:)g(:)h(:)f (:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(13)232 674 y(The)12 b(e)o(x)o(ecut)o(or)i(ICM-EXEC)21 b Fl(:)f(:)h(:)f(:)g(:)g(:)h(:)f(:)g (:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(13)99 724 y(2.3)72 b(The)12 b(c)o(alling)g(or)o(der)i(of)e(pr)o(ogr)o(ams)21 b Fl(:)f(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(14)99 774 y(2.4)72 b(Ex)o(ecut)o(able)13 b(mak)o(e\014les)g(under) f(Unix)23 b Fl(:)e(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(14)3 824 y(3)73 b(The)12 b(s)o(ynt)o(ax)h(of)f(the)h(mak)o (e\014le)20 b Fl(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:) g(:)g(:)h(:)f(:)40 b Fq(15)99 874 y(3.1)72 b(Comment)13 b(and)f(pr)o(epr)o(oc)o(essor)j(dir)o(ectiv)o(es)20 b Fl(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(15)232 924 y(The)12 b(#include)g(dir)o(ectiv)o(e)33 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(16)232 974 y(The)12 b(#de\014ne)g(dir)o(ectiv)o(e)22 b Fl(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(16)99 1024 y(3.2)72 b(T)o(ypes,)13 b(c)o(onst)o(ant)o(s)h(and)e(v)o(ariables)30 b Fl(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(17)99 1074 y(3.3)72 b(Strings)11 b(and)h(esc)o(ape)h(sequenc)o(es) 25 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(18)99 1124 y(3.4)72 b(The)12 b(c)o(ode)i(of)e(a)h(mak)o(e\014le)28 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) 40 b Fq(19)232 1174 y(Flow)12 b(c)o(ontr)o(ol)i(st)o(at)o(ement)o(s)27 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(19)232 1225 y(User-de\014ned)11 b(functions)19 b Fl(:)h(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(20)232 1275 y(The)12 b(user-de\014ned)g(function)g(main\(\))k Fl(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(21)99 1325 y(3.5)72 b(Expr)o(essions)11 b(and)h(oper)o(at)o(or)o(s)20 b Fl(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(23)232 1375 y(Logic)o(al)12 b(oper)o(at)o(or)o(s)35 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)40 b Fq(24)232 1425 y(Special)12 b(oper)o(at)o(or)o(s)34 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)40 b Fq(27)232 1475 y(T)o(ype)12 b(c)o(ast)o(s)38 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g (:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(27)99 1525 y(3.6)72 b(Built-in)10 b(functions)24 b Fl(:)c(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(29)232 1575 y(ar)o(ghead)17 b Fl(:)k(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g (:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(29)232 1625 y(ar)o(gt)o(ail)16 b Fl(:)k(:)h(:)f(:)g(:)g(:)h(:)f(:) g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)40 b Fq(29)232 1675 y(ascii)22 b Fl(:)e(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(29)232 1725 y(ascii)22 b Fl(:)e(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(29)232 1776 y(change)p 368 1776 13 2 v 14 w(base)32 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(29)232 1826 y(change)p 368 1826 V 14 w(e)o(xt)30 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:) h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(30)p eop %%Page: 3 4 3 3 bop -59 -127 a Fp(Cont)o(ent)o(s)p 127 -127 1114 2 v 1137 w Fn(3)232 -11 y Fq(change)p 368 -11 13 2 v 14 w(path)32 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:) h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(30)232 40 y(chdir)h Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(30)232 91 y(cmdhead)30 b Fl(:)20 b(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(31)232 142 y(cmdt)o(ail)28 b Fl(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g (:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(31)232 193 y(echo)18 b Fl(:)i(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(32)232 244 y(element\(int,)13 b(list\))39 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)40 b Fq(32)232 295 y(element\(int,)13 b(string\))20 b Fl(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(32)232 346 y(e)o(x)o(ec)26 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:) g(:)h(:)f(:)40 b Fq(33)232 397 y(e)o(x)o(ecut)o(e)28 b Fl(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(34)232 448 y(e)o(xist)o(s)31 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(36)232 499 y(fget)o(s)15 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(36)232 550 y(fprintf)15 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(37)232 601 y(get)p 294 601 V 15 w(base)h Fl(:)20 b(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(37)232 652 y(get)o(ch)d Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(38)232 703 y(get)p 294 703 V 15 w(e)o(xt)e Fl(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g (:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) 40 b Fq(38)232 754 y(get)p 294 754 V 15 w(path)h Fl(:)20 b(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h (:)f(:)g(:)g(:)h(:)f(:)40 b Fq(39)232 805 y(getpid)16 b Fl(:)k(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:) h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(39)232 856 y(get)o(s)29 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(40)232 907 y(mak)o(elist)g Fl(:)20 b(:)g(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(40)232 958 y(mak)o(elist)g Fl(:)20 b(:)g(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(41)232 1009 y(printf)29 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:) g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(41)232 1060 y(put)o(env)c Fl(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:) h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(42)232 1111 y(sizeof)30 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:) g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(42)232 1162 y(sizeo\015ist)c Fl(:)20 b(:)g(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(42)232 1213 y(st)o(at)35 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(42)232 1264 y(strlen)27 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(43)232 1315 y(strlwr)24 b Fl(:)c(:)h(:)f(:)g(:)g(:)h(:)f(:) g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)40 b Fq(43)232 1366 y(strupr)20 b Fl(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g (:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) 40 b Fq(43)232 1418 y(strt)o(ok)25 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(44)232 1469 y(substr)18 b Fl(:)i(:)h(:)f(:)g(:)g(:)h(:)f(:) g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f (:)40 b Fq(44)232 1520 y(s)o(yst)o(em)d Fl(:)21 b(:)f(:)g(:)g(:)h(:)f (:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:) f(:)40 b Fq(44)99 1571 y(3.7)72 b(Pr)o(eloaded)13 b(s)o(ymbols)29 b Fl(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h (:)f(:)40 b Fq(45)3 1622 y(4)73 b(Summar)o(y)24 b Fl(:)d(:)f(:)g(:)h(:) f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h (:)f(:)g(:)g(:)h(:)f(:)40 b Fq(46)3 1673 y(A)68 b(K)o(e)o(ywor)o(ds)18 b Fl(:)j(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:) g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(46)3 1724 y(B)68 b(S)o(ymbolic)11 b(c)o(onst)o(ant)o(s)34 b Fl(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h (:)f(:)g(:)g(:)h(:)f(:)40 b Fq(46)3 1775 y(C)69 b(Binar)o(y)12 b(oper)o(at)o(or)o(s)j Fl(:)20 b(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:) h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(46)3 1826 y(D)63 b(Unar)o(y)12 b(oper)o(at)o(or)o(s)24 b Fl(:)c(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(47)p eop %%Page: 4 5 4 4 bop -59 -127 a Fn(4)p -24 -127 960 2 v 984 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)3 -11 y Fq(E)71 b(T)o(ype)13 b(c)o(ast)o(s)41 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g (:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(47)3 39 y(F)71 b(Oper)o(and)13 b(matrix)32 b Fl(:)20 b(:)g(:)g(:)h(:)f(:)g (:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) 40 b Fq(48)3 89 y(G)67 b(Number)o(s)13 b(and)f(identi\014er)o(s)27 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g (:)h(:)f(:)40 b Fq(48)3 139 y(H)61 b(Esc)o(ape)13 b(sequenc)o(es)30 b Fl(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g (:)h(:)f(:)g(:)g(:)h(:)f(:)40 b Fq(49)p eop %%Page: 5 6 5 5 bop -59 -127 a Fp(ICMAKE)p 124 -127 1117 2 v 1142 w Fn(5)486 606 y Fs(ICMAKE)380 774 y Fq(The)13 b Fn(IC)p Fq(CE)f Fn(MAKE)g Fq(Utilit)o(y)581 823 y(or:)274 873 y(the)h Fn(I)p Fq(mpr)o(o)o(v)o(ed)h Fn(C)p Fq(-lik)o(e)e Fn(MAKE)g Fq(Utilit)o(y)441 923 y(Distribution)g(6.17)303 1091 y(Fr)o(ank)h(B.)f(Br)o(okk)o(en)i(and)e(K.)h(Kubat)p eop %%Page: 6 7 6 6 bop -59 -127 a Fn(6)p -24 -127 960 2 v 984 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -6 y Fm(1)60 b(Intr)o(oduction)17 b(t)o(o)i(ICMAKE)-59 93 y Fq(Welc)o(ome)c(t)o(o)f Fp(icmak)o(e)p Fq(!)19 b Fp(Icmak)o(e)14 b Fq(is)e(a)h(gr)o(oup)g(of)g(pr)o(ogr)o(ams) h(which)e(c)o(onstitut)o(e)-59 143 y(an)j(aut)o(omatic)i(pr)o(ogr)o(am) g(maint)o(enanc)o(e)g(utilit)o(y,)f(c)o(ompar)o(able)h(t)o(o)f(the)g Fp(unix)p Fq(-)-59 193 y(pr)o(ogr)o(am)f Fp(mak)o(e)p Fq(.)23 b(Howe)o(v)o(er,)17 b Fp(icmak)o(e)e Fq(is,)f(in)f(our)h (opinion,)g(mor)o(e)i(`manage-)-59 243 y(able')d(than)g Fp(mak)o(e)p Fq(:)19 b(dependencies)13 b(between)g(\014les)f(and)h (actions)h(t)o(o)g(perform)-59 292 y(c)o(an)i(be)g(st)o(at)o(ed)i(in)d (way)h(which)f(is)g(easily)g(under)o(st)o(ood)i(and)e(quit)o(e)h (`natur)o(al')-59 342 y(t)o(o)g Fn(C)g Fq(pr)o(ogr)o(ammer)o(s.)27 b(Besides)15 b(being)f(a)i(t)o(ool)g(for)g(pr)o(ogr)o(am)h(maint)o(ent) o(anc)o(e,)-59 392 y Fp(icmak)o(e)11 b Fq(has)e(gr)o(own)g(int)o(o)h(a) g(useful)e(shell)g(script)i(language.)15 b(S)o(yst)o(em)9 b(adminis-)-59 442 y(tr)o(ativ)o(e)k(t)o(asks,)g(such)e(as)g(the)h(st)o (arting)g(of)f(backups,)h(c)o(an)h(be)e(ac)o(c)o(omplished)i(b)o(y)-59 492 y Fp(icmak)o(e)g Fq(just)f(as)h(with)f(an)g(other)h(language;)e (but)h(in)g(our)g Fn(C)p Fq(-orient)o(ed)h(opinion)-59 542 y(mor)o(e)h(easily.)-18 596 y(This)j(document)i(is)d(the)i(User)g (Guide)f(t)o(o)i Fp(icmak)o(e)p Fq(.)33 b(The)17 b(pr)o(ogr)o(ams)i(c)o (on-)-59 646 y(stituting)c Fp(icmak)o(e)p Fq(,)k(the)d(s)o(ynt)o(ax)g (of)g(a)h(mak)o(e\014le)g(and)f(se)o(v)o(er)o(al)h(e)o(x)o(amples)f(ar) o(e)-59 695 y(discussed.)f(It)d(is)f(assumed)h(that)h(the)f(r)o(eader)i (is)d(familiar)g(with)h(the)g(c)o(onc)o(ept)o(s)-59 745 y(of)f(a)h(mak)o(e)g(utilit)o(y,)g(with)f(the)h(c)o(onc)o(ept)h(of)e (dependencies)g(between)h(\014les)f(and)-59 795 y(with)h(the)h(c)o(onc) o(ept)i(of)d(aut)o(omatic)j(pr)o(ogr)o(am)f(maint)o(enanc)o(e.)-18 849 y(Furthermor)o(e,)22 b(it)c(is)f(assumed)h(that)g(the)h(r)o(eader)g (is)e(familiar)h(with)f(c)o(on-)-59 899 y(c)o(ept)o(s)g(of)e(pr)o(ogr)o (amming)h(\(such)f(as)h(v)o(ariable)f(de\014nitions,)h(functions,)g(ar) o(gu-)-59 949 y(ment)o(s)e(and)g(r)o(eturn)h(v)o(alues\))f(and)f(with)h (the)g(s)o(ynt)o(ax)g(of)g(the)g Fn(C)g Fq(pr)o(ogr)o(amming)-59 999 y(language.)j(This)12 b(document)i(does)f(not)h(study)e(these)h (themes)h(in)e(depth,)i(but)-59 1049 y(r)o(ather)g(point)o(s)e(out)h (di\013er)o(enc)o(es)h(between)f Fn(C)f Fq(and)g Fp(icmak)o(e)p Fq(.)-18 1103 y Fp(Icmak)o(e)18 b Fq(was)10 b(de)o(v)o(eloped)h(as)e (our)h(answer)g(t)o(o)h(pr)o(oblems)g(e)o(xperienc)o(ed)f(with)-59 1153 y(the)g(mak)o(e)h(utilit)o(y)e(av)o(ailable)h(in)f(UNIX)g(and)h (MS-DOS)e(oper)o(ating)j(s)o(yst)o(em)f(en-)-59 1203 y(vir)o(onment)o(s.)26 b(Initially)14 b(\(that)j(is,)f(aft)o(er)h(the)e (one)h(and)g(a)f(half)g(week)h(it)g(t)o(ook)-59 1252 y(us)c(t)o(o)i(de)o(v)o(elop)g Fp(icmak)o(e)8 b Fq(\))13 b(the)g(pr)o(ogr)o(ams)h(wer)o(e)g(av)o(ailable)f(on)g(MS-DOS)f(s)o (ys-)-59 1302 y(t)o(ems,)f(sinc)o(e)d(the)h(pr)o(ogr)o(ams)h(wer)o(e)f (de)o(v)o(eloped)h(ther)o(e.)16 b(The)9 b Fp(icmak)o(e)g Fq(pr)o(ogr)o(ams)-59 1352 y(wer)o(e)i(then)e(suc)o(c)o(essfully)f (port)o(ed)k(t)o(o)e(UNIX)g(platforms,)h(such)e(as,)h(LINUX)g(and)-59 1402 y(SCO-UNIX.)j(The)i Fp(icmak)o(e)g Fq(pr)o(ogr)o(ams)g(furthermor) o(e)h(also)e(ar)o(e)h(av)o(ailable)f(for)-59 1452 y(HP-UX.)-59 1591 y Fk(1.1)50 b(Legal)16 b(c)o(onsider)o(ations)-59 1676 y Fp(Icmak)o(e)11 b Fq(is)e(shar)o(ewar)o(e.)17 b(This)10 b(means)g(that)h(no)f(fee)g(is)f(char)o(ged)i(for)f(it.)16 b(As)10 b(with)-59 1726 y(e)o(v)o(er)o(ything)g(that's)g(fr)o(ee,)h (ther)o(e's)f(no)g(pay)g(but)f(also)h Fn(absolutely)f(no)h(warranty)p Fq(.)-59 1776 y(Furthermor)o(e,)j(y)o(ou)e(ar)o(e)h(allowed)f(\(and)g (enc)o(our)o(aged\))i(t)o(o)f(distribut)o(e)f Fp(icmak)o(e)p Fq(,)-59 1826 y(pr)o(o)o(vided)i(that)g(y)o(ou)g(include)e(this)h (information)h(with)f(each)h(distribution.)p eop %%Page: 7 8 7 7 bop -59 -127 a Fp(ICMAKE)p 124 -127 1117 2 v 1142 w Fn(7)-18 -11 y Fq(The)13 b(sour)o(c)o(e)g(\014les)f(and)g(the)g (document)o(ation)i(for)f Fp(icmak)o(e)g Fq(ar)o(e)g(c)o(op)o(yright)o (ed)-59 39 y(b)o(y)f(us.)j(The)d(r)o(eason)g(for)g(this)f(is)g(\(a\))i (that)f(we'd)g(lik)o(e)g(t)o(o)h(hav)o(e)e(always)h(the)g(last)-59 89 y(v)o(er)o(sion)h(of)h(Icmak)o(e,)h(and)e(\(b\))h(that)g(we'd)f(lik) o(e)h(t)o(o)g(hav)o(e)g(the)f(last)g(wor)o(d)h(in)f(all)-59 139 y(modi\014c)o(ations.)22 b(If)13 b(y)o(ou)h(hav)o(e)g(r)o(equest)o (s)h(\(or)g(e)o(v)o(en)g(bett)o(er,)h(\\working)e(c)o(ode")-59 188 y(t)o(o)g(include)e(in)h Fp(icmak)o(e)p Fq(\))h(please)f(mail)g(us) f(and)h(we'll)f(gladly)g(oblige)g(when)g(we)-59 238 y(\014nd)g(the)g (time.)-59 366 y Fk(1.2)50 b(Obt)o(aining)16 b(ICMAKE)-59 446 y Fq(The)d Fp(icmak)o(e)h Fq(pack)o(age)f(c)o(an)h(be)e(obt)o (ained)i(b)o(y)e(anonymous)g(ftp)h(fr)o(om)g(the)g(sit)o(e)-59 496 y Fp(beatrix.ic)o(c)o(e.rug.nl)p Fq(,)22 b(dir)o(ect)o(or)o(y)h Fp(pub/unix)p Fq(.)38 b(The)21 b(pack)o(age)g(c)o(omes)h(as)e(an)-59 546 y(ar)o(chiv)o(e,)f(usually)c(in)g(the)i(form)g Fp(icmak)o(e-X.XX.t) o(ar.gz)p Fq(,)i(wher)o(e)e(the)g(curr)o(ent)-59 596 y(v)o(er)o(sion)d(of)g Fp(icmak)o(e)h Fq(is)e(denot)o(ed)i(b)o(y)f Fp(X.XX)679 578 y Fj(1)695 596 y Fq(.)g(This)f(ar)o(chiv)o(e)i(c)o(ont) o(ains)f(a)h(t)o(ar'd)-59 645 y(and)9 b(gzip'd)g(dir)o(ect)o(or)o(y)j (structur)o(e,)g(in)d(which)g(the)h(sour)o(c)o(e)g(\014les)f(for)h Fp(icmak)o(e)h Fq(and)-59 695 y(the)g(e)o(x)o(ecut)o(able)g(pr)o(ogr)o (ams)g(for)g(MS-DOS)e(c)o(an)i(be)f(found.)15 b(The)10 b(same)h(ar)o(chiv)o(e)-59 745 y(sit)o(e)j(also)g(c)o(ont)o(ains)h(the) g(\014le)e Fp(icmak)o(e.doc)p Fq(,)j(which)d(is)g(a)i(guide)e(t)o(o)i (the)f(inst)o(al-)-59 795 y(lation)e(of)h Fp(icmak)o(e)p Fq(.)18 b(This)11 b(\014le)h(is)g(especially)g(useful)f(for)h(UNIX)h (inst)o(allations.)-18 847 y(The)f Fp(icmak)o(e)h Fq(pack)o(age)g(c)o (an)g(also)e(be)h(found)f(at)i(the)f(sit)o(e)g Fp(t)o(s)o(x-11.mit.edu) e Fq(as)-59 897 y(part)i(of)g(the)g(Linux)e(Oper)o(ating)i(S)o(yst)o (em)g(distribution.)j(The)d(\014les)f(ar)o(e)h(usually)-59 946 y(loc)o(at)o(ed)i(in)e Fp(pub/linux/sour)o(c)o(es/usr.bin)o Fq(.)-59 1095 y Fm(2)60 b(The)17 b(pr)o(ogr)o(ams)i(of)f(ICMAKE)-59 1189 y Fp(Icmak)o(e)c Fq(c)o(onsist)o(s)f(of)g(\014v)o(e)f(pr)o(ogr)o (ams)i(which)e(may)h(be)g(nec)o(essar)o(y)h(in)e(the)h(pr)o(o-)-59 1239 y(c)o(ess)j(of)g(r)o(eading)g(a)g(mak)o(e\014le)h(and)e(e)o(x)o (ecuting)h(the)g(c)o(ommands)h(speci\014ed)e(in)-59 1289 y(this)g(\014le.)26 b(The)16 b(pr)o(ogr)o(ams)h(c)o(an)f(be)g(divided)f (in)g(two)h(c)o(at)o(egories:)25 b(pr)o(ogr)o(ams)-59 1339 y(of)12 b(which)g(the)g(c)o(asual)h(user)f(of)g Fp(icmak)o(e)i Fq(must)e(be)g(awar)o(e)i(\(the)f(t)o(op-le)o(v)o(el)g (pr)o(o-)-59 1389 y(gr)o(ams\))g(and)f(pr)o(ogr)o(ams)i(which)e(ar)o(e) h(c)o(alled)g(int)o(ernally)f(b)o(y)g Fp(icmak)o(e)p Fq(.)-18 1441 y(Each)i(of)f(the)g(pr)o(ogr)o(ams)h(of)e(the)i Fp(icmak)o(e)g Fq(family)e(has)g(it)o(s)h(v)o(er)o(sion)g(number.)-59 1491 y(The)k(v)o(er)o(sion)f(number)o(s)h(c)o(onsist)f(of)h(a)g(major)g (and)g(a)f(minor)h(number;)h(e.g.,)-59 1540 y(in)f(the)i(v)o(er)o(sion) g(number)f(5.03,)h(the)g(major)h(v)o(er)o(sion)e(is)g(5)g(and)g(the)g (minor)-59 1590 y(v)o(er)o(sion)d(is)f(03.)24 b(The)16 b(pr)o(ogr)o(ams)g(c)o(an)f(only)g(c)o(ommunic)o(at)o(e)j(when)c(the)h (major)-59 1640 y(v)o(er)o(sion)c(number)o(s)g(of)g(all)f Fp(icmak)o(e)i Fq(pr)o(ogr)o(ams)h(ar)o(e)f(equal:)j(i.e.,)c(a)h (working)e(set)-59 1690 y(of)k(pr)o(ogr)o(ams)i(must)e(hav)o(e)h(the)g (same)g(major)g(v)o(er)o(sion)g(number.)23 b(The)14 b(minor)-59 1740 y(number)e(is)f(used)g(t)o(o)i(indic)o(at)o(e)f(small)g(changes)f (in)g(the)h(separ)o(at)o(e)i(pr)o(ogr)o(ams.)p -59 1786 534 2 v -18 1814 a Fi(1)1 1826 y Fh(Jok)o(e)9 b(of)g(the)h(day:)j Fg(\\The)d(last)g(v)o(er)o(sion)g(if)g(icmak)o(e)g(is)g(bug-fr)o(ee.")p eop %%Page: 8 9 8 8 bop -59 -127 a Fn(8)p -24 -127 960 2 v 984 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fk(2.1)50 b(The)16 b(t)o(op-le)o(v)o(el)g (pr)o(ogr)o(ams)-59 69 y Fq(T)o(wo)d(pr)o(ogr)o(ams)g(of)f(the)g Fp(icmak)o(e)h Fq(gr)o(oup)f(form)h(the)f(int)o(erfac)o(e)h(t)o(o)g (the)g(user:)j Fp(ic-)-59 119 y(mak)o(e)11 b Fq(it)o(self)e(and)g Fp(icmun)p Fq(.)15 b(The)10 b(`dependent')f(pr)o(ogr)o(ams)i(ar)o(e)f (gener)o(ally)f(c)o(alled)-59 168 y(b)o(y)18 b(the)h(t)o(op-le)o(v)o (el)g(pr)o(ogr)o(ams)g(as)g(child-pr)o(oc)o(esses)f(or)h(o)o(v)o (erlay-pr)o(oc)o(esses.)-59 218 y(Howe)o(v)o(er,)d(e)o(v)o(er)o(y)e (dependent)f(pr)o(ogr)o(am)i(is)e(a)g(c)o(omplet)o(e)j(pr)o(ogr)o(am)e (b)o(y)g(it)o(self,)-59 268 y(and)e(c)o(ould)h(as)f(well)g(be)h(activ)o (at)o(ed)h(b)o(y)f(user)o(s)f(of)g Fp(icmak)o(e.)-59 384 y Fn(The)h(ICMAKE)f(program)-59 464 y Fq(The)d(main)f(pr)o(ogr)o (am)i(is)e Fp(icmak)o(e)474 446 y Fj(2)491 464 y Fq(.)15 b(The)9 b Fp(icmak)o(e)h Fq(pr)o(ogr)o(am)g(act)o(s)f(as)g(an)f(int)o (erfac)o(e)-59 514 y(between)i(the)g(user)g(and)f(other)i(pr)o(ogr)o (ams)f(of)g(the)g Fp(icmak)o(e)h Fq(gr)o(oup.)k(Normally,)-59 564 y(the)g(user)g(will)f(hav)o(e)h(no)g(need)g(t)o(o)h(know)f(the)g(e) o(x)o(act)h(names)f(or)h(functions)e(of)-59 613 y(the)f(other)h Fp(icmak)o(e)g Fq(pr)o(ogr)o(ams;)f(only)f(the)h(`t)o(op)h(le)o(v)o (el')f(pr)o(ogr)o(am)h(will)e(hav)o(e)g(t)o(o)-59 663 y(be)g(activ)o(at)o(ed)j(t)o(o)f(st)o(art)f(the)g(pr)o(oc)o(ess)h(of)e (making.)-18 715 y(The)g Fp(icmak)o(e)h Fq(pr)o(ogr)o(am)h(is)d (normally)h(inv)o(ok)o(ed)g(b)o(y)g(one)g(of)g(the)g(two)g(follow-)-59 765 y(ing)f(c)o(ommand)j(lines:)84 864 y Fp(icmak)o(e)27 b([\015ags])d(ascii\014le)g([binar)o(y\014le])i([)p Ff(--)f Fp(ar)o(gument)o(s])222 914 y(icmak)o(e)h([\015ags])f(-i)12 b(ascii\014le)24 b([ar)o(gument)o(s])-59 1012 y Fq(The)14 b(two)g(inv)o(oc)o(ation)h(modes)f(di\013er)g(in)e(the)i(fact)h(that)f (the)g(\014r)o(st)g(inv)o(oc)o(ation,)-59 1062 y(without)i(the)h Fp(-i)e Fq(\015ag,)i(allows)e(the)i(user)f(t)o(o)h(specify)e(the)h (name)h(of)f(a)g(binar)o(y)-59 1111 y(\014le.)k(This)14 b(\014le)f(is)g(an)h(int)o(ermediat)o(e)i(\014le)d(in)h(the)g(making)f (pr)o(oc)o(ess.)22 b(The)15 b(sec-)-59 1161 y(ond)h(inv)o(oc)o(ation)i (allows)e Fp(icmak)o(e)h Fq(t)o(o)h(choose)f(a)g(name)f(for)h(the)g (binar)o(y)f(\014le.)-59 1211 y(When)10 b(not)h(speci\014ed,)g Fp(icmak)o(e)h Fq(uses)d(the)i(name)g(of)f(the)h(ascii\014le)f(but)g (with)g(the)-59 1261 y(e)o(xt)o(ension)i Fp(.bim)p Fq(.)-18 1312 y(In)h(both)i(c)o(ommand)g(lines,)e(the)i Fp(\015ags,)e Fq(or)h(the)h(two)f(c)o(onsecutiv)o(e)h(hyphens)-59 1362 y(and)i(the)g(ar)o(gument)o(s)h(ar)o(e)h(optional.)31 b(The)17 b(ar)o(gument)o(s)h(ar)o(e)g(passed)f(t)o(o)h(the)-59 1412 y(mak)o(e\014le)c(and)g(c)o(an)g(be)g(inspect)o(ed)f(ther)o(e.)22 b(The)13 b(\015ags)g(ar)o(e)i(used)d(for)i(r)o(equest-)-59 1462 y(ing)g(speci\014c)i(actions)g(of)g Fp(icmak)o(e)p Fq(.)27 b(The)16 b(speci\014c)o(ation)h(of)e(the)h(ascii\014le)f(is)g (in)-59 1512 y(both)f(inv)o(oc)o(ations)h(obligat)o(or)o(y:)20 b(this)13 b(\014le)h(is)f(the)i(mak)o(e)g(script,)g(which)e(is)h(in-) -59 1561 y(t)o(erpr)o(et)o(ed)f(b)o(y)d Fp(icmak)o(e)h Fq(and)f(ac)o(c)o(or)o(ding)i(t)o(o)f(which)e(speci\014c)h(actions)h (ar)o(e)g(t)o(ak)o(en.)-18 1613 y(When)i Fp(icmak)o(e)h Fq(is)e(activ)o(at)o(ed)i(without)f(any)g(ar)o(gument)o(s,)g(a)g(help)f (summar)o(y)-59 1663 y(is)i(display)o(ed,)g(showing)f(among)i(other)g (things)e(the)i(\015ags)f(which)g(ar)o(e)h(r)o(ec)o(og-)p -59 1707 534 2 v -18 1735 a Fi(2)1 1747 y Fh(Under)e(MS-DOS,)j(all)f (pr)o(ogr)o(ams)f(of)h(the)f Fg(icmak)o(e)h Fh(gr)o(oup)g(hav)o(e)f(e)o (xt)o(ension)g Fg(e)o(x)o(e)p Fh(.)28 b(In)15 b(this)-59 1786 y(document)9 b(the)i(e)o(xt)o(ension)e(of)i(e)o(x)o(ecut)o(ables)f (is)g(left)h(out,)g(sinc)o(e)f(other)g(oper)o(ating)h(s)o(yst)o(ems)g (than)-59 1826 y(DOS)g(may)e(r)o(equir)o(e)h(other)f(e)o(xt)o(ensions)g (or)g(may)h(r)o(equir)o(e)g(no)f(e)o(xt)o(ensions)f(at)i(all.)p eop %%Page: 9 10 9 9 bop -59 -127 a Fp(ICMAKE)p 124 -127 1117 2 v 1142 w Fn(9)-59 -11 y Fq(nized)18 b(b)o(y)g Fp(icmak)o(e)p Fq(.)36 b(When)18 b Fp(icmak)o(e)i Fq(is)e(st)o(art)o(ed)i(without)e (any)g(ar)o(gument)o(s,)-59 39 y(something)12 b(lik)o(e)h(the)f (following)f(output)i(appear)o(s)g(on)g(the)g(scr)o(een)1074 21 y Fj(3)1090 39 y Fq(:)-59 114 y Fe(ICCE)k(Make)g(Utility)f(Version)g (6.00)-59 154 y(Copyright)g(\(c\))h(ICCE)g(1992,)f(1993.)35 b(All)17 b(rights)f(reserved.)-59 233 y(Usage:)g(ICMAKE)h([flags])f (source[.im])f([dest[.bim]])g([--)j([args]])-59 272 y(where:)83 311 y(flags:)34 b(optional)16 b(flags:)225 351 y(-b)89 b(:)17 b(blunt)g(execution)f(of)h(the)g(destinationfile)225 390 y(-c)89 b(:)17 b(the)g(destination)f(file)h(is)g(compiled)225 430 y(-o)h(file:)e(all)h(icmake)g(output)f(is)i(redirected)d(to)j (`file')225 469 y(-i)g(file:)e(define)h(input)f(file,)h(argument)f (processing)g(stops)225 509 y(-p)89 b(:)17 b(only)g(the)g(preprocessor) e(is)j(activated)225 548 y(-q)89 b(:)17 b(quiet)g(mode:)g(copyright)e (banner)i(not)g(displayed)83 588 y(source:)f(make)h(description)f (source)g(file)225 627 y(\(default)g(extension:)g(.im\))83 666 y(dest:)52 b(binary)17 b(make)g(file)225 706 y(\(default)f (filename:)34 b(source.bim\))83 745 y(--)18 b(:)53 b(optional)16 b(icmake-file)f(arguments)h(separator)83 785 y(args:)35 b(optional)16 b(arguments)f(following)h(--)h(received)f(by)208 824 y(the)h(icmake)f(file)h(in)g(its)g(argv-list)-59 955 y Fq(Fr)o(om)c(this)f(help-summar)o(y)g(it)h(is)e(seen)h(that)i (the)e(following)f(\015ags)h(ar)o(e)h(r)o(ec)o(og-)-59 1005 y(nized:)-59 1091 y Fn(-b.)20 b Fq(When)9 b(this)f(\015ag)g(is)g (used,)h(no)g Fp(r)o(ec)o(enc)o(y)16 b Fq(t)o(est)10 b(is)e(t)o(ak)o(en.)16 b(R)o(ather,)c(the)d(binar)o(y)24 1141 y(mak)o(e)h(\014le)f(is)g(e)o(x)o(ecut)o(ed)h(immediat)o(ely)g (`as)f(is'.)14 b(When)9 b(this)g(\015ag)g(is)f(absent,)24 1190 y Fp(icmak)o(e)i Fq(c)o(ompiles)f(the)g(input)f(\014le)g(\()p Fp(.im)h Fq(\014le\))g(int)o(o)g(a)g(binar)o(y)f(\014le)g(\()p Fp(.bim)i Fq(\014le\))24 1240 y(if)i(the)g(input)g(\014le)g(is)g(mor)o (e)i(r)o(ec)o(ent.)-59 1321 y Fn(-c.)21 b Fq(When)13 b(this)f(\015ag)h(is)f(used,)h(the)g(ascii)g(input)f(\014le)h(is)g(c)o (ompiled)g(t)o(o)i(a)e(binar)o(y)24 1371 y(mak)o(e\014le,)e(but)f(not)g (aut)o(omatic)o(ally)h(e)o(x)o(ecut)o(ed.)16 b(The)10 b(c)o(ompilation)g(oc)o(cur)o(s)24 1421 y(irr)o(espectiv)o(e)k(t)o(o)g (the)e(r)o(ec)o(enc)o(y)j(of)d(the)h(input)f(\014le)g(and)g(the)h (binar)o(y)f(\014le.)-59 1501 y Fn(-i)g(\014le.)21 b Fq(This)11 b(option)i(speci\014es)f Fp(\014le)g Fq(as)g(the)h(input)f (\014le)g(for)h Fp(icmak)o(e)g Fq(and)f(st)o(ops)24 1551 y(the)h(further)f(pr)o(oc)o(essing)g(of)g(the)h(ar)o(gument)o(s.)k(The) 12 b(name)h(of)f(the)h(binar)o(y)24 1601 y(mak)o(e\014le)18 b(\()p Fp(.bim)f Fq(\014le\))g(is)g(then)f(the)i(name)f(of)g(the)g (input)f(\014le)h(but)g(with)24 1651 y(the)e(e)o(xt)o(ension)f Fp(.bim)p Fq(.)23 b(The)14 b(default)h(input)e(\014le)i(e)o(xt)o (ension,)g Fp(.im)p Fq(,)g(is)f Fn(not)24 1701 y Fq(supplied)d(b)o(y)h Fp(icmak)o(e)i Fq(when)e(this)f(\015ag)h(is)g(giv)o(en:)k(the)c (speci\014ed)h(name)f(is)24 1750 y(t)o(ak)o(en)i(lit)o(er)o(ally.)p -59 1786 534 2 v -18 1814 a Fi(3)1 1826 y Fh(The)9 b(actual)h(summar)o (y)f(may)h(v)o(ar)o(y)h(with)f(di\013er)o(ent)g(v)o(er)o(sions)g(of)f Fg(icmak)o(e)p Fh(.)p eop %%Page: 10 11 10 10 bop -59 -127 a Fn(10)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fn(-o)h(\014le.)21 b Fq(With)15 b(this)g(option,)i(an)e(e)o(xtr)o(a)h(\014lename)f(is)g(r)o(equir)o (ed.)26 b(When)15 b(used,)24 39 y(all)h Fp(icmak)o(e)h Fq(output)g(is)e(r)o(edir)o(ect)o(ed)k(t)o(o)e(`\014le',)g(and)f(will)f (not)i(appear)g(on)24 89 y(the)h(scr)o(een)227 71 y Fj(4)244 89 y Fq(.)31 b(This)17 b(\015ag)g(is)f(only)h(av)o(ailable)g(in)g (MS-DOS)f(v)o(er)o(sions)i(of)24 139 y Fp(icmak)o(e)p Fq(:)27 b(under)17 b Fh(DOS)p Fq(,)j(an)d(`or)o(dinar)o(y')h(r)o(edir)o (ection)h(st)o(at)o(ement)h(on)d(the)24 188 y(c)o(ommand)k(line)d (fails)g(t)o(o)i(r)o(edir)o(ect)i(child)c(pr)o(ogr)o(ams)i(and)f(ther)o (efor)o(e)i(a)24 238 y(separ)o(at)o(e)11 b(r)o(edir)o(ection)h (mechanism,)e(activ)o(at)o(ed)i(b)o(y)e(this)f(\015ag,)h(is)f(needed.) 24 288 y(Under)j(UNIX,)h(r)o(edir)o(ection)h(of)e Fp(icmak)o(e)i Fq(and)d(of)i(it)o(s)f(child)g(pr)o(ogr)o(ams)h(c)o(an)24 338 y(be)g(achie)o(v)o(ed)g(using)d(the)j Fl(>)g Fq(sign)e(on)h(the)h (c)o(ommand)h(line.)-59 437 y Fn(-p.)20 b Fq(When)15 b(this)f(option)h(is)f(used,)h(only)g(the)g Fp(Icmak)o(e)g(pr)o(epr)o (oc)o(essor)23 b Fq(is)14 b(acti-)24 487 y(v)o(at)o(ed.)k(The)12 b(output)g(of)g(the)h(pr)o(epr)o(oc)o(essor)h(is)e(sent)g(t)o(o)h(a)f (\014le)g(having)e(the)24 537 y(same)g(name)h(as)f(the)g(input)f (\014le,)i(but)f(e)o(xt)o(ension)f Fp(.pim)p Fq(.)16 b(When)10 b(this)g(\015ag)f(is)24 586 y(absent,)k Fp(icmak)o(e)p Fq('s)g(pr)o(epr)o(oc)o(essor)i(still)c(gener)o(at)o(es)i(a)g Fp(.pim)f Fq(\014le;)g(but)g(this)24 636 y(\014le)g(is)g(delet)o(ed)h (when)f(no)g(longer)h(r)o(equir)o(ed.)-59 736 y Fn(-q.)20 b Fq(When)13 b(this)e(option)i(is)f(used,)g Fp(Icmak)o(e)21 b Fq(oper)o(at)o(es)14 b Fp(quiet)p Fq(.)i(I.e.,)d(the)g(c)o(op)o(y-)24 785 y(right)f(banner)g(is)g(not)h(display)o(ed.)-59 885 y Ff(--)p Fn(.)21 b Fq(By)16 b(default,)h(the)g(\014r)o(st)f (non-\015ag)g(ar)o(gument)g(on)h(the)f(c)o(ommand)i(line)d(is)24 934 y(the)h(input)f(\014le,)h(for)g(which)f(the)h(e)o(xt)o(ension)f Fp(.im)h Fq(is)f(assumed.)26 b(When)15 b(a)24 984 y(sec)o(ond)c (non-\015ag)f(ar)o(gument)h(is)f(giv)o(en,)h(then)f(this)g(name)h(is)f (used)g(for)h(the)24 1034 y(binar)o(y)17 b(\014le)g(\()p Fp(.bim)i Fq(\014le\).)31 b(The)18 b(pr)o(oc)o(essing)g(of)f(ar)o (gument)o(s)h(st)o(ops)g(only)24 1084 y(when)c(two)i(c)o(onsecutiv)o(e) g(hyphens)d(ar)o(e)j(enc)o(ount)o(er)o(ed.)26 b(All)15 b(ar)o(gument)o(s)24 1134 y(which)d(follow)g(the)h Ff(--)g Fq(\015ag)e(c)o(an)j(be)e(inspect)o(ed)h(b)o(y)f(the)h(mak)o(e\014le.) 24 1208 y(Not)o(e)19 b(that)f(the)f Ff(--)h Fq(\015ag)e(is)h(not)g(r)o (equir)o(ed)h(when)f Fp(icmak)o(e)h Fq(is)f(activ)o(at)o(ed)24 1258 y(with)12 b(the)h Fp(-i)f Fq(\015ag)g(pr)o(esent.)-18 1365 y(The)18 b Fp(ascii\014le)e Fq(speci\014c)o(ation)i(is)e(obligat)o (or)o(y.)32 b(This)16 b(is)g(the)i(ascii)f(mak)o(e\014le)-59 1415 y(which)12 b(will)g(be)h(c)o(ompiled)h(and)e(t)o(est)o(ed)j(b)o(y) d Fp(icmak)o(e)p Fq(.)20 b Fp(Icmak)o(e)14 b Fq(assumes)e(a)h(de-)-59 1465 y(fault)f(e)o(xt)o(ension)h Fp(.im)p Fq(.)18 b(E.g.,)13 b(the)g(c)o(ommand)h(line)e Fp(icmak)o(e)i(t)o(est)f Fq(will)e(activ)o(at)o(e)-59 1515 y Fp(icmak)o(e)k Fq(t)o(o)f(pr)o(oc)o (ess)h(the)f Fh(ASCII)g Fq(mak)o(e\014le)g Fp(t)o(est.im)p Fq(.)19 b(Not)o(e)c(howe)o(v)o(er)g(that)f(the)-59 1565 y(c)o(ommand)i(line)f Fp(icmak)o(e)h(-i)e(t)o(est)h Fq(will)f(st)o(art) i Fp(icmak)o(e)h Fq(t)o(o)f(pr)o(oc)o(ess)g(the)g(mak)o(e-)-59 1614 y(\014le)h Fp(t)o(est)p Fq(;)h(the)g(pr)o(esenc)o(e)g(of)f(the)h Fp(-i)e Fq(\015ag)h(for)o(c)o(es)h Fp(icmak)o(e)g Fq(not)g(t)o(o)g (supply)e(an)-59 1664 y(e)o(xt)o(ension.)p -59 1707 534 2 v -18 1735 a Fi(4)1 1747 y Fh(The)8 b Fd(IC)o(C)o(E)16 b Fh(pr)o(ogr)o(am)9 b Fg(t)o(ee)15 b Fh(is)9 b(another)e(useful)h(t)o (ool)h(her)o(e,)f(allowing)h(the)g(display)g(of)f(output)g(t)o(o)-59 1786 y(the)h(scr)o(een,)g(and)f(the)i Fg(simult)o(aneous)k Fh(gener)o(ation)9 b(of)g(a)g(c)o(op)o(y)g(of)g(the)g(display)o(ed)h (information)d(t)o(o)-59 1826 y(a)j(\014le.)p eop %%Page: 11 12 11 11 bop -59 -127 a Fp(ICMAKE)p 133 -127 1075 2 v 1119 w Fn(11)-18 -11 y Fq(The)17 b Fp(binar)o(y\014le)f Fq(speci\014c)o (ation)h(is)f(optional.)27 b(When)16 b(giv)o(en,)h Fp(icmak)o(e)g Fq(uses)-59 39 y(this)12 b(\014le)h(as)g(the)g(binar)o(y)g(int)o (ermediat)o(e)i(\014le)e(in)f(the)i(pr)o(oc)o(ess)g(of)f(making.)18 b(Ex-)-59 89 y(t)o(ension)d Fp(.bim)g Fq(is)f(the)h(default.)24 b(When)14 b(not)i(giv)o(en,)f Fp(icmak)o(e)h Fq(uses)e(the)h(base-)-59 139 y(name)e(of)f(the)h Fp(ascii\014le)e Fq(but)i(with)f(e)o(xt)o (ension)g Fp(.bim)p Fq(.)-18 190 y(Following)21 b(the)i Fp(binar)o(y\014le)g Fq(speci\014c)o(ation,)j(se)o(v)o(er)o(al)d(ar)o (gument)o(s)g(t)o(o)g(the)-59 240 y(mak)o(e\014le)16 b(it)o(self)e(may)i(be)f(giv)o(en.)23 b(Howe)o(v)o(er,)18 b(befor)o(e)e(any)e(e)o(xtr)o(a)i(ar)o(gument)o(s)-59 290 y(ar)o(e)g(speci\014ed)f(two)h(c)o(onsecutiv)o(e)h(hyphens)d(ar)o (e)i(needed.)25 b(Following)14 b(these)-59 340 y(hyphens)e(e)o(xtr)o(a) j(ar)o(gument)o(s)f(may)h(follow)e(which)g(will)g(be)h(passed)f(t)o(o)i (the)g Fp(ic-)-59 389 y(mak)o(e)23 b Fq(dependent)14 b(pr)o(ogr)o(ams.)23 b(As)15 b(described)f(abo)o(v)o(e,)i(the)f (delimiting)e(two)-59 439 y(hyphens)e(ar)o(e)i(not)g(nec)o(essar)o(y)g (when)f(the)h Fp(-i)f Fq(\015ag)g(is)g(used.)-18 491 y(The)17 b Fp(icmak)o(e)25 b Fq(speci\014c)o(ation)17 b(\014le)f(is)g(writt)o(en)h(as)f(a)h Fn(C)f Fq(pr)o(ogr)o(am,)k(and)c (c)o(on-)-59 540 y(t)o(ains)f(a)g Fp(main\(\))22 b Fq(function)15 b(which)f(r)o(ec)o(eiv)o(es)i(some)f(of)g(the)g(ar)o(gument)o(s)h (spec-)-59 590 y(i\014ed)g(on)h(the)g(c)o(ommand)h(line.)28 b(The)17 b(\014r)o(st)g(ar)o(gument)g(is)f(always)g(the)h(name)-59 640 y(of)f(the)g(binair)o(y)g(mak)o(e)h(\014le)f(\(normally)g(having)f (the)h Fp(.bim)24 b Fq(e)o(xt)o(ension\).)j(R)o(e-)-59 690 y(maining)13 b(ar)o(gument)o(s)j(ar)o(e)f(the)h(ar)o(gument)o(s)f (that)g(follow)g(the)g(two)g(hyphens.)-59 740 y(The)e(hyphens)f (themselv)o(es)h(ar)o(e)h Fp(not)19 b Fq(included)12 b(in)g(the)h(series)g(of)g(ar)o(gument)o(s)-59 790 y(which)e(ar)o(e)i (passed)e(t)o(o)i Fp(main\(\))8 b Fq(\))k(\(See)g(also)g(the)g(par)o (agr)o(aph)h(below)f(about)g Fp(the)-59 839 y(user-de\014ned)h (function)c(main\(\))f Fq(\).)-59 956 y Fn(The)13 b(ICMUN)e(program)-59 1036 y Fq(The)i Fp(icmun)g Fq(pr)o(ogr)o(am)h(is)f(mainly)f(used)g(in)h (de)o(v)o(eloping)f Fp(icmak)o(e)p Fq(.)20 b(The)13 b Fp(icmun)-59 1085 y Fq(pr)o(ogr)o(am)20 b(is)e(an)g(unassembler)f(for)i (the)g(binar)o(y)f(mak)o(e)i(\014le)e(cr)o(eat)o(ed)i(b)o(y)f Fp(ic-)-59 1135 y(mak)o(e.)31 b(Icmun)23 b Fq(e)o(xpect)o(s)17 b(a)g(binar)o(y)f(mak)o(e\014le)i(as)e(ar)o(gument)h(and)g(pr)o(oduc)o (es)-59 1185 y(an)g(assembly-lik)o(e)g(listing)e(of)i(the)h (instructions)f(c)o(ont)o(ained)i(in)d(the)i(binar)o(y)-59 1235 y(mak)o(e\014le.)k(The)14 b(r)o(emainder)h(of)f(this)f(section)h (c)o(an)h(be)f(skipped)f(without)h(loss)-59 1285 y(of)i(c)o(ontinuit)o (y.)27 b(It)16 b(is)f(mainly)g(included)g(for)i(those)f(who)g(ar)o(e)h (int)o(er)o(est)o(ed)g(in)-59 1334 y(the)11 b(way)f(the)h(binar)o(y)g (mak)o(e\014le)g(is)f(or)o(ganized.)16 b(Further)11 b(information)g(on) f(this)-59 1384 y(subject)j(c)o(an)g(be)f(obt)o(ained)i(fr)o(om)f(the)g (author)o(s)g(of)f Fp(icmak)o(e)-18 1434 y Fq(An)h(e)o(x)o(ample)f(of)h (a)f(mak)o(e-sour)o(c)o(e\014le)j(is:)-59 1513 y Fe(void)i(main\(\))-59 1552 y({)12 1592 y(printf\("Hello)e(world\\n"\);)-59 1631 y(})-59 1776 y Fq(A)e(he)o(x)o(dump)e(of)h(the)h(binar)o(y)f(mak)o (e\014le)h(which)f(is)g(gener)o(at)o(ed)h(fr)o(om)g(this)f(small)-59 1826 y Fp(icmak)o(e)20 b Fq(pr)o(ogr)o(am)14 b(is:)p eop %%Page: 12 13 12 12 bop -59 -127 a Fn(12)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 29 y Fe(00000000:)33 b(32)18 b(2E)f(31)g(32)h(26)f(00)g(00)h(00)f(33)g(00)h(00)f(00)g(33)h(00)f(00)g (00)36 b(2.12&...3...3.)o(..)-59 68 y(00000010:)e(22)17 b(00)g(00)g(00)h(06)f(00)g(00)h(05)f(00)g(00)h(05)f(02)g(00)h(1B)f(0D)g (1C)36 b(".............)o(..)-59 107 y(00000020:)e(03)17 b(23)g(21)g(14)h(00)f(1D)g(48)h(65)f(6C)g(6C)h(6F)f(20)g(77)h(6F)f(72)g (6C)36 b(.#!...Hello)15 b(worl)-59 147 y(00000030:)34 b(64)17 b(0A)g(00)g(74)h(65)f(73)g(74)h(2E)f(69)g(6D)h(0A)302 b(d..test.im.)-59 253 y Fq(Another)24 b(way)g(t)o(o)h(look)f(at)g(the)g (binar)o(y)f(mak)o(e\014le)h(is)f(t)o(o)i(use)e Fp(icmun)29 b Fq(t)o(o)-59 302 y(unassemble)11 b(the)i(binar)o(y)e(\014le.)16 b(When)c Fp(icmun)19 b Fq(is)11 b(c)o(alled)i(t)o(o)g(unassemble)e (this)-59 352 y(binar)o(y)h(\014le,)h(the)f(following)f(output)i(is)f (obt)o(ained:)-59 413 y Fe(ICCE)17 b(ICMAKE)f(Binary)h(Make)g(File)f (Unassembler)34 b(Version)16 b(2.01)-59 453 y(Copyright)g(\(c\))h(ICCE) g(1992,)f(1993.)h(All)g(rights)g(reserved.)-59 532 y(Binary)f(file)h (statistics:)83 571 y(strings)194 b(at)17 b(offset)88 b(0026)83 611 y(variables)158 b(at)17 b(offset)88 b(0033)83 650 y(filenames)158 b(at)17 b(offset)88 b(0033)83 689 y(first)17 b(instruction)e(at)i(offset)88 b(0022)-59 768 y(String)16 b(constants)g(dump:)83 808 y("Hello)h(world.")-59 887 y(Disassembled)e(code:)83 926 y([0014])i(06)g(00)g(00)53 b(push)17 b(string)f("Hello)h(world.")83 965 y([0017])g(05)g(00)g(00)53 b(push)17 b(int)g(0000)83 1005 y([001a])g(05)g(02)g(00)53 b(push)17 b(int)g(0002)83 1044 y([001d])g(1b)g(0d)106 b(callrss)16 b(13)i(\(print\))83 1084 y([001f])f(1c)g(03)106 b(add)17 b(sp,)g(3)83 1123 y([0021])g(23)159 b(ret)83 1163 y([0022])17 b(21)g(14)g(00)53 b(call)17 b([0014])83 1202 y([0025])g(1d)159 b(exit)-59 1308 y Fq(This)13 b(\014nal)g(output) i(clearly)f(shows)f(the)h(or)o(ganization)h(of)f(the)g(binar)o(y)g(mak) o(e-)-59 1358 y(\014le:)h(The)9 b(strings,)h(v)o(ariables)f(\(in)h (this)f(e)o(x)o(ample)g(ther)o(e)i(ar)o(e)g(none\),)f(\014lenames,)-59 1407 y(and)15 b(\014r)o(st)h(instruction)f(o\013set)i(is)d(clearly)i (mark)o(ed,)i(the)e(strings)e(ar)o(e)j(shown,)-59 1457 y(and)12 b(the)h(instructions)g(ar)o(e)h(display)o(ed)d(in)h(an)h (assembly-lik)o(e)f(way.)17 b(The)c(dis-)-59 1507 y(assembled)h(c)o (ode)i(c)o(onsist)o(s)f(of)f(lines,)h(one)g(line)e(for)i(each)g (disassembled)f(in-)-59 1557 y(struction.)22 b(Within)14 b(each)g(line)g(thr)o(ee)h(part)o(s)g(ar)o(e)g(r)o(ec)o(ognized.)23 b(The)14 b(leftmost)-59 1607 y(part)h(is)e(between)i(squar)o(e)f(br)o (ack)o(et)o(s,)j(showing)c(the)h(b)o(yt)o(e-o\013set)i(of)e(the)g (\014r)o(st)-59 1656 y(b)o(yt)o(e)f(of)e(the)h(instruction.)17 b(The)12 b(middle)f(part)i(shows)e(the)h(b)o(yt)o(es)g(forming)f(the) -59 1706 y(instruction,)k(and)e(the)i(rightmost)f(part)h(is)e(a)h (legible)f(tr)o(anslation)h(of)g(the)g(bi-)-59 1756 y(nar)o(y)j(c)o (ode.)32 b(For)17 b(e)o(x)o(ample,)i(st)o(arting)f(at)f(o\013set)h(1f) 838 1738 y Fj(5)871 1756 y Fq(ther)o(e)g(ar)o(e)g(t)o(ow)h(b)o(yt)o (es,)p -59 1786 534 2 v -18 1814 a Fi(5)1 1826 y Fg(Icmun)c Fh(displays)10 b(v)o(alues)g(in)f(he)o(x)o(adecimal)g(form)p eop %%Page: 13 14 13 13 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(13)-59 -11 y Fq(having)10 b(v)o(alues)i(of)g(r)o(espectiv)o(ely)h (1c)f(and)g(03.)k(These)c(v)o(alues)f(ar)o(e)i(int)o(erpr)o(et)o(ed)-59 39 y(as)f(the)h(instruction)f(t)o(o)i(add)f(a)f(v)o(alue)g(3)h(t)o(o)g Fp(sp,)f Fq(the)h(st)o(ack)h(point)o(er.)-59 190 y Fk(2.2)50 b(The)16 b(`dependent')f(pr)o(ogr)o(ams,)h(used)g(int)o(ernally)-59 279 y Fq(The)10 b(following)f(pr)o(ogr)o(ams)i(ar)o(e)g(the)f (`dependent')g(pr)o(ogr)o(am)i(of)e Fp(icmak)o(e.)17 b Fq(Nor-)-59 328 y(mally)d(these)g(pr)o(ogr)o(ams)h(ar)o(e)g(not)g(st) o(art)o(ed)h(b)o(y)e(the)g(user)g(of)g Fp(icmak)o(e,)h Fq(but)g(ar)o(e)-59 378 y(\(e)o(v)o(entually\))e(st)o(art)o(ed)h(as)f (child-)e(or)i(o)o(v)o(erlay-pr)o(oc)o(esses)h(of)f Fp(icmak)o(e.)-59 521 y Fn(The)g(preprocessor)e(ICM-PP)-59 609 y Fp(Icm-pp)18 b Fq(is)g(the)h(pr)o(epr)o(oc)o(essor)i(of)d(the)h Fp(icmak)o(e)h Fq(c)o(ompiler.)36 b(This)18 b(pr)o(ogr)o(am)-59 659 y(sc)o(ans)j(the)g(user-supplied)e(mak)o(e\014le)j(for)f(pr)o(epr)o(oc) o(essor)i(dir)o(ectiv)o(es)f(\(e.g.,)-59 709 y Fp(#include)p Fq(,)14 b(see)h(section)g(3.1\))g(and)g(t)o(ak)o(es)h(appr)o(opriat)o (e)g(actions.)24 b(An)15 b(output)-59 759 y(\014le)j(is)g(writt)o(en)h (in)f(which)f(the)i(pr)o(epr)o(oc)o(essor)i(dir)o(ectiv)o(es)e(ar)o(e)h (`e)o(xpanded'.)-59 809 y(This)12 b(\(t)o(empor)o(ar)o(y\))k(\014le)c (is)f(used)h(b)o(y)h(the)f(ne)o(xt)g(st)o(age)h(of)g Fp(icmak)o(e)p Fq(.)-18 865 y(The)j(pr)o(ogr)o(am)h Fp(icm-pp)e Fq(is)g(furthermor)o(e)i(r)o(esponsible)e(for)h(the)f(de\014nition)-59 915 y(of)j(`pr)o(e-loaded)h(s)o(ymbols',)h(such)e(as)h Fp(MSDOS)e Fq(or)i Fp(UNIX)p Fq(.)g(This)f(is)f(further)-59 965 y(described)c(in)e(section)i(3.7.)-59 1107 y Fn(The)g(compiler)e (ICM-COMP)-59 1196 y Fq(The)e(following)e(st)o(age)i(of)f Fp(icmak)o(e)i Fq(is)e(the)h(c)o(ompiler)h Fp(icm-c)o(omp)p Fq(.)k(This)8 b(pr)o(ogr)o(am)-59 1246 y(tr)o(anslat)o(es)15 b(an)f Fh(ASCII)h Fq(\014le,)g(gener)o(at)o(ed)g(b)o(y)f Fp(icm-pp)p Fq(,)h(t)o(o)g(a)g(binar)o(y)f(format)h(and)-59 1295 y(performs)g(err)o(or)h(checking.)22 b(The)15 b(r)o(esulting)e (binar)o(y)h(\014le)g(c)o(ont)o(ains)h Fp(opc)o(odes)p Fq(,)-59 1345 y(much)g(lik)o(e)h(the)g(output)f(\014le)g(of)h(a)f(c)o (ompiler)i(of)e(a)h(pr)o(ogr)o(amming)g(language.)-59 1395 y(When)d(a)h(binar)o(y)f(mak)o(e\014le)i(is)e(gener)o(at)o(ed,)i (the)f(int)o(ermediat)o(e)i(output)e(\014le)f(of)-59 1445 y(the)g(pr)o(epr)o(oc)o(essor)i(is)d(no)g(longer)g(needed)h(and)f (is)g(delet)o(ed.)-59 1587 y Fn(The)h(e)o(xecutor)f(ICM-EXEC)-59 1676 y Fp(Icm-e)o(x)o(ec)18 b Fq(is)g(the)h(e)o(x)o(ecut)o(or)h(of)f (the)g(binar)o(y)g(mak)o(e\014le)g(gener)o(at)o(ed)h(b)o(y)f Fp(icm-)-59 1726 y(c)o(omp)p Fq(.)30 b(This)16 b(st)o(age)i(r)o(eads)g (the)f(binar)o(y)g(mak)o(e\014le)h(and)e(int)o(erpr)o(et)o(s)j(the)f (op-)-59 1776 y(c)o(odes:)g(list)o(s)13 b(of)g(\014les)f(ar)o(e)i (built,)f(\014les)f(ar)o(e)i(c)o(ompar)o(ed)i(b)o(y)d(dat)o(es,)h (actions)g(ar)o(e)-59 1826 y(t)o(ak)o(en.)p eop %%Page: 14 15 14 14 bop -59 -127 a Fn(14)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fk(2.3)50 b(The)16 b(c)o(alling)g(or)o (der)f(of)g(pr)o(ogr)o(ams)-59 66 y Fq(The)d Fp(icmak)o(e)i Fq(gr)o(oup)e(of)h(pr)o(ogr)o(ams)g(att)o(empt)o(s)i(t)o(o)e(mak)o(e)h (use)e(of)g(the)h(av)o(ailable)-59 115 y(memor)o(y)h(as)e(e\016cient)h (as)g(possible.)i(Memor)o(y)e(pr)o(oblems)g(may)g(arise)f(during)-59 165 y(the)h(e)o(x)o(ecution)g(phase)f(of)g(a)h(pr)o(ogr)o(am;)g(i.e.,)g (during)e(the)i(run)f(of)g Fp(icm-e)o(x)o(ec)p Fq(.)-18 215 y(The)k(main)f(pr)o(ogr)o(am)i Fp(icmak)o(e)f Fq(spawns)e(the)i(pr) o(epr)o(oc)o(essor)i(and)d(the)g(c)o(om-)-59 265 y(piler)i(as)f(child)h (pr)o(oc)o(esses.)31 b(Howe)o(v)o(er,)20 b(when)d(the)g(e)o(x)o(ecut)o (or)i(is)d(c)o(alled)h(the)-59 315 y Fp(icmak)o(e)k Fq(pr)o(ogr)o(am)g (it)o(self)e(is)g(o)o(v)o(erlay)o(ed,)k(ther)o(eb)o(y)e(making)f(the)g (maximum)-59 365 y(amount)11 b(of)f(memor)o(y)i(av)o(ailable.)k(Due)10 b(t)o(o)i(this)e(setup,)h Fp(icm-e)o(x)o(ec)f Fq(may)g(spawn)-59 414 y(child)f(pr)o(oc)o(esses)h(which)f(ar)o(e)i(speci\014ed)e(b)o(y)g (the)h(user)g(with)f(a)h(maximum)f(mem-)-59 464 y(or)o(y)k(pool)g(av)o (ailable.)-59 579 y Fk(2.4)50 b(Ex)o(ecut)o(able)17 b(mak)o(e\014les)g (under)e(Unix)-59 656 y Fq(Under)9 b(the)h(oper)o(ating)g(s)o(yst)o(em) g(UNIX)f(it)h(is)f(possible)f(t)o(o)i(cr)o(eat)o(e)i(mak)o(e\014les)e (for)-59 706 y Fp(icmak)o(e)15 b Fq(which)f(ar)o(e)h(themselv)o(es)g(e) o(x)o(ecut)o(able.)23 b(E.g.,)15 b(a)f(setup)g(is)g(feasible)f(in)-59 756 y(which)d(a)g(mak)o(e\014le)i Fp(backup)e Fq(e)o(xist)o(s,)h(which) e(c)o(an)i(be)g(st)o(art)o(ed)h(b)o(y)e(the)h(c)o(ommand)-59 805 y Fp(backup)p Fq(.)16 b(In)9 b(such)g(a)h(setup)f(the)h(same)g (e\013ect)i(may)e(be)g(achie)o(v)o(ed)g(b)o(y)g(cr)o(eating)g(a)-59 855 y(mak)o(e\014le)j Fp(backup.im)g Fq(and)f(b)o(y)g(st)o(arting)g(it) h(with)f(the)g(c)o(ommand)i(line)d Fp(icmak)o(e)-59 905 y(backup)p Fq(.)-59 955 y(T)o(o)i(cr)o(eat)o(e)i(an)d(e)o(x)o(ecut)o (able)h(mak)o(e\014le,)h(the)f(following)e(st)o(eps)i(may)f(be)h(t)o (ak)o(en.)-18 1042 y Fo(\017)21 b Fq(The)15 b(mak)o(e\014le)i(c)o(an)e (be)h(r)o(enamed)g(t)o(o)h(a)e(suit)o(able)g(name.)25 b(This)15 b(name)g(is)24 1091 y(lat)o(er)f(used)d(t)o(o)j(inv)o(ok)o(e) f(the)g(pr)o(oc)o(ess)g(which)f(e)o(x)o(ecut)o(es)h(the)g(mak)o (e\014le;)g(for)24 1141 y(this)f(r)o(eason,)h(the)g(name)g Fp(backup)g Fq(may)f(be)h(pr)o(efer)o(able)g(t)o(o)h Fp(backup.im)p Fq(.)-18 1222 y Fo(\017)21 b Fq(The)10 b(mak)o(e\014le)h(is)e(made)h(e)o(x)o(ecut)o(able)h(using)c(the)k(UNIX) e Fp(chmod)g Fq(pr)o(ogr)o(am.)24 1272 y(E.g.,)k(the)f(c)o(ommand)476 1375 y Fp(chmod)f(+x)i(backup)24 1477 y Fq(labels)f(the)g(\014le)h Fp(backup)f Fq(as)g(an)h(e)o(x)o(ecut)o(able)g(pr)o(ogr)o(am.)24 1542 y(The)j(mak)o(e\014le)h(may)f(furthermor)o(e)h(be)f(plac)o(ed)g (in)f(a)h(dir)o(ect)o(or)o(y)i(point)o(ed)24 1592 y(t)o(o)e(b)o(y)e (the)h Fp(P)n(A)n(TH)g Fq(envir)o(onment.)23 b(E.g.,)15 b(the)g(mak)o(e\014le)h(may)e(be)h(plac)o(ed)24 1642 y(in)d(a)g(user's)g(priv)o(at)o(e)i Fp(bin)e Fq(dir)o(ect)o(or)o(y.)-18 1723 y Fo(\017)21 b Fq(The)13 b(following)d(line)i(is)g(added)g(as)h (the)f(\014r)o(st)h(line)f(in)g(the)h(mak)o(e\014le:)432 1826 y Fp(#!/usr/bin/icmak)o(e)f(-qi)p eop %%Page: 15 16 15 15 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(15)24 -11 y Fq(This)14 b(line)h(informs)g(the)g(oper)o(ating)h(s)o (yst)o(em)g(that)g(when)f(e)o(x)o(ecuting)f(the)24 39 y(\014le,)j(the)f(pr)o(ogr)o(am)h Fp(/usr/bin/icmak)o(e)f Fq(should)e(be)i(st)o(art)o(ed,)j(supplying)24 89 y(the)13 b(\015ags)e Fp(-qi)h Fq(and)g(supplying)d(the)k(name)f(of)h(the)f(mak)o (e\014le.)18 b(The)12 b(\015ag)g Fp(-q)24 139 y Fq(suppr)o(esses)i Fp(icmak)o(e)p Fq('s)i(c)o(op)o(yright)g(header;)h(the)e(\015ag)g Fp(-i)f Fq(c)o(auses)h Fp(icmak)o(e)24 188 y Fq(t)o(o)d(t)o(ak)o(e)g (the)f(following)f(\014le)g(ar)o(gument)h(as)g(the)g(lit)o(er)o(al)g (input)f(\014le)h(inst)o(ead)24 238 y(of)h(supplying)e(the)j(default)f (e)o(xt)o(ension)g Fp(.im)p Fq(.)17 b(See)12 b(also)h(section)g(2.1)f (for)g(a)24 288 y(description)h(of)f(these)h(\015ags.)24 356 y(Not)o(e)19 b(that)f(this)f(line)f(must)h(c)o(ont)o(ain)i(a)e (full)f(r)o(efer)o(enc)o(e,)21 b(including)15 b(the)24 405 y(path,)27 b(t)o(o)e(the)f(pr)o(ogr)o(am)h Fp(icmak)o(e)p Fq(.)52 b(In)23 b(this)g(e)o(x)o(ample)g(this)g(path)h(is)24 455 y Fp(/usr/bin)p Fq(.)-18 549 y(The)9 b(binar)o(y)f(mak)o(e\014le)i (\()p Fp(.bim)f Fq(\014le\))f(is)g(plac)o(ed)h(b)o(y)f Fp(icmak)o(e)i Fq(in)d(the)i(same)g(dir)o(ec-)-59 599 y(t)o(or)o(y)k(as)e(the)h(ascii)f(mak)o(e\014le.)17 b(This)11 b(dir)o(ect)o(or)o(y)j(must)d(ther)o(efor)o(e)i(be)f(ac)o(c)o(essible) -59 648 y(t)o(o)i(the)e(user)h(inv)o(oking)e(the)i(mak)o(e\014le.)-59 788 y Fm(3)60 b(The)17 b(s)o(ynt)o(ax)h(of)g(the)f(mak)o(e\014le)-59 880 y Fq(The)12 b(user-supplied)f(mak)o(e\014le)i(must)f(follow)g(a)g (well-de\014ned)f(s)o(ynt)o(ax,)i(which)-59 930 y(r)o(esembles)k(the)f Fn(C)g Fq(pr)o(ogr)o(amming)h(language.)27 b(This)15 b(section)i(describes)f(the)-59 980 y(s)o(ynt)o(ax)c(of)h(the)g(mak)o (e\014le.)-59 1099 y Fk(3.1)50 b(Comment)16 b(and)f(pr)o(epr)o(oc)o (essor)i(dir)o(ectiv)o(es)-59 1176 y Fq(One)d(of)g(the)g(t)o(asks)h(of) f(the)g(pr)o(epr)o(oc)o(essor)j(is)c(t)o(o)i(strip)f(the)h(mak)o (e\014le)g(of)e(c)o(om-)-59 1226 y(ment.)18 b Fp(Icmak)o(e)c Fq(r)o(ec)o(ognizes)f(two)h(t)o(ypes)f(of)g(c)o(omment:)19 b(the)13 b(st)o(andar)o(d)h Fn(C)p Fq(-lik)o(e)-59 1276 y(c)o(omment)20 b(and)d(end-of-line)g(c)o(omment)i(which)f(is)f (implement)o(ed)h(in,)h(e.g.,)-59 1326 y(the)13 b(Micr)o(osoft)g(6.00a) f Fn(C)h Fq(c)o(ompiler.)-18 1376 y(St)o(andar)o(d)h(c)o(omment)i(must) d(be)h(pr)o(ec)o(eded)h(b)o(y)e(/)p Fo(\003)f Fq(and)h(must)h(be)f (closed)h(b)o(y)-59 1426 y Fo(\003)p Fq(/.)i(This)11 b(t)o(ype)h(of)g(c)o(omment)i(may)e(str)o(et)o(ch)i(o)o(v)o(er)f(mor)o (e)h(than)e(one)g(line.)j(End-)-59 1476 y(of-line)c(c)o(omment)k(is)d (pr)o(ec)o(eded)i(b)o(y)e(//)g(and)g(ends)g(when)g(a)g(new)h(line)e(st) o(art)o(s.)-18 1526 y(Lines)16 b(which)g(st)o(art)i(with)f Fp(#!)28 b Fq(ar)o(e)18 b(skipped)e(b)o(y)h(the)g(pr)o(epr)o(oc)o (essor.)31 b(This)-59 1576 y(featur)o(e)19 b(is)f(included)g(t)o(o)h (allow)g(e)o(x)o(ecut)o(able)g(mak)o(e\014les)g(under)g(UNIX,)f(see)-59 1626 y(section)13 b(2.4.)-18 1676 y(Apart)k(fr)o(om)f(the)g Fp(#!)25 b Fq(dir)o(ectiv)o(e,)18 b Fp(icmak)o(e)e Fq(r)o(ec)o(ognizes) g(two)g(mor)o(e)h(pr)o(epr)o(o-)-59 1726 y(c)o(essor)12 b(dir)o(ectiv)o(es:)17 b Fp(#include)10 b Fq(and)i Fp(#de\014ne)p Fq(.)k(Both)c(dir)o(ectiv)o(es)g(must)g(be)f(pr)o(e-)-59 1776 y(c)o(eded)h(b)o(y)f(a)h(`#'-sign)d(which)h(must)h(be)h(loc)o(at)o (ed)h(at)f(the)g(\014r)o(st)f(c)o(olumn)h(of)f(a)g(line)-59 1826 y(in)h(the)g(mak)o(e\014le.)p eop %%Page: 16 17 16 16 bop -59 -127 a Fn(16)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fn(The)i(#include)g(directive)-59 66 y Fq(The)g Fp(#include)e Fq(dir)o(ectiv)o(e)i(must)g(obe)o(y)g(the)g (following)e(s)o(ynt)o(ax)992 48 y Fj(6)1008 66 y Fq(:)412 152 y Fn(#)h(include)h(")p Fp(\014lename)p Fn(")395 202 y(#)f(include)h Fl(<)p Fp(\014lename)h Fl(>)-59 288 y Fq(When)g Fp(icmak)o(e)g Fq(\(or,)i(mor)o(e)f(e)o(x)o(actly)f(the)g(pr) o(epr)o(oc)o(essor)j Fp(icm-pp)p Fq(\))c(enc)o(ount)o(er)o(s)-59 338 y(this)e(dir)o(ectiv)o(e,)k(the)d Fp(\014lename)h Fq(which)e(is)h(st)o(at)o(ed)i(following)c(the)j Fp(#include)d Fq(di-)-59 388 y(r)o(ectiv)o(e)j(is)d(r)o(ead.)17 b(The)11 b(\014lename)g(may)g(include)f(a)i(path)f(speci\014c)o(ation)1118 370 y Fj(7)1135 388 y Fq(.)16 b(When)-59 438 y(the)c(\014lename)f(is)g (enclosed)g(b)o(y)h(double)f(quot)o(es,)h Fp(icmak)o(e)h Fq(att)o(empt)o(s)h(t)o(o)e(ac)o(c)o(ess)-59 488 y(this)f(\014le)h(e)o (x)o(actly)g(as)g(st)o(at)o(ed.)18 b(When)12 b(the)g(\014lename)g(is)g (enclosed)g(b)o(y)g Fl(<)g Fq(and)g Fl(>)p Fq(,)-59 537 y Fp(icmak)o(e)g Fq(att)o(empt)o(s)h(t)o(o)g(ac)o(c)o(ess)f(this)e (\014le)h(r)o(elativ)o(e)h(t)o(o)g(the)g(dir)o(ect)o(or)o(y)h(point)o (ed)e(t)o(o)-59 587 y(b)o(y)h(the)h(s)o(yst)o(em)g(v)o(ariable)g Fp(IM)p Fq(.)f(This)g(setup)g(is)g(analogous)g(t)o(o)i(the)f(pr)o(oc)o (essing)-59 637 y(of)f(include-\014les)f(b)o(y)h(the)h(Micr)o(osoft)g Fn(C)g Fq(c)o(ompiler)g(under)g(MS-DOS.)-18 687 y(Any)h(information)f (enc)o(ount)o(er)o(ed)i(be)o(y)o(ond)f(the)f(\014lename)h(is)e(ignor)o (ed)i(until)-59 737 y(end-of-line.)-59 844 y Fn(The)f(#de\014ne)g (directive)-59 920 y Fq(The)d Fp(#de\014ne)g Fq(dir)o(ectiv)o(e)h(is)e (a)h(means)g(of)g(inc)o(orpor)o(ating)h(c)o(onst)o(ant)o(s)g(in)e(a)i (mak)o(e-)-59 970 y(\014le.)16 b(The)d(dir)o(ectiv)o(e)g(follows)f(the) h(following)e(s)o(ynt)o(ax:)190 1056 y Fn(#)i(de\014ne)g Fp(identi\014er)f(r)o(ede\014nition-of-identi\014)o(er)-59 1143 y Fq(The)d(de\014ned)g(name)h(\(the)g(name)f(of)g(the)h(de\014ned) f(c)o(onst)o(ant\))i(must)e(be)g(an)h(iden-)-59 1193 y(ti\014er)18 b(ac)o(c)o(or)o(ding)h(t)o(o)g(the)f Fn(C)f Fq(pr)o(ogr)o(amming)h(language:)26 b(the)18 b(\014r)o(st)g(char)o(act) o(er)-59 1242 y(must)g(be)g(an)g(under)o(sc)o(or)o(e)i(or)f(a)f(char)o (act)o(er)j(of)d(the)h(alphabet,)h(subsequent)-59 1292 y(char)o(act)o(er)o(s)15 b(may)e(be)g(under)o(sc)o(or)o(es)g(or)g (alphanumeric)o(s.)-18 1342 y(The)20 b(r)o(ede\014nition)f(part)h(of)g (the)f Fp(#de\014ne)g Fq(dir)o(ectiv)o(e)i(c)o(onsist)o(s)f(of)f(spac)o (es,)-59 1392 y(number)o(s,)f(or)g(what)o(e)o(v)o(er)h(is)d(appr)o (opriat)o(e.)32 b(The)18 b(pr)o(epr)o(oc)o(essor)h(simply)d(r)o(e-)-59 1442 y(plac)o(es)h(all)f(oc)o(curr)o(enc)o(es)j(of)d(the)h(de\014ned)f (c)o(onst)o(ant)i(following)d(the)i Fp(#de\014ne)-59 1491 y Fq(dir)o(ectiv)o(e)12 b(b)o(y)f(the)g(r)o(ede\014nition)f(part.) 17 b(Not)o(e)c(that)e(r)o(ede\014nitions)g(ar)o(e)g(not)g(fur-)-59 1541 y(ther)j(e)o(xpanded;)e(i.e.,)i(an)f(alr)o(eady)h(de\014ned)e (name)i(which)e(oc)o(cur)o(s)j(in)e(the)g(r)o(e-)-59 1591 y(de\014nition)f(part)h(is)f(not)h(pr)o(oc)o(essed)g(but)g(is)f (left)g(as)g(is.)p -59 1627 534 2 v -18 1655 a Fi(6)1 1667 y Fh(S)o(ynt)o(actic)o(al)d(rules)g(ar)o(e)g(r)o(epr)o(esent)o(ed) g(in)g(this)g(document)e(b)o(y)j(two)f(font)o(s:)k(the)8 b(boldfac)o(e)h(part)o(s)-59 1706 y(must)f(appear)g(e)o(x)o(actly)g(in) g(the)h(mak)o(e\014le.)j(The)c(slant)o(ed)g(part)o(s)h(may)f(be)h (substitut)o(ed)f(b)o(y)h(the)f(user.)-18 1735 y Fi(7)1 1747 y Fh(Under)g(MS-DOS,)i(the)f(path)h(speci\014c)o(ation)e(may)h (include)g(slashes)g(as)g(well)h(as)f(backslashes.)-59 1786 y(When)18 b(backslashes)f(ar)o(e)h(used,)i(only)f(one)f(backslash) f(must)h(be)h(used)f(t)o(o)h(separ)o(at)o(e)g(\(sub-)-59 1826 y(\)dir)o(ect)o(ories.)p eop %%Page: 17 18 17 17 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(17)-18 -11 y Fq(Howe)o(v)o(er,)14 b(c)o(omment)g(may)d(be)h(found) e(on)h(the)h(line)f(be)o(y)o(ond)g(the)h Fp(identi\014er)-59 39 y Fq(of)d(a)h Fp(#de\014ne.)15 b Fq(Both)10 b(c)o(omment)i(t)o(o)e (end-of-line)e(and)h(st)o(andar)o(d)h(c)o(omment)i(ar)o(e)-59 89 y(ac)o(c)o(ept)o(ed,)20 b(albeit)c(that)h(st)o(andar)o(d)g(c)o (omment)h(must)e(end)g(at)h(the)f(line)f(it)o(self:)-59 139 y(st)o(andar)o(d)k(c)o(omment)h(enc)o(ount)o(er)o(ed)g(in)d(a)i Fp(#de\014ne-)p Fq(line)e(c)o(an)h(curr)o(ently)h(not)-59 188 y(e)o(xt)o(end)g(o)o(v)o(er)h(multiple)e(lines.)34 b(No)19 b(c)o(omment)i(is)d(ac)o(c)o(ept)o(ed)j(between)e(the)-59 238 y Fp(#de\014ne)12 b Fq(and)h(the)f Fp(identi\014er.)-59 363 y Fk(3.2)50 b(T)o(ypes,)16 b(c)o(onst)o(ant)o(s)h(and)e(v)o (ariables)-59 443 y Fp(Icmak)o(e)j Fq(r)o(ec)o(ognizes)f(four)g(t)o (ypes:)26 b Fp(int,)16 b(string,)g(list)23 b Fq(and)16 b Fp(v)o(oid.)29 b Fq(The)17 b(t)o(ypes)-59 492 y(ser)o(v)o(e)c(the)g (following)e(purposes:)-18 590 y Fo(\017)21 b Fq(The)13 b(t)o(ype)g Fp(v)o(oid)20 b Fq(is)12 b(used)g(only)g(with)h(functions,) f(t)o(o)i(indic)o(at)o(e)g(that)f(these)24 640 y(functions)f(do)g(not)h (r)o(eturn)g(v)o(alues.)-18 730 y Fo(\017)21 b Fq(Const)o(ant)o(s)13 b(may)f(be)g(used)g(in)f(the)i(mak)o(e\014le)g(t)o(o)g(indic)o(at)o(e)g (a)f(number)h(or)f(a)24 780 y(string.)j(The)c(c)o(onst)o(ant)o(s)h (then)e(ob)o(viously)g(hav)o(e)h(t)o(ype)g Fp(int)e Fq(or)j(t)o(ype)f Fp(string)p Fq(.)24 829 y Fp(Int)e Fq(c)o(onst)o(ant)o(s)j(ar)o(e)f (denot)o(ed)g(b)o(y)f(numeric)h(char)o(act)o(er)o(s;)i(e.g.,)e Fp(13)f Fq(is)g(an)g Fp(int)24 879 y Fq(c)o(onst)o(ant.)27 b Fp(String)14 b Fq(c)o(onst)o(ant)o(s)j(ar)o(e)g(denot)o(ed)f(b)o(y)g (t)o(e)o(xt)g(between)g(double)24 929 y(quot)o(e)i(marks;)j(e.g.,)d Fp("a)g(string")e Fq(is)h(a)h(piec)o(e)g(of)f(t)o(e)o(xt.)32 b(List)17 b(c)o(onst)o(ant)o(s)24 979 y(ar)o(e)f(not)g(allowed)g(in)e Fp(icmak)o(e)p Fq(:)24 b(list)o(s)14 b(of)i(\014les)e(always)h(hav)o(e) g(t)o(o)i(be)e(built)24 1029 y(run-time.)24 1098 y(A)10 b(sec)o(ond)g(way)g(t)o(o)g(denot)o(e)h(an)e Fp(int)g Fq(c)o(onst)o(ant)i(is)e(b)o(y)g(enclosing)g(a)h(char)o(act)o(er)24 1148 y(in)k(single)g(quot)o(es.)25 b(The)15 b(numeric)g(v)o(alue)g(of)g (the)g(c)o(onst)o(ant)i(is)d(then)h(the)24 1198 y Fh(ASCII)c Fq(number)g(of)f(the)h(char)o(act)o(er;)j(e.g.,)e(the)f(c)o(onst)o(ant) h Fp('A')f Fq(has)f(the)h(v)o(alue)24 1248 y(65.)16 b(The)11 b(char)o(act)o(er)j(between)e(quot)o(es)g(may)f(not)h(be)f(`esc)o (aped',)i(such)d(as,)24 1298 y(e.g.,)15 b Fp(')p Fo(n)p Fp(n')p Fq(.)22 b(Only)14 b(single)e(char)o(act)o(ers)17 b(ar)o(e)e(allowed)g(in)e(this)h(not)o(ation)i(of)24 1347 y(int)o(eger)d(c)o(onst)o(ant)o(s.)-18 1437 y Fo(\017)21 b Fq(The)14 b(thr)o(ee)i(t)o(ypes)e(further)g(ser)o(v)o(e)h(the)g (de\014nition)e(of)h(v)o(ariables)h(and)e(ar-)24 1487 y(gument)o(s.)i Fp(Icmak)o(e)d Fq(allows)d(global)g(v)o(ariables)h(and) g(loc)o(al)h(v)o(ariables.)k(The)24 1537 y(declar)o(ation)d(of)f(a)f(v) o(ariable)h(or)g(of)g(an)f(ar)o(gument)i(must)e(st)o(at)o(e)i(the)f(t)o (ype)h(of)24 1587 y(the)h(v)o(ariable:)18 b(e.g.,)c Fp(int)e Fq(for)h(a)g(c)o(ount)o(er)i(v)o(ariable)e(or)h Fp(list)e Fq(for)h(a)g(v)o(ariable)24 1636 y(holding,)e(e.g.,)i(the)g(names)f(of) h(all)f(\014les)f(having)g(e)o(xt)o(ension)h(`.c'.)-18 1726 y Fo(\017)21 b Fq(Some)14 b(of)f(the)h(built-in)d(functions)h(of)i Fp(icmak)o(e)g Fq(\(see)g(section)f(3.6\))h(r)o(eturn)24 1776 y(a)f(v)o(alue)f(of)h(one)g(of)f(the)h(t)o(ypes)g Fp(int)p Fq(,)g Fp(string)e Fq(or)i Fp(list)p Fq(.)j(The)d(r)o(eturned) h(v)o(alue)24 1826 y(may)e(be)f(assigned)f(t)o(o)j(a)e(v)o(ariable)h (of)f(the)h(same)g(t)o(ype)g(or)g(may)g(be)f(passed)p eop %%Page: 18 19 18 18 bop -59 -127 a Fn(18)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)24 -11 y Fq(t)o(o)17 b(another)f(function.)25 b(Additionally,)16 b(all)f(built-in)f(functions)h(r)o(equir)o(e)24 39 y(ar)o(gument)o(s)e(of)f(a)h(c)o(ert)o(ain)h(t)o(ype.)-18 117 y Fo(\017)21 b Fq(Similarly)g(t)o(o)i(built-in)d(functions,)k (user-de\014ned)d(functions)g(ar)o(e)i(as-)24 167 y(sumed)16 b(t)o(o)h(r)o(eturn)g(a)g(v)o(alue)f(which)f(is)h(either)g Fp(int)p Fq(,)h Fp(string)e Fq(or)i Fp(list)p Fq(.)26 b(The)24 217 y Fp(int)11 b Fq(t)o(ype)j(is)d(the)i(default.)-59 297 y(The)18 b(de\014nition)f(of)h(v)o(ariables)g(follows)f(a)h Fn(C)p Fq(-lik)o(e)g(s)o(ynt)o(ax.)33 b(Ar)o(gument)o(s)19 b(ar)o(e)-59 347 y(de\014ned)12 b(as)g(in)g Fh(ANSI)p Fq(-)p Fn(C)p Fq(.)-59 397 y(Some)k(e)o(x)o(amples)e(of)h(the)h(usage)e (of)h(t)o(ypes)g(ar)o(e)h(giv)o(en)f(in)f(the)h(listing)f(below.)-59 447 y(Not)o(e)g(also)f(the)f(use)g(of)h(the)f(c)o(onst)o(ant)o(s)i Fp(55)f Fq(and)f Fp("main.c")p Fq(.)12 516 y Fe(string)17 b(myfun)f(\(int)h(x,)g(string)g(y,)g(list)g(z\))35 b(//)17 b(a)h(user-defined)d(function)12 556 y({)693 b(//)17 b(of)h(type)f(string,)f(having)g(3)83 595 y(int)586 b(//)17 b(parameters)154 635 y(counter,)425 b(//)17 b(local)g(variables:)f(2)h (ints,)154 674 y(i;)533 b(//)17 b(1)h(string)e(and)i(1)f(list)83 713 y(string)154 753 y(name;)83 792 y(list)154 832 y(cfiles;)83 911 y(counter)f(=)i(55;)408 b(//)17 b(counter)g(is)g(set)g(to)g(55)83 950 y(name)g(=)h("main.c";)353 b(//)17 b(name)g(is)h(set)f(to)g(string) g(main.c)83 990 y(.)83 1029 y(.)83 1068 y(.)83 1108 y(return)g (\(name\);)389 b(//)17 b(a)h(string)e(is)i(returned)e(to)h(the)12 1147 y(})693 b(//)17 b(caller)-59 1301 y Fk(3.3)50 b(Strings)15 b(and)g(esc)o(ape)i(sequenc)o(es)-59 1377 y Fq(Strings)g(in)h(mak)o (e\014les)h(ar)o(e)g(used)f(t)o(o)h(r)o(epr)o(esent)h(both)f (\014lenames)f(and)g(dis-)-59 1427 y(play)o(ed)11 b(t)o(e)o(xt.)17 b Fp(Icmak)o(e)c Fq(allows)e(a)h(number)f(of)g(special)h(formatting)g (sequenc)o(es)-59 1477 y(in)f(strings)g(t)o(o)i(facilit)o(at)o(e)g(the) f(display)e(of)i(t)o(e)o(xt.)17 b(These)12 b(sequenc)o(es)g(ar)o(e)h(c) o(alled,)-59 1527 y(in)f(analogy)g(t)o(o)h(the)g Fn(C)f Fq(pr)o(ogr)o(amming)i(language,)d(esc)o(ape)j(sequenc)o(es.)-18 1577 y(Esc)o(ape)19 b(sequenc)o(es)e(in)g(strings)f(ar)o(e)j (identi\014ed)d(b)o(y)i(a)f(backslash)g(char)o(ac-)-59 1626 y(t)o(er)d(\()p Fo(n)p Fq(\),)f(followed)g(b)o(y)f(a)h(char)o(act) o(er)i(which)d(identi\014es)g(the)h(esc)o(ape)g(sequenc)o(e.)-59 1676 y(The)i(esc)o(ape)i(sequenc)o(es)e(r)o(ec)o(ognized)h(b)o(y)g Fp(icmak)o(e)g Fq(\(or,)i(mor)o(e)f(ac)o(cur)o(at)o(ely)h(b)o(y)-59 1726 y(the)g(c)o(ompiler)i Fp(icm-c)o(omp)p Fq(\))e(ar)o(e)h (summarized)f(in)g(\014gur)o(e)f(1.)34 b(E.g.,)20 b(when)d(a)-59 1776 y(string)d Fp("St)o(arting.)p Fo(n)p Fp(n")g Fq(is)h(display)o (ed,)g(the)g(string)g Fp(St)o(arting.)23 b Fq(is)14 b(print)o(ed)i(and) -59 1826 y(the)d(cur)o(sor)g(is)f(set)h(t)o(o)g(the)g(st)o(art)h(of)f (the)f(following)f(line.)p eop %%Page: 19 20 19 19 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(19)p 228 -51 740 2 v 253 -23 a Fc(Escape)10 b(sequence)48 b(Action)p 228 -10 V 364 18 a Fb(n)p Fh(a)161 b(alert)9 b(\(bell\))363 57 y Fb(n)p Fh(b)160 b(backspac)o(e)8 b(char)o(act)o(er)368 97 y Fb(n)p Fh(f)164 b(formfeed)8 b(char)o(act)o(er)363 136 y Fb(n)p Fh(n)160 b(newline)366 176 y Fb(n)p Fh(r)j(c)o(arriage)9 b(r)o(eturn)h(char)o(act)o(er)367 215 y Fb(n)p Fh(t)163 b(t)o(ab)364 255 y Fb(n)p Fh(v)e(v)o(ertic)o(al) 10 b(t)o(ab)331 294 y Fb(n)p Fg(other)127 b Fh(lit)o(er)o(al)11 b Fg(other)p 228 308 V 398 335 a Fh(Figur)o(e)f(1:)j(Esc)o(ape)d (sequenc)o(es)-18 472 y Fq(As)j(a)g(side)g(e\013ect,)i(the)e(backslash) g(char)o(act)o(er)i(it)o(self)e(must)g(be)g(r)o(epr)o(esent)o(ed)-59 522 y(as)f(`)p Fo(nn)p Fq('.)k(This)11 b(may)i(be)f(needed)h(when,)f (e.g.,)g(strings)g(r)o(epr)o(esent)h(pathnames)-59 572 y(under)c(MS-DOS.)e(The)i Fn(only)g Fq(e)o(x)o(c)o(eption)h(t)o(o)g (this)f(rule)f(is)h(the)g Fp(#include)e Fq(pr)o(epr)o(o-)-59 622 y(c)o(essor)14 b(dir)o(ectiv)o(e)g(\(see)g(section)f(3.1\):)18 b(this)13 b(dir)o(ectiv)o(e)h(t)o(ak)o(es)g(strings)e(lit)o(er)o(ally) -59 671 y(as)g(the)o(y)h(appear)g(in)f(a)h(mak)o(e\014le.)-18 723 y(Lik)o(e)h Fn(C,)g Fp(Icmak)o(e)21 b Fq(allows)13 b Fp(string-c)o(onc)o(at)o(enation.)j Fq(Long)d(strings,)g(e)o(xt)o (end-)-59 773 y(ing)i(o)o(v)o(er)i(se)o(v)o(er)o(al)f(lines)f(of)h(t)o (e)o(xt,)h(c)o(an)g(be)f(built)f(b)o(y)g(separ)o(ating)h(string)f(c)o (on-)-59 823 y(st)o(ant)o(s)e(b)o(y)f(whit)o(e-spac)o(e)i(char)o(act)o (er)o(s)h(\(blanks,)e(t)o(abs,)g(newlines\).)-59 948 y Fk(3.4)50 b(The)16 b(c)o(ode)g(of)f(a)g(mak)o(e\014le)-59 1028 y Fq(This)g(section)g(discusses)f(the)i(user-de\014ned)e (functions)h(which)f(may)i(appear)-59 1078 y(in)c(a)g(mak)o(e\014le)i (and)e(list)o(s)g(the)h(most)g(c)o(ommon)h(st)o(at)o(ement)o(s.)-59 1195 y Fn(Flow)e(control)g(statements)-59 1275 y Fp(Icmak)o(e)i Fq(r)o(ec)o(ognizes)f(six)e(c)o(ontr)o(ol)j(st)o(at)o(ement)o(s:)-18 1374 y Fo(\017)21 b Fp(if)e Fq(st)o(at)o(ement)o(s,)c(including)10 b Fp(if-else,)-18 1464 y Fo(\017)21 b Fp(while)e Fq(st)o(at)o(ement)o (s)-18 1555 y Fo(\017)i Fp(for)e Fq(st)o(at)o(ement)o(s)-18 1645 y Fo(\017)i Fp(r)o(eturn)f Fq(st)o(at)o(ement)o(s)-18 1735 y Fo(\017)h Fp(br)o(eak)g Fq(st)o(at)o(ement)o(s)-18 1826 y Fo(\017)g Fp(e)o(xit)d Fq(st)o(at)o(ement)o(s)p eop %%Page: 20 21 20 20 bop -59 -127 a Fn(20)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fq(The)17 b Fp(e)o(xit\(\))h Fq(st)o(at)o(ement,)j(though)c(a)g(function)g(in)g Fn(C)p Fq(,)h(is)e(part)i(of)g(the)f Fp(icmak)o(e)-59 39 y Fq(language.)k (Following)13 b(the)i Fp(e)o(xit)e Fq(k)o(e)o(ywor)o(d,)k(an)d(e)o(xpr) o(ession)g(yielding)e(an)j Fp(int)-59 89 y Fq(may)10 b(follow.)16 b(If)9 b(an)g Fp(int)g Fq(e)o(xpr)o(ession)h(follows,)g (it)o(s)g(v)o(alue)g(is)f(r)o(eturned)i(as)f(an)g Fp(int)-59 139 y Fq(t)o(o)k(the)g(oper)o(ating)f(s)o(yst)o(em;)h(otherwise,)g(the) g(r)o(eturned)g(v)o(alue)f(is)f(unde\014ned.)-59 188 y(The)e(other)h(\015ow)f(c)o(ontr)o(ol)i(st)o(at)o(ement)o(s)h(ar)o(e)e (analogous)e(t)o(o)j(the)e(c)o(orr)o(esponding)-59 238 y(ones)i(in)g(the)h Fn(C)f Fq(pr)o(ogr)o(amming)h(language.)-59 358 y Fn(User-de\014ned)g(functions)-59 438 y Fp(Icmak)o(e)i Fq(allows)e(the)h(c)o(onstruction)h(of)f(user-de\014ned)f(functions)g (in)g(a)h(mak)o(e-)-59 488 y(\014le.)25 b(The)16 b(de\014nition)e(of)i (a)f(function)g(must)g(follow)g(an)h Fh(ANSI)p Fq(-)p Fn(C)p Fq(-lik)o(e)f(s)o(ynt)o(ax,)-59 538 y(howe)o(v)o(er,)f(slight)d (di\013er)o(enc)o(es)j(e)o(xist)d(between)i(an)f Fp(icmak)o(e)i Fq(function)e(and)g(a)h Fn(C)-59 588 y Fq(function.)j(These)c(di\013er) o(enc)o(es)i(ar)o(e)g(highlight)o(ed)c(in)i(this)f(section.)-59 640 y(The)i(de\014nition)e(of)i(a)f(function)g(must)h(follow)f(the)h(s) o(ynt)o(ax:)-18 740 y Fo(\017)21 b Fq(Optionally)13 b(the)h(r)o(eturn)h (t)o(ype)f(of)g(the)g(function)f(is)f(speci\014ed.)20 b(The)14 b(t)o(ype)24 790 y(is)e Fp(v)o(oid,)f(int,)g(string)18 b Fq(or)13 b Fp(list)p Fq(.)j(The)c(default)g(r)o(eturn)i(t)o(ype)f(is) f Fp(int)p Fq(.)24 860 y(Not)o(e)h(that)f(when)f(a)h(function)e(e)o (xplicitly)g(r)o(eturns)i(using)e(a)h Fp(r)o(eturn)h Fq(st)o(at)o(e-)24 910 y(ment,)g(the)f(r)o(eturned)h(v)o(alue)e(must)h (mat)o(ch)h(the)f(r)o(eturn)g(t)o(ype.)17 b(A)11 b(function)24 960 y(r)o(eturns)i(an)f(unde\014ned)f(v)o(alue)h(if)g(it)h(does)f(not)h (use)f(a)g Fp(r)o(eturn)h Fq(st)o(at)o(ement.)24 1010 y(Functions)8 b(which)g(ar)o(e)i(de\014ned)f(as)g Fp(v)o(oid)15 b Fq(c)o(an)9 b(also)g(use)g(the)g Fp(r)o(eturn)16 b Fq(st)o(at)o(e-)24 1060 y(ment,)e(albeit)e(without)h(an)f(e)o(xpr)o (ession.)-18 1152 y Fo(\017)21 b Fq(Following)12 b(the)h(optional)h(r)o (eturn)g(t)o(ype,)g(the)g(function)f(name)g(must)g(fol-)24 1201 y(low.)j(The)9 b(name)h(must)g(be)g(an)f(identi\014er;)h(i.e.,)h (the)f(\014r)o(st)g(char)o(act)o(er)j(must)24 1251 y(be)f(an)f(under)o (sc)o(or)o(e)j(or)e(a)g(char)o(act)o(er)j(of)c(the)h(alphabet)g(and)f (optional)h(fol-)24 1301 y(lowing)f(char)o(act)o(ers)k(may)d(be)h (under)o(sc)o(or)o(es)h(or)f(alphanumeric)o(s.)-18 1393 y Fo(\017)21 b Fq(Following)11 b(the)i(function)f(name,)h(a)g Fn(\()f Fq(is)g(e)o(xpect)o(ed.)-18 1485 y Fo(\017)21 b Fq(A)c(par)o(amet)o(er)i(list)e(may)g(follow,)g(c)o(onsisting)f(of)h (par)o(amet)o(er)i(speci\014c)o(a-)24 1535 y(tions)d(separ)o(at)o(ed)h (b)o(y)f Fn(,)h Fq(\(this)f(is)f(r)o(eferr)o(ed)j(t)o(o)f(as)f(an)g Fh(ANSI)p Fq(-)p Fn(C)g Fq(par)o(amet)o(er)24 1584 y(list\).)g(P)o(ar)o (amet)o(er)f(speci\014c)o(ations)d(c)o(onsist)g(of)g(the)g(par)o(amet)o (er)i(t)o(ype)f(\()p Fp(int)p Fq(,)24 1634 y Fp(string)d Fq(or)h Fp(list)p Fq(\))f(and)h(the)g(par)o(amet)o(er)j(name)d(\(an)g (identi\014er\).)16 b(In)10 b(c)o(ontr)o(ast)24 1684 y(t)o(o)15 b Fn(C)p Fq(,)f Fp(icmak)o(e)i Fq(does)e(not)g(allow)g (functions)f(having)f(a)i(v)o(ariable)h(number)24 1734 y(of)d(par)o(amet)o(er)o(s.)-18 1826 y Fo(\017)21 b Fq(Following)11 b(the)i(optional)g(par)o(amet)o(er)i(list)d(a)g Fn(\))g Fq(is)g(e)o(xpect)o(ed.)p eop %%Page: 21 22 21 21 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(21)-18 -11 y Fo(\017)21 b Fq(Ne)o(xt,)16 b(the)f(c)o(ode)g(of)g (the)g(function)e(is)h(e)o(xpect)o(ed:)22 b(st)o(at)o(ement)o(s)16 b(enclosed)24 39 y(b)o(y)c Fo(f)h Fq(and)f Fo(g)p Fq(.)-18 120 y Fo(\017)21 b Fq(Following)10 b(the)h(\014r)o(st)h Fo(f)e Fq(of)h(the)h(c)o(ode)g(block,)h(loc)o(al)e(v)o(ariables)g(may)h (be)f(de-)24 170 y(\014ned.)25 b(Not)o(e)18 b(that)e Fp(icmak)o(e)h Fq(allows)e(the)h(de\014nition)f(of)g(loc)o(al)i(v)o (ariables)24 220 y(only)f(aft)o(er)h(the)f(out)o(er)i(curly)e(br)o(ac)o (e)h(of)f(the)h(function)e(c)o(ode)j(block;)g(the)24 270 y(de\014nition)12 b(within)g(any)h(block)h(of)e(st)o(at)o(ement)o (s)k(is)c(not)h(allowed)g(\(in)g(c)o(on-)24 319 y(tr)o(ast)h(t)o(o)f Fn(C)p Fq(\).)24 385 y(The)e(de\014nition)f(of)h(loc)o(al)h(v)o (ariables)f(c)o(onsist)o(s)g(of)g(the)h(v)o(ariable)f(t)o(ype,)h(one)24 435 y(or)j(mor)o(e)h(v)o(ariable)f(names)f(separ)o(at)o(ed)j(b)o(y)d(c) o(ommas)i(and)e(a)h(semic)o(olon.)24 485 y(In)d(c)o(ontr)o(ast)i(t)o(o) g Fn(C)p Fq(,)f Fp(icmak)o(e)h Fq(initializes)c(all)i(loc)o(al)i(v)o (ariables)e(t)o(o)i(zer)o(o.)-18 572 y Fp(Icmak)o(e)f Fq(does)f(not)g(allow)f(forwar)o(d)i(r)o(efer)o(enc)o(es.)18 b(This)11 b(means)g(that)i(a)f(func-)-59 621 y(tion)j(may)f(only)g(be)h (c)o(alled)f Fp(aft)o(er)h Fq(it)g(has)f(been)g(de\014ned.)22 b(Furthermor)o(e,)17 b(the)-59 671 y(st)o(at)o(ement)d(which)d(c)o (alls)g(a)h(function)f(must)h(supply)e(the)i(e)o(x)o(act)g(number)g(of) f(r)o(e-)-59 721 y(quir)o(ed)f(ar)o(gument)o(s)i(and)e(each)h(ar)o (gument)g(t)o(ype)g(must)g(mat)o(ch)h(the)f(par)o(amet)o(er)-59 771 y(list)16 b(of)h(the)g(function.)28 b(The)17 b(built-in)e (functions)g(ar)o(e)j(pr)o(ede\014ned)f(and)f(may)-59 821 y(ther)o(efor)o(e)e(be)f(used)f(anywher)o(e)g(within)g(functions.) -59 928 y Fn(The)h(user-de\014ned)g(function)h(main\(\))-59 1004 y Fq(The)d(c)o(ode)i(section)f(of)f(a)h(mak)o(e\014le)g(must)g(c)o (ont)o(ain)g(at)g(least)g(one)g(user-de\014ned)-59 1054 y(function,)20 b(c)o(alled)g Fp(main\(\))p Fq(.)37 b(The)19 b(e)o(x)o(ecution)g(of)g(a)g(mak)o(e\014le)h(st)o(art)o(s)h(at)e(this) -59 1104 y(function.)j(The)14 b(run-time)g(support)h(s)o(yst)o(em)g(of) f Fp(icmak)o(e)i Fq(\(or,)g(mor)o(e)g(e)o(x)o(actly,)-59 1154 y(the)f(e)o(x)o(ecut)o(or)h Fp(icm-e)o(x)o(ec)p Fq(\))e(pr)o(o)o(vides)h(thr)o(ee)g(ar)o(gument)o(s)h(which)d(the)i (function)-59 1203 y Fp(main\(\))g Fq(may)g(use.)23 b(The)14 b(ar)o(gument)o(s)h(ar)o(e)h(used)e(t)o(o)h(hold)g(the)f(c)o(ommand)i (line)-59 1253 y(par)o(amet)o(er)o(s)f(of)d(the)h Fp(icmak)o(e)h Fq(inv)o(oc)o(ation)f(and)f(the)h(envir)o(onment)g(setting.)-18 1303 y(The)i(thr)o(ee)g(ar)o(gument)o(s)g(ar)o(e)g(most)h(c)o(ommonly)f (r)o(eferr)o(ed)h(t)o(o)f(as)f Fp(ar)o(gc)p Fq(,)i Fp(ar)o(gv)-59 1353 y Fq(and)d Fp(envp)p Fq(.)18 b Fp(Ar)o(gc)c Fq(is)e(an)h Fp(int)g Fq(ar)o(gument,)h(holding)d(the)j(number)f(of)g(c)o(ommand)-59 1403 y(line)e(par)o(amet)o(er)o(s.)19 b Fp(Ar)o(gv)13 b Fq(is)e(a)h Fp(list)p Fq(,)f(holding)f(the)j(c)o(ommand)g(line)e(par) o(amet)o(er)o(s)-59 1452 y(themselv)o(es.)24 b Fp(Envp)15 b Fq(is)f(a)h(list)f(holding)g(the)h(envir)o(onment)g(setting.)24 b(A)15 b(de\014-)-59 1502 y(nition)d(of)g(the)h Fp(main\(\))g Fq(function)f(which)f(uses)h(all)g(ar)o(gument)o(s)h Fp(ar)o(gc)p Fq(,)g Fp(ar)o(gv)g Fq(and)-59 1552 y Fp(envp)f Fq(is)g(giv)o(en)g(below:)244 1639 y Fp(int)g(main)h(\(int)e(ar)o(gc,)i (list)e(ar)o(gv,)i(list)e(envp)p Fq(\))-59 1726 y(User)o(s)20 b(may)g(wish)f(t)o(o)i(de\014ne)e(the)h Fp(main\(\))h Fq(function)e(without)h(ar)o(gument)o(s,)-59 1776 y(when)15 b(the)h(c)o(ommand)h(line)e(par)o(amet)o(er)o(s)k(need)c(not)h(be)g(e)o (x)o(amined.)26 b(In)15 b(this)-59 1826 y(c)o(ase,)f(the)f Fp(main\(\))g Fq(function)f(c)o(an)h(be)g(de\014ned)f(as:)p eop %%Page: 22 23 22 22 bop -59 -127 a Fn(22)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)506 -11 y(int)g(main)i(\(\))-59 82 y Fq(Also)i(it)g(is)f(possible)g(t)o(o)i(de\014ne)f(the)g Fp(main\(\))h Fq(function)e(t)o(o)i(use)f(only)f(the)h(\014r)o(st)-59 132 y(two)e(ar)o(gument)o(s)g Fp(ar)o(gc)g Fq(and)f Fp(ar)o(gv)p Fq(:)342 225 y Fp(int)f(main)i(\(int)f(ar)o(gc,)g(list)f(ar)o(gv\))-59 317 y Fq(Following)c(the)i(same)g(r)o(easoning,)g(it)f(is)g(possible)f (t)o(o)j(de\014ne)e(a)h Fp(main\(\))g Fq(function)-59 367 y(using)i(only)h(it)o(s)g(\014r)o(st)h(ar)o(gument)h Fp(ar)o(gc)p Fq(.)j(Howe)o(v)o(er,)e(this)d(does)h(not)g(seem)g(v)o(er) o(y)-59 417 y(useful,)h(sinc)o(e)h(such)f(a)g Fp(main\(\))i Fq(function)e(c)o(ould)h(inv)o(estigat)o(e)g(the)g(number)g(of)-59 467 y(c)o(ommand)k(line)e(ar)o(gument)o(s)h(but)f(would)g(not)i(be)e (able)h(t)o(o)g(inv)o(estigat)o(e)g(the)-59 516 y(ar)o(gument)o(s)13 b(themselv)o(es.)-18 567 y(A)d(sample)f(mak)o(e\014le)h(which)e(print)o (s)h(it)o(s)g(c)o(ommand)h(line)f(ar)o(gument)o(s)g(is)f(giv)o(en)-59 616 y(below)58 599 y Fj(8)74 616 y Fq(:)83 699 y Fe(void)17 b(main)g(\(int)g(argc,)f(list)h(argv\))83 738 y({)154 778 y(int)225 817 y(i;)154 896 y(for)g(\(i)h(=)f(0;)h(i)f(<)h(argc;)e (i++\))225 936 y(printf)h(\("Argument)e(",)j(i,)f(")h(is)f(",)g (element)f(\(i,)i(argv\),)e("\\n"\);)83 975 y(})-18 1107 y Fq(The)f(ar)o(gument)o(s)g(passed)f(t)o(o)h(the)g Fp(main\(\))g Fq(function)f(of)h Fp(icmak)o(e)g Fq(as)f(the)h(list)-59 1157 y Fp(ar)o(gv)e Fq(ar)o(e:)-18 1249 y Fo(\017)21 b Fq(The)f(\014r)o(st)g(ar)o(gument)g(is)f(always)g(the)h(name)g(of)f (the)h(binar)o(y)g(mak)o(e\014le)24 1299 y(which)12 b(is)g(int)o(erpr)o (et)o(ed)i(b)o(y)f Fp(icm-e)o(x)o(ec.)-18 1384 y Fo(\017)21 b Fq(R)o(emaining)d(ar)o(gument)o(s)g(ar)o(e)h Fp(only)24 b Fq(those)18 b(ar)o(gument)o(s)h(which)e(ar)o(e)i(e)o(x-)24 1433 y(plicit)o(ely)12 b(supplied)f(on)i(the)f(c)o(ommand)i(line.)-59 1526 y(E.g.,)e(t)o(o)g(supply)e(the)i(ar)o(gument)o(s)g Fp(one)p Fq(,)f Fp(two)g Fq(and)g Fp(thr)o(ee)h Fq(t)o(o)g(a)g(mak)o (e\014le)g(c)o(alled)-59 1576 y Fp(t)o(est.im)p Fq(,)h(one)f(of)h(the)f (following)f(inv)o(oc)o(ations)i(c)o(an)g(be)g(used:)326 1669 y Fp(icmak)o(e)g(t)o(est)f Ff(--)h Fp(one)f(two)g(thr)o(ee)300 1719 y(icmak)o(e)h(-i)f(t)o(est.im)g(one)g(two)g(thr)o(ee)p -59 1746 534 2 v -18 1774 a Fi(8)1 1786 y Fh(The)i(functions)g Fg(printf\(\))i Fh(and)e Fg(element\(\))i Fh(used)f(in)f(this)h(e)o(x)o (ample)f(ar)o(e)h(discussed)f(in)h(sec-)-59 1826 y(tion)9 b(3.6.)p eop %%Page: 23 24 23 23 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(23)-59 -11 y Fq(In)16 b(both)g(c)o(ases,)j(the)e(\014r)o(st)g Fp(int)e Fq(ar)o(gument)i(of)g(the)f(function)g Fp(main)h(\(\))g Fq(equals)-59 39 y(four.)k(The)14 b(\014r)o(st)g(element)h(of)f(the)g (list)f Fp(ar)o(gv)i Fq(holds)e(the)h(name)h(of)f(the)g(binar)o(y)-59 89 y(mak)o(e\014le)k(\()p Fp(t)o(est.bim)p Fq(\),)h(the)f(r)o(emaining) f(element)o(s)h(of)f Fp(ar)o(gv)h Fq(hold)e(the)i(ar)o(gu-)-59 139 y(ment)o(s)13 b Fp(one)p Fq(,)g Fp(two)e Fq(and)h Fp(thr)o(ee)p Fq(.)-18 188 y(The)i(thir)o(d)g(ar)o(gument)g(of)f Fp(main\(\))p Fq(,)i Fp(envp)p Fq(,)f(is)f(a)g(list)g(holding)f(the)i (setting)f(of)-59 238 y(the)h(envir)o(onment)h(\(the)f(envir)o(onment)h (v)o(ariables\).)21 b(An)14 b(e)o(x)o(ample)g(of)g(such)f(a)-59 288 y(v)o(ariable)d(is)f(the)i Fp(P)n(A)n(TH)f Fq(setting)g(under)g (MS-DOS,)f(which)g(det)o(ermines)i(wher)o(e)-59 338 y(the)h(oper)o (ating)g(s)o(yst)o(em)h(sear)o(ches)f(for)g(e)o(x)o(ecut)o(able)h (\014les.)i(The)d Fp(envp)g Fq(list)f(c)o(on-)-59 388 y(sist)o(s)i(of)h(pair)o(s)g(of)f(element)o(s,)j(wher)o(e)e(each)h (\014r)o(st)f(element)h(of)e(the)i(pair)e(holds)-59 437 y(the)18 b(v)o(ariable)f(name)h(\(e.g.,)h(the)f(string)f(\\P)n(A)n (TH"\))i(and)e(wher)o(e)h(the)g(sec)o(ond)-59 487 y(element)g(of)f (each)h(pair)f(holds)f(the)i(v)o(alue)e(of)i(the)f(v)o(ariable)g (\(e.g,,)j(a)d(list)g(of)-59 537 y(dir)o(ect)o(ories)d(wher)o(e)f(e)o (x)o(ecut)o(able)h(\014les)d(may)i(be)g(found\).)-18 587 y(An)g(e)o(x)o(ample)g(of)g(a)g(mak)o(e\014le)g(which)g(print)o(s)f (the)h(settings)f(of)h(envir)o(onment)-59 637 y(v)o(ariables)f(is)g (giv)o(en)g(below:)83 713 y Fe(void)17 b(main)g(\(int)g(argc,)f(list)h (argv,)g(list)g(envp\))83 752 y({)154 792 y(int)225 831 y(i;)154 910 y(for)g(\(i)h(=)f(0;)h(i)f(<)h(sizeof)e(\(envp\);)g(i)i (+=)f(2\))225 949 y(printf)g(\("variable)e(",)j(element)e(\(i,)h (envp\),)f(")i(has)f(value)g(",)350 989 y(element)f(\(i)h(+)h(1,)f (envp\)\);)83 1028 y(})-59 1183 y Fk(3.5)50 b(Expr)o(essions)17 b(and)e(oper)o(at)o(or)o(s)-59 1259 y Fp(Icmak)o(e)i Fq(allows)f(a)h(lar)o(ge)g(number)f(of)g(oper)o(at)o(ors)j(t)o(o)e (form)g(or)g(c)o(ombine)g(e)o(x-)-59 1309 y(pr)o(essions.)27 b(Each)17 b(oper)o(at)o(or)i(has)d(it)o(s)g(own)h(char)o(act)o(eristic) o(s,)j(which)c(ar)o(e)h(the)-59 1359 y(following:)-18 1446 y Fo(\017)k Fq(The)14 b(number)g(of)g(oper)o(ands)h(which)e(an)h (oper)o(at)o(or)j(uses)c(may)i(be)f(two)h(or)24 1495 y(one.)23 b(In)14 b(analogy)g(t)o(o)i Fn(C)p Fq(,)f Fp(icmak)o(e)h Fq(r)o(ec)o(ognizes)f(binar)o(y)g(or)g(unar)o(y)g(oper)o(a-)24 1545 y(t)o(or)o(s.)-18 1626 y Fo(\017)21 b Fq(Each)d(binar)o(y)f(oper)o (at)o(or)j(must)d(be)g(used)g(with)g(two)h(v)o(ariables)f(or)h(c)o(on-) 24 1676 y(st)o(ant)o(s)c(of)e(the)i(same)f(t)o(ype.)18 b(E.g.,)c(the)f(addition)g(of)f(an)h Fp(int)f Fq(and)h(a)g Fp(string)24 1726 y Fq(is)k(not)i(allowed:)27 b Fp(icmak)o(e)19 b Fq(performs)f(no)g(default)g(t)o(ype)h(c)o(asting.)32 b(The)24 1776 y(oper)o(and)10 b(t)o(ypes)f(for)h(which)e(oper)o(at)o (or)o(s)k(ar)o(e)e(allowed)g(is)e(giv)o(en)g(in)h(\014gur)o(e)g(2.)24 1826 y(The)k(shown)e(matrix)i(shows)f(which)g(t)o(ypes)h(may)f(use)g (which)g(oper)o(at)o(or)o(s.)p eop %%Page: 24 25 24 24 bop -59 -127 a Fn(24)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)p 365 -13 2 40 v 433 -25 a Fc(int)p 540 -13 V 140 w(string)p 777 -13 V 146 w(list)p 969 -13 V 226 -11 744 2 v 365 28 2 40 v 403 16 a Fg(all)f(but)p 540 28 V 777 28 V 969 28 V 365 68 V 406 56 a Fh(newer)p 540 68 V 777 68 V 969 68 V 251 95 a Fc(int)p 365 107 V 120 w Fh(older)p 540 107 V 148 w(|)p 777 107 V 181 w(|)p 969 107 V 365 146 V 391 135 a(y)o(ounger)p 540 146 V 777 146 V 969 146 V 365 186 V 540 186 V 777 186 V 969 186 V 226 188 744 2 v 365 227 2 40 v 540 227 V 589 215 a(==)g(!=)f Fa(>)p 777 227 V 969 227 V 365 266 V 540 266 V 582 255 a(<)h(<)p Fh(=)g Fa(>)p Fh(=)p 777 266 V 969 266 V 251 294 a Fc(string)p 365 306 V 97 w Fh(|)p 540 306 V 126 w(+)g(+=)f(=)p 777 306 V 134 w(|)p 969 306 V 365 345 V 540 345 V 566 333 a(newer)h(older)p 777 345 V 969 345 V 365 385 V 540 385 V 597 373 a(y)o(ounger)p 777 385 V 969 385 V 226 386 744 2 v 365 426 2 40 v 540 426 V 777 426 V 969 426 V 365 465 V 540 465 V 777 465 V 823 453 a(==)f(!=)p 969 465 V 251 493 a Fc(list)p 365 505 V 138 w Fh(|)p 540 505 V 173 w(|)p 777 505 V 171 w(+)h({)p 969 505 V 365 544 V 540 544 V 777 544 V 803 532 a(+=)f({=)g(=)p 969 544 V 365 584 V 540 584 V 777 584 V 969 584 V 226 585 744 2 v 219 615 a(Figur)o(e)h(2:)k(The)c(oper)o (and)e(matrix)i(for)f(binar)o(y)h(oper)o(at)o(or)o(s)-18 739 y Fo(\017)21 b Fq(Some)16 b(oper)o(at)o(or)o(s,)i(unar)o(y)d(and)g (binar)o(y,)h(may)f(not)h(be)f(used)f(with)h(some)24 789 y(t)o(ypes.)h(E.g.,)c(string)f(subtr)o(action)i(is)d(not)i (allowed,)h(but)e(string)g(addition)24 839 y(is.)-18 917 y Fo(\017)21 b Fq(The)15 b(oper)o(at)o(or)o(s)j(hav)o(e)d(a)g(c)o (ert)o(ain)h(priorit)o(y:)22 b(some)16 b(oper)o(at)o(or)o(s)h(ar)o(e)f (e)o(v)o(al-)24 967 y(uat)o(ed)i(befor)o(e)g(other)o(s.)32 b(The)18 b(priorit)o(y)g(of)f(oper)o(at)o(or)o(s)j(is)d(analogous)f(t)o (o)24 1016 y Fn(C)p Fq(.)-18 1096 y(The)f(binar)o(y)f(oper)o(at)o(or)o (s)i(r)o(ec)o(ognized)g(b)o(y)e Fp(icmak)o(e)h Fq(ar)o(e)g(summarized)f (in)g(\014g-)-59 1145 y(ur)o(e)20 b(3.)38 b(All)20 b(binar)o(y)f(oper)o (at)o(or)o(s)k(with)c(the)h(e)o(x)o(c)o(eption)h(of)f(the)g(assignment) -59 1195 y(oper)o(at)o(or)o(s)f(ar)o(e)f(left-associativ)o(e.)30 b(The)16 b(assignment)g(oper)o(at)o(or)o(s)k(ar)o(e)d(right-)-59 1245 y(associativ)o(e.)27 b(The)15 b(oper)o(at)o(ors)j(at)e(the)g(t)o (op)h(of)e(this)g(\014gur)o(e)h(hav)o(e)f(the)h(lowest)-59 1295 y(priorit)o(y;)h(the)e(oper)o(at)o(or)o(s)i(at)f(the)f(bott)o(om)i (of)e(this)f(\014gur)o(e)h(hav)o(e)g(the)g(highest)-59 1345 y(priorit)o(y.)i(Oper)o(at)o(or)o(s)e(with)e(di\013er)o(ent)g (priorit)o(y)g(ar)o(e)h(separ)o(at)o(ed)g(b)o(y)e(lines.)-18 1394 y(The)19 b(unar)o(y)g(oper)o(at)o(or)o(s)j(ar)o(e)e(summarized)f (in)f(t)o(able)h(4.)36 b(The)19 b(unar)o(y)g(op-)-59 1444 y(er)o(at)o(or)o(s)j(hav)o(e)e(higher)f(priorit)o(y)i(than)f (binar)o(y)g(oper)o(at)o(or)o(s,)25 b(and)19 b(ar)o(e)i(right-)-59 1494 y(associativ)o(e.)f(The)14 b(e)o(x)o(c)o(eption)g(is)f(the)g(e)o (xpr)o(ession-nesting)e(oper)o(at)o(or,)17 b(which)-59 1544 y(surr)o(ounds)12 b(an)g(e)o(xpr)o(ession)g(and)g(does)g(not)h (associat)o(e.)-59 1649 y Fn(Logical)e(operators)-59 1726 y Fp(Icmak)o(e)16 b Fq(r)o(ec)o(ognizes)g(thr)o(ee)h(logic)o(al)e (oper)o(at)o(or)o(s:)25 b(the)15 b(logic)o(al)g(and)g(\(&&\),)j(the)-59 1776 y(logic)o(al)c(or)h(\()p Fo(jj)p Fq(\))f(and)g(the)g(logic)o(al)g (not)h(\(!\).)22 b(These)14 b(oper)o(at)o(or)o(s)j(c)o(an)e(be)f(used)f (t)o(o)-59 1826 y(c)o(ombine)g(or)g(r)o(e)o(v)o(er)o(se)i(logic)o(al)d (e)o(xpr)o(essions.)p eop %%Page: 25 26 25 25 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(25)p 92 89 1014 2 v 168 116 a Fc(Operator)100 b(Operation)243 b(Allowed)10 b(types)p 92 130 V 232 157 a Fh(,)165 b(sequential)9 b(e)o(v)o(aluation)63 b(all)10 b(\(mix)o(ed\))p 92 171 V 224 198 a(=)157 b(assignment)221 b(all)130 238 y({=)9 b(+=)g Fb(\003)p Fh(=)h(/=)63 b(c)o(ompound)8 b(assignment)49 b(arithm.)10 b(oper)o(at)o(or)o(s)160 277 y(\045=)f(&=)h Fb(j)p Fh(=)214 317 y(^)f(=)p 92 330 V 227 358 a Fb(jj)161 b Fh(logic)o(al)10 b(or)254 b(all)10 b(\(mix)o(ed\))p 92 371 V 212 399 a(&&)146 b(logic)o(al)10 b(and)230 b(all)10 b(\(mix)o(ed\))p 92 412 V 232 440 a Fb(j)166 b Fh(bitwise)10 b(or)241 b Fg(int)p 92 454 V 232 481 a Fh(^)165 b(e)o(x)o(clusiv)o(e)10 b(or)215 b Fg(int)p 92 495 V 225 522 a Fh(&)158 b(bitwise)10 b(and)217 b Fg(int)p 92 536 V 142 563 a Fa(<)10 b(>)g(<)p Fh(=)f Fa(>)p Fh(=)75 b(c)o(omparison)216 b Fg(int,)10 b(string)116 603 y Fh(newer,)g(y)o(ounger)49 b(\014le)10 b(dat)o(e)271 b Fg(string)197 642 y Fh(older)129 b(\014le)10 b(dat)o(e)271 b Fg(string)p 92 656 V 210 683 a Fa(<<)144 b Fh(left)o(shift)277 b Fg(int)210 723 y Fa(>>)144 b Fh(right)o(shift)p 92 736 V 224 764 a(+)157 b(addition)266 b(all)229 803 y({)162 b(subtr)o(action)220 b Fg(int,)10 b(list)p 92 817 V 228 844 a Fb(\003)162 b Fh(multiplic)o(ation)179 b Fg(int)229 884 y Fh(/)162 b(division)274 b Fg(int)227 923 y Fh(\045)160 b(modulo)277 b Fg(int)p 92 937 V 306 967 a Fh(Figur)o(e)10 b(3:)k(Ov)o(er)o(view)d(of)f(binar)o(y)g(oper)o (at)o(or)o(s)p 172 1289 853 2 v 197 1317 a Fc(Operator)48 b(Operation)182 b(Allowed)10 b(types)p 172 1330 V 260 1358 a Fh(!)112 b(logic)o(al)10 b(not)174 b(all)261 1397 y(~)113 b(bitwise)11 b(not)160 b Fg(int)253 1437 y Fh(+)105 b(unar)o(y)10 b(plus)172 b(all)258 1476 y({)110 b(unar)o(y)10 b(minus)142 b Fg(int)240 1516 y Fh(++)91 b(incr)o(ement)179 b Fg(int)10 b Fh(\(v)o(ariable)h(only\))245 1555 y({)e({)97 b(decr)o(ement)171 b Fg(int)10 b Fh(\(v)o(ariable)h(only\))220 1594 y(\()p Fg(t)o(ype)p Fh(\))75 b(t)o(ype)11 b(c)o(ast)197 b(see)10 b(3.5)250 1634 y(\()g(\))103 b(e)o(xpr)o(ession)9 b(nesting)49 b(all)p 172 1647 V 311 1677 a(Figur)o(e)10 b(4:)k(Ov)o(er)o(view)e(of)d(unar)o(y)g(oper)o(at)o(or)o(s)p eop %%Page: 26 27 26 26 bop -59 -127 a Fn(26)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-18 -11 y Fq(The)i(logic)o(al)f(not)h(oper)o(at)o (or)i(r)o(e)o(v)o(er)o(ses)f(the)f(logic)o(al)g(out)o(c)o(ome)i(of)d (an)g(e)o(xpr)o(es-)-59 39 y(sion.)k(The)c(logic)o(al)g(and)g(oper)o (at)o(or)j(and)d(the)g(logic)o(al)g(or)h(oper)o(at)o(or)i(gr)o(oup)d(c) o(on-)-59 89 y(ditions.)j Fp(Icmak)o(e)10 b Fq(e)o(v)o(aluat)o(es)g(a)f (c)o(ombined)g(c)o(ondition)h(using)d(these)i(oper)o(at)o(or)o(s)-59 139 y(until)i(the)i(out)o(c)o(ome)i(of)e(the)f(c)o(ondition)h(is)f(det) o(ermined,)i(in)e(analogy)g(t)o(o)h Fn(C)p Fq(:)-18 236 y Fo(\017)21 b Fq(In)16 b(the)h(c)o(ondition)g Fp(c1)f(&&)i(c2)p Fq(,)f Fp(c2)f Fq(is)g(not)h(e)o(v)o(aluat)o(ed)h(if)e Fp(c1)g Fq(yields)f(zer)o(o)24 286 y(sinc)o(e)f(when)g Fp(c1)f Fq(yields)g(zer)o(o,)k(the)d(c)o(ombined)h(c)o(ondition)g(c)o (an)g(only)f(fail.)24 335 y(Ther)o(efor)o(e,)h Fp(c2)d Fq(is)f(only)h(e)o(v)o(aluat)o(ed)i(if)e Fp(c1)f Fq(yields)h(not)h(zer) o(o.)-18 424 y Fo(\017)21 b Fq(In)13 b(the)h(c)o(ondition)g Fp(c1)f Fo(jj)g Fp(c2)p Fq(,)h Fp(c2)f Fq(is)g(not)h(e)o(v)o(aluat)o (ed)h(if)e Fp(c1)g Fq(yields)f(not)i(zer)o(o)24 474 y(sinc)o(e)h(when)g Fp(c1)g Fq(yields)f(not)h(zer)o(o,)j(the)e(c)o(ombined)g(c)o(ondition)f (c)o(an)h(only)24 524 y(suc)o(c)o(eed.)i(Ther)o(efor)o(e,)c Fp(c2)e Fq(is)g(only)g(e)o(v)o(aluat)o(ed)i(if)d Fp(c1)h Fq(yields)f(zer)o(o.)-59 621 y(This)h(is)f(illustr)o(at)o(ed)i(in)f (the)h(following)e(c)o(ode)i(fr)o(agment:)83 709 y Fe(if)k(\(exists)g (\("main.c"\))e(&&)j(exists)e(\("main.exe"\)\))154 748 y(print)h(\(0,)g("main.c)f(and)h(main.exe)f(both)h(found.\\n"\);)83 788 y(if)g(\(exists)g(\("main.c"\))e(||)j(exists)e(\("main.exe"\)\))154 827 y(print)h(\(0,)g("main.c)f(exists,\\n",)332 867 y("or)h(main.c)g (not)g(found)f(but)h(main.exe)f(found.\\n"\);)-18 1003 y Fq(Logic)o(al)j(oper)o(at)o(or)o(s)i(may)e(be)g(used)e(with)h(any)h (t)o(ype)g(of)f(e)o(xpr)o(ession.)34 b(An)-59 1053 y Fp(int)17 b Fq(c)o(onst)o(ant)j(or)f(v)o(ariable)g(yields)e(it)o(s)i (int)o(eger)f(r)o(epr)o(esent)o(ation.)37 b(A)19 b Fp(string)-59 1103 y Fq(c)o(onst)o(ant)d(or)g(v)o(ariable)f(yields)f(not)h(zer)o(o)h (when)f(the)g(length)f(of)h(the)g(string)f(is)-59 1153 y(non-zer)o(o;)f(e.g.,)f(string)g Fp("a")h Fq(yields)e(not)i(zer)o(o.) -18 1204 y(A)19 b Fp(list)f Fq(or)h(v)o(ariable)g(yields)e(not)i(zer)o (o)h(when)e(the)h(number)f(of)h(strings)e(in)-59 1254 y(the)e(list)e(is)h(not)h(zer)o(o.)23 b(E.g.,)15 b(in)e(the)i (following)e(c)o(ode)i(fr)o(agment)g(the)g(making)-59 1304 y(pr)o(oc)o(ess)f(is)d(st)o(opped)i(when)f(no)h(\014les)e(with)i (e)o(xt)o(ension)f Fp(".c")g Fq(ar)o(e)h(found:)83 1392 y Fe(list)154 1431 y(cfiles;)83 1510 y(//)18 b(cfiles)e(is)h(set)g(to)h (hold)f(all)g(filenames)e(with)i(extension)f(.c)83 1550 y(cfiles)h(=)g(makelist)f(\("*.c"\);)83 1589 y(//)i(if)f(no)g(such)g (files)g(found...)f(terminate!)83 1628 y(if)h(\(!)h(cfiles\))83 1668 y({)154 1707 y(print)f(\(0,)g("No)g(files)g(with)g(extension)e(.c) j(found!!\\n"\);)154 1747 y(exit)f(\(1\);)83 1786 y(})p eop %%Page: 27 28 27 27 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(27)-59 -11 y(Special)12 b(operators)-59 66 y Fq(In)g(addition)h(t) o(o)i(the)f(oper)o(at)o(or)o(s)i(of)d(the)g Fn(C)h Fq(pr)o(ogr)o (amming)g(language,)e Fp(icmak)o(e)-59 115 y Fq(r)o(ec)o(ognizes)h(a)g (few)f(`special')g(oper)o(at)o(or)o(s.)19 b(These)13 b(ar)o(e:)-18 202 y Fo(\017)21 b Fq(The)13 b Fp(y)o(ounger)f Fq(oper)o(at)o(or)k(is)c(used)g(t)o(o)i(c)o(ompar)o(e)h(two)e(strings)f (which)g(r)o(ep-)24 251 y(r)o(esent)18 b(\014lenames.)32 b(An)17 b(e)o(xpr)o(ession)g(using)f Fp(y)o(ounger)h Fq(is)g(e)o(v)o(aluat)o(ed)h(t)o(o)24 301 y(non-zer)o(o)d(or)g(zer)o(o) h(and)e(may)h(be)g(used)f(in)g(a)h(c)o(ondition.)23 b(The)15 b(oper)o(at)o(or)24 351 y Fp(newer)e Fq(is)f(an)g(alias)g(for)h Fp(y)o(ounger)p Fq(.)24 416 y(The)k(e)o(xpr)o(ession)f(using)e(the)j Fp(y)o(ounger)g Fq(oper)o(at)o(or)i(yields)c(non-zer)o(o)j(if)d(a)24 466 y(\014le)10 b(with)h(the)g(name)g(r)o(epr)o(esent)o(ed)i(b)o(y)d (the)h(left)g(oper)o(and)g(is)f(mor)o(e)j(r)o(ec)o(ent)24 516 y(than)f(the)h(\014le)f(r)o(epr)o(esent)o(ed)j(b)o(y)d(the)h(right) f(oper)o(and.)24 582 y(E.g.,)18 b(the)e(following)f(c)o(ode)j(print)o (s)e(a)h(message)f(if)g(\014le)g Fp(main.c)g Fq(is)g(mor)o(e)24 631 y(r)o(ec)o(ent)e(than)f Fp(main.e)o(x)o(e)p Fq(:)237 723 y Fe(if)18 b(\("main.c")d(newer)i("main.exe"\))308 762 y(printf)g(\("main.c)f(is)h(more)g(recent)g(than)f(main.exe\\n"\);) -18 903 y Fo(\017)21 b Fq(The)14 b Fp(older)f Fq(oper)o(and)h(c)o (ompar)o(es)i(two)e(\014les)e(and)i(yields)e(non-zer)o(o)i(if)e(the)24 953 y(\014le)i(r)o(epr)o(esent)o(ed)j(b)o(y)d(the)h(left)g(oper)o(and)g (is)f(older)h(than)g(the)g(\014le)f(r)o(epr)o(e-)24 1003 y(sent)o(ed)f(b)o(y)f(the)h(right)f(oper)o(and.)-59 1089 y(When)g(the)g(dat)o(e)h(of)f(a)g(\014le)g(is)f(c)o(ompar)o(ed)j(using) c Fp(older)i Fq(or)h Fp(y)o(ounger)f Fq(and)f(when)-59 1139 y(no)g(\014le)g(with)g(such)f(a)i(name)f(is)g(pr)o(esent,)h(then)f (the)h(age)f(if)f(the)i(\014le)f(is)f(assumed)-59 1189 y(t)o(o)16 b(be)g(in\014nit)o(e.)24 b(A)15 b(c)o(onsequenc)o(e)h(of)f (this)g(implement)o(ation)h(is)f(that,)i(in)d(the)-59 1239 y(following)c(c)o(ode)i(e)o(x)o(ample,)g(a)g(message)f(is)g (display)o(ed)f(if)g Fp("t)o(est.e)o(x)o(e")i Fq(does)f(not)-59 1288 y(e)o(xist:)83 1364 y Fe(if)17 b(\("test.c")f(younger)g ("test.exe"\))154 1404 y(printf)h(\("test.c)f(should)g(be)h (compiled!!\\n"\);)-59 1550 y Fn(Type)12 b(casts)-59 1626 y Fq(Though)d Fp(icmak)o(e)i Fq(does)f(not)g(allow)g(the)g(use)f (of)h(oper)o(at)o(or)o(s)i(on)e(di\013er)o(ent)h(t)o(ypes,)-59 1676 y(a)k(possibilit)o(y)f(c)o(onsist)o(s)i(of)f(the)g(c)o(onv)o(er)o (sion)i(of)e(one)g(t)o(ype)h(t)o(o)h(another.)25 b(The)-59 1726 y(c)o(onv)o(er)o(sion)13 b(of)g(a)g(t)o(ype)g(is)e(r)o(eferr)o(ed) j(t)o(o)g(as)e(`t)o(ype)h(c)o(ast'.)-18 1776 y(T)o(ype)j(c)o(ast)o(s)g (ar)o(e)g(denot)o(ed)h(b)o(y)e(a)g(t)o(ype)h(name)f(in)g(par)o (entheses)g(befor)o(e)h(the)-59 1826 y(oper)o(and)11 b(which)f(should)f(be)h(c)o(onv)o(ert)o(ed.)18 b(E.g.,)11 b Fp(\(int\)x)f Fq(c)o(onv)o(ert)o(s)i(the)f(oper)o(and)p eop %%Page: 28 29 28 28 bop -59 -127 a Fn(28)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y(x)i Fq(t)o(o)i(int)o(eger)g(r)o(epr)o (esent)o(ation.)22 b(T)o(ype)15 b(c)o(ast)o(s)f(ar)o(e)h(not)g(allowed) e(on)h(all)f(t)o(ypes;)-59 39 y(e.g.,)g(a)f(list)g(v)o(ariable)h(c)o (an)g(not)g(be)f(c)o(onv)o(ert)o(ed)j(t)o(o)f Fp(int)p Fq(.)-59 93 y(Allowed)f(t)o(ype)g(c)o(ast)o(s)g(ar)o(e)h(the)f (following:)-18 201 y Fo(\017)21 b Fq(An)c(int)o(eger)g(may)h(be)f(c)o (ast)h(t)o(o)g Fp(string)p Fq(.)29 b(E.g.,)18 b(in)f(the)g(following)e (listing)24 251 y Fp(stringv)o(ar)e Fq(is)f(assigned)f(t)o(o)j(hold)e (the)h(t)o(e)o(xt)h(r)o(epr)o(esent)o(ation)h(of)e(the)g(v)o(alue)24 301 y Fp(14)p Fq(.)237 419 y Fe(string)308 459 y(stringvar;)237 538 y(stringvar)j(=)i(\(string\))e(14;)141 b(//)18 b(now,)e(stringvar)g (is)i("14")-18 706 y Fo(\017)j Fq(A)13 b(string)e(may)i(be)f(c)o(ast)i (t)o(o)f Fp(int)p Fq(.)j(This)11 b(is)h(the)h(r)o(e)o(v)o(er)o(se)h (action)f(of)f(the)h(t)o(ype)24 756 y(c)o(ast)h(shown)d(in)h(the)h (listing)e(abo)o(v)o(e.)-18 856 y Fo(\017)21 b Fq(A)c(string)g(may)g (be)g(c)o(ast)i(t)o(o)f(a)f Fp(list)p Fq(.)29 b(This)16 b(may)i(be)f(particularly)g(useful)24 905 y(when)11 b(\014lenames)h (should)f(be)h(added)g(t)o(o)h(or)g(r)o(emo)o(v)o(ed)h(fr)o(om)e(a)h (list.)i(E.g.,)24 955 y(in)f(the)h(listing)e(below)i(the)g(\014lename)g Fp("main.c")f Fq(\(a)i Fp(string)p Fq(\))e(is)g(r)o(emo)o(v)o(ed)24 1005 y(fr)o(om)f(the)g(list)f Fp(c\014les)p Fq(:)237 1124 y Fe(list)308 1163 y(cfiles;)237 1242 y(//)18 b(cfiles)e(is)h(set) h(to)f(hold)g(a)g(list)g(of)237 1281 y(//)h(all)f(filenames)f(with)g (extension)g(.c)237 1321 y(cfiles)h(=)g(makelist)f(\("*.c"\);)237 1360 y(//)i(filename)e(main.c)g(is)h(removed)g(from)g(the)g(list)237 1400 y(cfiles)g(-=)g(\(list\))g("main.c";)24 1568 y Fq(Not)o(e)d(that)e (the)g(string)f Fp("main.c")h Fn(must)h Fq(be)e(c)o(onv)o(ert)o(ed)k(t) o(o)e(a)f Fp(list)e Fq(t)o(ype)i(t)o(o)24 1618 y(allow)g(the)h(subtr)o (action)h(fr)o(om)f(the)g(list.)-59 1726 y(Other)j(t)o(ypec)o(ast,)i (speci\014c)o(ally)d(fr)o(om)h(a)f(string)f(t)o(o)i(an)f Fh(ASCII)p Fq(-r)o(epr)o(esent)o(ation,)-59 1776 y(c)o(an)g(be)g(r)o (ealized)g(thr)o(ough)f(specialized)g(functions)g(\(see,)i(e.g.,)f(the) g(function)-59 1826 y Fp(ascii\(\))p Fq(.\))p eop %%Page: 29 30 29 29 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(29)-59 -11 y Fk(3.6)50 b(Built-in)16 b(functions)-59 66 y Fq(Built)11 b(int)o(o)h Fp(icmak)o(e)h Fq(is)d(a)i(number)g(of)f (functions)g(which)f(may)i(be)g(used)f(t)o(o)i(per-)-59 115 y(form)d(special)f(oper)o(ations,)j(such)c(as)h(sc)o(anning)g(a)g (dir)o(ect)o(or)o(y)j(for)e(\014les,)f(display-)-59 165 y(ing)i(information,)i(et)o(c..)18 b(This)12 b(section)h(describes)f (all)g(built-in)f(functions.)-59 270 y Fn(arghead)-59 346 y Fp(\(int\))f(ar)o(ghead)i(\(string\):)22 b Fq(This)10 b(function)g(set)o(s)h(the)f(ar)o(gument)i(head)e(t)o(o)i Fp(string)p Fq(.)-59 396 y(See)g Fp(e)o(x)o(ec\(\))i Fq(and)e Fp(e)o(x)o(ecut)o(e\(\))p Fq(.)-59 500 y Fn(argtail)-59 577 y Fp(\(int\))k(ar)o(gt)o(ail)h(\(string\):)31 b Fq(This)15 b(function)h(set)o(s)h(the)g(ar)o(gument)g(t)o(ail)f(t)o(o)i Fp(string)p Fq(.)-59 627 y(See)12 b Fp(e)o(x)o(ec\(\))i Fq(and)e Fp(e)o(x)o(ecut)o(e\(\))p Fq(.)-59 731 y Fn(ascii)-59 807 y Fp(\(int\))g(ascii)g(\(string\):)17 b Fq(This)12 b(function)g(r)o(eturns)i(the)f Fh(ASCII)p Fq(-number)g(of)g(the)g (\014r)o(st)-59 857 y(char)o(act)o(er)g(in)c(the)i(string,)f(supplied)e (as)i(ar)o(gument.)17 b(E.g.,)11 b Fp(ascii)e(\("A"\))i Fq(r)o(eturns)-59 907 y(65.)-59 1011 y Fn(ascii)-59 1088 y Fp(\(string\))i(ascii)f(\(int\):)18 b Fq(The)13 b(o)o(v)o(erloaded)i (function,)f(which)e(e)o(xpect)o(s)i(an)f Fp(int)f Fq(ar-)-59 1138 y(gument,)17 b(r)o(eturns)f(a)h(string)e(r)o(epr)o(esent)o(ation)j (of)e(a)g(numeric)g Fh(ASCII)h Fq(number.)-59 1187 y(E.g.,)c Fp(ascii)e(\(65\))i Fq(r)o(eturns)g("A".)-59 1292 y Fn(change)p 75 1292 13 2 v 16 w(base)-59 1368 y Fp(\(string\))f(change)p 231 1368 V 15 w(base)h(\(string,)f(string\):)23 b Fq(This)12 b(function)g(changes)h(the)g(base-)-59 1418 y(name)f(in)e(the)i(string) e(which)h(is)f(supplied)g(as)h(it)o(s)g(\014r)o(st)h(ar)o(gument)g(t)o (o)g(the)g(base-)-59 1468 y(name)20 b(which)e(is)h(supplied)f(as)h(sec) o(ond)h(ar)o(gument.)37 b(The)20 b(string)e(with)h(the)-59 1518 y(changed)12 b(basename)h(is)f(r)o(eturned.)-18 1567 y(Ex)o(ample:)154 1628 y Fe(string)225 1668 y(name;)154 1747 y(name)17 b(=)h(change_base)d(\("main.c",)h("test"\);)154 1786 y(//)i(name)e(now)i(is)f("test.c")p eop %%Page: 30 31 30 30 bop -59 -127 a Fn(30)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fn(change)p 75 -11 13 2 v 16 w(e)o(xt)-59 66 y Fp(\(string\))j(change)p 233 66 V 14 w(e)o(xt)g(\(string,)f(string\):)27 b Fq(This)13 b(function)h(changes)g(the)h(e)o(xt)o(en-)-59 116 y(sion)h(in)g(the)h (string)f(which)h(is)f(supplied)f(as)i(it)o(s)g(\014r)o(st)g(ar)o (gument)g(t)o(o)h(the)f(e)o(x-)-59 165 y(t)o(ension)12 b(which)f(is)g(supplied)f(as)h(sec)o(ond)i(ar)o(gument.)k(The)12 b(modi\014ed)f(string)g(is)-59 215 y(r)o(eturned.)-18 265 y(The)h(e)o(xt)o(ension)g(\(the)g(sec)o(ond)g(ar)o(gument\))h(may)f (be)g(speci\014ed)f(as)h(an)g(empt)o(y)-59 315 y(string)f(\(""\);)i(in) e(this)h(c)o(ase)g Fp(change)p 525 315 V 15 w(e)o(xt\(\))g Fq(r)o(emo)o(v)o(es)h(the)g(e)o(xt)o(ension.)j(Also,)c(the)-59 365 y(e)o(xt)o(ension)h(may)g(be)h(speci\014ed)f(as)g(one)g(dot)h (\("."\);)h(in)d(this)h(c)o(ase)h Fp(change)p 1176 365 V 15 w(e)o(xt\(\))-59 414 y Fq(r)o(emo)o(v)o(es)g(the)f(e)o(xt)o (ension)f(but)g(leav)o(es)h(the)g(dot.)-18 464 y(Ex)o(ample:)154 545 y Fe(char)225 585 y(name;)154 664 y(name)k(=)h(rss_changeExt)d (\("main.c",)h("obj"\);)154 703 y(//)i(name)e(now)i(is)f("main.obj")154 743 y(name)g(=)h(rss_changeExt)d(\(name,)i(""\);)154 782 y(//)h(name)e(now)i(is)f("main")154 821 y(name)g(=)h(rss_changeExt)d (\(name,)i("."\);)154 861 y(//)h(name)e(now)i(is)f("main.")-59 1008 y Fn(change)p 75 1008 V 16 w(path)-59 1085 y Fp(\(string\))d (change)p 233 1085 V 15 w(path)g(\(string,)g(string\):)28 b Fq(This)14 b(function)g(changes)g(the)h(path)-59 1135 y(in)c(the)i(string)e(which)h(is)f(supplied)g(as)h(it)o(s)g(\014r)o(st) g(ar)o(gument)h(t)o(o)g(the)g(path)f(which)-59 1184 y(is)g(supplied)f (as)h(sec)o(ond)h(ar)o(gument.)-18 1234 y(Ex)o(ample:)154 1315 y Fe(string)225 1355 y(name;)154 1434 y(name)k(=)h(change_path)d (\("c:/prog/c/prog)o(.c",)f("/bin"\);)154 1473 y(//)k(name)e(now)i(is)f ("c:/bin/prog.c")154 1512 y(name)g(=)h(change_path)d(\(name,)h(""\);) 154 1552 y(//)i(name)e(now)i(is)f("c:prog.c")-59 1699 y Fn(chdir)-59 1776 y Fp(\(string\))f(chdir)f(\(int,)h(string\):)30 b Fq(This)16 b(function)f(changes)h(the)g(curr)o(ent)i(work-)-59 1826 y(ing)d(dir)o(ect)o(or)o(y)k(t)o(o)f(the)f(supplied)e(name.)29 b(The)16 b(\014r)o(st)h Fp(int)f Fq(ar)o(gument)h(may)f(be)p eop %%Page: 31 32 31 31 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(31)-59 -11 y Fp(P)p -29 -11 13 2 v 14 w(CHECK)16 b Fq(or)f Fp(P)p 228 -11 V 15 w(NOCHECK)p Fq(.)g(This)f(ar)o(gument)i (is)e(optional;)i(when)e(absent,)-59 39 y Fp(P)p -29 39 V 14 w(CHECK)i Fq(is)e(assumed.)23 b(Failur)o(e)15 b(t)o(o)h(change)f(the)g(working)g(dir)o(ect)o(or)o(y)i(with)-59 89 y(the)11 b(pr)o(esenc)o(e)h(of)e Fp(P)p 273 89 V 15 w(CHECK)h Fq(leads)f(t)o(o)i(the)f(t)o(ermination)g(of)g(the)g(making)f (pr)o(o-)-59 139 y(c)o(ess.)-18 188 y(When)k(the)f(pr)o(oc)o(essing)g (of)h(the)f(mak)o(e\014le)h(t)o(erminat)o(es)h(the)f(original)e(dir)o (ec-)-59 238 y(t)o(or)o(y)i(is)e(r)o(est)o(or)o(ed.)-18 288 y(A)19 b(string)f(c)o(ont)o(aining)g(the)g(new)g(working)g(dir)o (ect)o(or)o(y,)23 b(always)18 b(ending)e(in)-59 338 y(a)f(dir)o(ect)o (or)o(y)i(separ)o(at)o(or)349 320 y Fj(9)382 338 y Fq(is)c(r)o (eturned.)24 b(The)15 b Fp(string)21 b Fq(ar)o(gument)15 b(may)g(t)o(ermi-)-59 388 y(nat)o(e)d(in)f(a)h(\014nal)f (\(back\)slash.)17 b(The)11 b(r)o(eturned)i(string)e(c)o(an)h(be)g (used)f(t)o(o)i(inspect)-59 437 y(whether)j(the)f(r)o(equest)o(ed)i (dir)o(ect)o(or)o(y)g(is)e(r)o(eached,)j(giv)o(en)c(that)i(the)g (modi\014er)-59 487 y Fp(P)p -29 487 V 14 w(NOCHECK)d Fq(is)f(supplied)f(as)h(\014r)o(st)h(ar)o(gument.)-59 537 y(T)o(wo)g(special)g(string)e(ar)o(gument)o(s)i(ar)o(e)h(r)o(ec)o (ognized)f(b)o(y)g Fp(chdir)e(\(\))p Fq(:)-18 620 y Fo(\017)21 b Fq(A)16 b(dir)o(ect)o(or)o(y)i(ar)o(gument)e(which)f(c)o(onsist)o(s)h (of)f(one)h(dot)g(\(i.e.,)h(the)f(string)24 669 y("."\))g(c)o(auses)11 b Fp(icmak)o(e)h Fq(t)o(o)g(change)e(t)o(o)i(the)f(curr)o(ent)h(dir)o (ect)o(or)o(y.)18 b(The)11 b(r)o(eturn)24 719 y(v)o(alue)h(is)g(then)g (a)h(string)f(holding)f(the)h(curr)o(ent)i(dir)o(ect)o(or)o(y.)-18 799 y Fo(\017)21 b Fq(A)10 b(dir)o(ect)o(or)o(y)j(ar)o(gument)e(which)e (is)h(an)g(empt)o(y)h(string)e(\(i.e.,)i(the)g(string)e(""\))24 849 y(c)o(auses)15 b Fp(icmak)o(e)g Fq(not)h(t)o(o)f(change)g(the)g (curr)o(ent)g(dir)o(ect)o(or)o(y)i(but)e(t)o(o)h(r)o(eturn)24 898 y(the)d(st)o(artup-dir)o(ect)o(or)o(y,)j(fr)o(om)d(which)f Fp(icmak)o(e)h Fq(was)g(st)o(art)o(ed.)-18 981 y(Ex)o(ample:)154 1053 y Fe(//)18 b(print)e(the)h(current)g(working)f(directory)154 1092 y(printf\("Current)f(dir:)i(",)g(chdir)g(\("."\),)f("\\n"\);)154 1132 y(//)i(change)e(to)h(directory)f(/c/prog)154 1171 y(chdir)h(\("/c/prog"\);)154 1211 y(//)h(print)e(startup)g(directory) 154 1250 y(printf)h(\("Startup)e(dir:)i(",)h(chdir)e(\(""\),)h ("\\n"\);)-59 1396 y Fn(cmdhead)-59 1472 y Fp(\(int\))22 b(cmdhead)h(\(string\):)42 b Fq(This)22 b(function)f(set)o(s)i(the)g(c) o(ommand)g(head)f(t)o(o)-59 1522 y Fp(string)p Fq(.)15 b(See)e Fp(e)o(x)o(ec\(\))g Fq(and)f Fp(e)o(x)o(ecut)o(e\(\))p Fq(.)-59 1628 y Fn(cmdtail)-59 1705 y Fp(\(int\))i(cmdt)o(ail)g (\(string\):)27 b Fq(This)13 b(function)h(set)o(s)g(the)h(c)o(ommand)h (t)o(ail)e(t)o(o)i Fp(string)p Fq(.)-59 1755 y(See)c Fp(e)o(x)o(ec\(\))i Fq(and)e Fp(e)o(x)o(ecut)o(e\(\))p Fq(.)p -59 1786 534 2 v -18 1814 a Fi(9)1 1826 y Fh(The)d(dir)o(ect)o (or)o(y)i(separ)o(at)o(or)e(is)h(a)g(backslash)e(under)h(MS-DOS)i(and)e (a)h(slash)f(under)g(UNIX.)p eop %%Page: 32 33 32 32 bop -59 -127 a Fn(32)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fn(echo)-59 66 y Fp(\(int\))i(echo)g (\(int\):)26 b Fq(This)13 b(function)g(det)o(ermines)h(whether)g(befor) o(e)h(the)f(e)o(x)o(ecu-)-59 116 y(tion)f(of)f(a)h(c)o(ommand)h(the)f (c)o(ommand)h(will)d(be)i(display)o(ed.)j(The)c(ar)o(gument)i(of)-59 165 y(the)g(function)f(det)o(ermines)i(the)f(displaying)d(mode:)20 b(when)13 b(zer)o(o,)j(displaying)-59 215 y(is)e(suppr)o(essed;)h (else,)g(c)o(ommands)h(ar)o(e)f(display)o(ed)f(befor)o(e)h(e)o(x)o (ecution.)24 b(T)o(wo)-59 265 y(pr)o(ede\014ned)15 b(c)o(onst)o(ant)o (s)g(ar)o(e)h(av)o(ailable)e(for)h(use)f(as)g(an)g(ar)o(gument)h(t)o(o) h Fp(echo\(\))p Fq(:)-59 315 y(the)11 b(c)o(onst)o(ant)o(s)h Fp(ON)f Fq(and)g Fp(OFF)p Fq(.)f(The)h(v)o(alues)f(of)h(these)g(c)o (onst)o(ant)o(s)h(ar)o(e,)h(r)o(espec-)-59 365 y(tiv)o(ely,)g(1)f(and)g (0.)17 b(Initially,)11 b(echoing)h(is)g(on.)-18 414 y(Ex)o(ample:)154 496 y Fe(echo)17 b(\(ON\);)70 b(//)17 b(commands)f(will)h(be)h (displayed)154 535 y(.)154 574 y(.)154 614 y(echo)f(\(OFF\);)52 b(//)17 b(commands)f(will)h(not)g(be)h(displayed)-59 761 y Fn(element\(int,)12 b(list\))-59 838 y Fp(\(string\))e(element)i (\(int,)e(list\):)22 b Fq(This)10 b(function)g(r)o(etrie)o(v)o(es)j(a)e (string)f(fr)o(om)i(a)f(list.)-59 888 y(The)k(or)o(der)i(number)e(of)g (the)h(name)f(in)g(the)g(list)g(is)f(giv)o(en)h(b)o(y)g(the)g(\014r)o (st)h(ar)o(gu-)-59 937 y(ment.)h(Not)o(e)12 b(that)f(this)f(inde)o(x)g (is)g(zer)o(o-based;)h(i.e.,)h(the)f(\014r)o(st)g(element)g(in)f(the) -59 987 y(list)h(has)h(inde)o(x)e(0.)16 b(The)c(last)g(element)h(in)e (the)h(list)g(has)f(inde)o(x)g Fp(sizeo\015ist\(list\))e({)-59 1037 y(1)p Fq(.)-18 1087 y(Ex)o(ample:)154 1168 y Fe(list)225 1207 y(l;)154 1247 y(string)225 1286 y(n;)154 1326 y(int)225 1365 y(i;)154 1444 y(l)18 b(=)f(makelist)f(\("*.c"\);)154 1483 y(for)h(\(i)h(=)f(0;)h(i)f(<)h(sizeoflist)d(\(l\);)i(i++\))225 1523 y(if)h(\(element)e(\(i,)h(l\))g(newer)g("main.exe"\))296 1562 y(printf)g(\("Source)f(file)h(",)g(element)f(\(i,)h(l\),)350 1602 y(")g(is)h(more)f(recent)f(than)h(main.exe\\n"\);)-59 1749 y Fn(element\(int,)12 b(string\))-59 1826 y Fp(\(string\))k (element)h(\(int,)f(string\):)31 b Fq(This)16 b(function)g(r)o(etrie)o (v)o(es)i(a)f(substring)e(of)p eop %%Page: 33 34 33 33 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(33)-59 -11 y Fq(one)13 b(char)o(act)o(er)i(fr)o(om)e(the)g(string) f(giv)o(en)g(as)g(it)o(s)g(sec)o(ond)h(ar)o(gument.)-18 40 y(The)e(char)o(act)o(er)h(which)e(is)f(r)o(eturned)i(is)e(found)g (in)g(the)h(sec)o(ond)h(\(string\))f(ar)o(gu-)-59 90 y(ment)k(at)g(the)g(o\013set)h(position)e(speci\014ed)g(in)g(the)h (\014r)o(st)g(\(int\))g(ar)o(gument.)20 b(This)-59 140 y(inde)o(x)11 b(is)h(zer)o(o-based;)h(i.e.,)f(the)h(\014r)o(st)g(char)o (act)o(er)j(of)c(the)h(string)f(has)f(inde)o(x)h(0.)-18 191 y(Ex)o(ample:)154 279 y Fe(string)225 318 y(s;)154 358 y(int)225 397 y(count;)225 436 y(i;)154 515 y(count)17 b(=)g(0;)154 555 y(s)h(=)f("Hello)g(world";)154 594 y(for)g(\(i)h(=)f (0;)h(element\(i,)d(s\);)i(i++\))225 634 y(count++;)154 712 y(printf\("String)e('",)i(s,)g("')h(contains)e(",)279 752 y(count,)g(")i(characters.\\n"\))o(;)-59 906 y Fn(e)o(xec)-59 985 y Fp(\(int\))i(e)o(x)o(ec)h(\(int,)g(string,)g(...\):)41 b Fq(This)19 b(function)h(e)o(x)o(ecut)o(es)i(a)f(c)o(ommand)h(b)o(y) -59 1035 y(spawning)11 b(a)h(child)g(pr)o(oc)o(ess.)18 b(The)12 b(ar)o(gument)o(s)h(ar)o(e:)-18 1132 y Fo(\017)21 b Fq(The)g(\014r)o(st)h(ar)o(gument)g(is)e(an)h Fp(optional)26 b Fq(mode)c(\(an)f Fp(int)p Fq(\).)42 b(It)21 b(may)g(be)24 1181 y Fp(P)p 54 1181 13 2 v 14 w(CHECK)f Fq(\(0\))g(or)g Fp(P)p 391 1181 V 14 w(NOCHECK)g Fq(\(2\).)37 b(These)19 b(pr)o(ede\014ned)g(c)o(onst)o(ant)o(s)24 1231 y(det)o(ermine)i (whether)f(the)f(e)o(xit)g(st)o(atus)h(of)g(the)f(c)o(ommand)i(should)d (be)24 1281 y(check)o(ed)d(or)f(not.)19 b(If)13 b(the)g(e)o(xit)g(st)o (atus)h(should)e(be)h(check)o(ed,)j(and)d(a)g(non-)24 1331 y(zer)o(o)k(v)o(alue)g(is)e(r)o(eturned)j(b)o(y)e(the)g(c)o(alled) h(pr)o(ogr)o(am,)j(the)c(pr)o(oc)o(essing)h(of)24 1381 y(the)c(icmak)o(e)h(\014le)e(is)g(abort)o(ed.)24 1450 y(If)h(the)i(\014r)o(st)f(ar)o(gument)h(is)e(omitt)o(ed)j(\(i.e.,)f(if) f(the)g(\014r)o(st)h(ar)o(gument)f(is)g Fp(not)24 1499 y Fq(an)e(int\),)h Fp(P)p 207 1499 V 15 w(CHECK)20 b Fq(is)12 b(assumed.)-18 1588 y Fo(\017)21 b Fq(The)16 b(sec)o(ond)g(ar)o(gument)g(is)f(the)h(c)o(ommand)h(t)o(o)f(run)f(\(a)i Fp(string)p Fq(\).)25 b(This)14 b(is)24 1638 y(the)f(name)g(of)f(the)h (pr)o(ogr)o(am)h(t)o(o)f(be)g(activ)o(at)o(ed.)-18 1726 y Fo(\017)21 b Fq(The)h(following)f(ar)o(gument)o(s)i(ar)o(e)g(the)g (ar)o(gument)o(s)g(which)e(should)g(be)24 1776 y(passed)10 b(t)o(o)i(the)g(c)o(alled)f(pr)o(ogr)o(am.)17 b(These)11 b(ar)o(gument)o(s)h(may)f(be)g Fp(int)p Fq(s,)f Fp(list)p Fq(s)24 1826 y(or)j Fp(string)p Fq(s.)p eop %%Page: 34 35 34 34 bop -59 -127 a Fn(34)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-18 -11 y Fq(Each)16 b(c)o(ommand)g(is)e(c)o (omposed)j(of)e(the)g(pr)o(ogr)o(am)h(name)f(\(the)h(sec)o(ond)f(ar-) -59 39 y(gument\),)h(followed)e(b)o(y)h(the)g(curr)o(ent)h(setting)f (of)f(the)h(c)o(ommand)h(head)f(\(see)-59 89 y Fp(cmdhead\(\))p Fq(,)g(followed)d(b)o(y)h(all)g(ar)o(gument)o(s)g(and)g(t)o(erminat)o (ed)i(with)d(the)h(c)o(om-)-59 139 y(mand)f(t)o(ail)h(\(see)g Fp(cmdt)o(ail\(\))p Fq(\).)k(Each)c(ar)o(gument)g(t)o(o)g(the)g(c)o (ommand)h(is)d(pr)o(e\014x)o(ed)-59 188 y(with)d(the)h(ar)o(gument)g (head)g(\(see)g Fp(ar)o(ghead\(\))p Fq(\))i(and)d(post\014x)o(ed)h(b)o (y)f(the)h(ar)o(gument)-59 238 y(t)o(ail)k(\(see)g Fp(ar)o(gt)o (ail\(\))p Fq(\).)-18 288 y(Ex)o(ample:)k(see)c Fp(e)o(x)o(ecut)o (e\(\))g Fq(below.)-59 395 y Fn(e)o(xecute)-59 471 y Fp(\(int\))g(e)o(x)o(ecut)o(e)h(\(int,)f(string,)f(string,)h(string,)f (...,)i(string,)e(string\))p Fq(:)19 b(This)13 b(func-)-59 521 y(tion)d(e)o(x)o(ecut)o(es)h(a)f(c)o(ommand)h(b)o(y)f(spawning)e(a) i(child)f(pr)o(oc)o(ess.)17 b(The)10 b(ar)o(gument)o(s)-59 571 y(ar)o(e:)-18 657 y Fo(\017)21 b Fq(The)g(\014r)o(st)h(ar)o(gument) g(is)e(an)h Fp(optional)26 b Fq(mode)c(\(an)f Fp(int)p Fq(\).)42 b(It)21 b(may)g(be)24 707 y Fp(P)p 54 707 13 2 v 14 w(CHECK)f Fq(\(0\))g(or)g Fp(P)p 391 707 V 14 w(NOCHECK)g Fq(\(2\).)37 b(These)19 b(pr)o(ede\014ned)g(c)o(onst)o(ant) o(s)24 757 y(det)o(ermine)i(whether)f(the)f(e)o(xit)g(st)o(atus)h(of)g (the)f(c)o(ommand)i(should)d(be)24 807 y(check)o(ed)d(or)f(not.)19 b(If)13 b(the)g(e)o(xit)g(st)o(atus)h(should)e(be)h(check)o(ed,)j(and)d (a)g(non-)24 857 y(zer)o(o)k(v)o(alue)g(is)e(r)o(eturned)j(b)o(y)e(the) g(c)o(alled)h(pr)o(ogr)o(am,)j(the)c(pr)o(oc)o(essing)h(of)24 907 y(the)c(icmak)o(e)h(\014le)e(is)g(abort)o(ed.)24 972 y(If)h(the)i(\014r)o(st)f(ar)o(gument)h(is)e(omitt)o(ed)j(\(i.e.,)f (if)f(the)g(\014r)o(st)h(ar)o(gument)f(is)g Fp(not)24 1022 y Fq(an)e(int\),)h Fp(P)p 207 1022 V 15 w(CHECK)20 b Fq(is)12 b(assumed.)-18 1103 y Fo(\017)21 b Fq(The)16 b(sec)o(ond)g(ar)o(gument)g(is)f(the)h(c)o(ommand)h(t)o(o)f(run)f(\(a)i Fp(string)p Fq(\).)25 b(This)14 b(is)24 1153 y(the)f(name)g(of)f(the)h (pr)o(ogr)o(am)h(t)o(o)f(be)g(activ)o(at)o(ed.)-18 1234 y Fo(\017)21 b Fq(The)14 b(thir)o(d)h(ar)o(gument)g(is)f(the)g(c)o (ommand)i(head)e(\(a)h Fp(string)p Fq(\).)22 b(This)13 b(string)24 1284 y(is)h(used)g(as)h(\014r)o(st)h(ar)o(gument)f(t)o(o)h (the)f(pr)o(ogr)o(am)i(name.)24 b(The)15 b(string)f(may)24 1333 y(be)f(empt)o(y)g(\(i.e.,)g Ff("")p Fq(\),)h(in)e(which)f(c)o(ase) j(no)e(c)o(ommand)i(head)e(is)g(used.)-18 1414 y Fo(\017)21 b Fq(The)13 b(fourth)f(ar)o(gument)h(is)f(the)g(ar)o(gument)i(head)e (\(a)h Fp(string)p Fq(\).)j(This)11 b(string)24 1464 y(is)i(pr)o(e\014x)o(ed)h(t)o(o)h(all)e(following)f(ar)o(gument)o(s.)21 b(The)14 b(string)f(may)h(be)g(empt)o(y)24 1514 y(\(i.e.,)f Ff("")p Fq(\),)h(in)e(which)f(c)o(ase)j(no)e(ar)o(gument)h(head)g(is)e (used.)-18 1595 y Fo(\017)21 b Fq(The)h(following)f(ar)o(gument)o(s)i (ar)o(e)g(the)g(ar)o(gument)o(s)g(which)e(should)g(be)24 1645 y(passed)10 b(t)o(o)i(the)g(c)o(alled)f(pr)o(ogr)o(am.)17 b(These)11 b(ar)o(gument)o(s)h(may)f(be)g Fp(int)p Fq(s,)f Fp(list)p Fq(s)24 1695 y(or)j Fp(string)p Fq(s.)-18 1776 y Fo(\017)21 b Fq(The)16 b(one)g(but)g(last)f(ar)o(gument)i(is)e(the)h (ar)o(gument)g(t)o(ail)g(\(a)h Fp(string)p Fq(\).)25 b(This)24 1826 y(string)9 b(is)f(post\014x)o(ed)i(t)o(o)g(each)g(ar)o (gument)g(passed)f(t)o(o)i(the)e(c)o(alled)h(pr)o(ogr)o(am.)p eop %%Page: 35 36 35 35 bop -59 -127 a Fp(ICMAKE)p 133 -127 1075 2 v 1119 w Fn(35)24 -11 y Fq(The)10 b(string)f(may)i(be)f(empt)o(y)h(\(i.e.,)g Ff("")p Fq(\),)h(in)d(which)h(c)o(ase)h(no)f(ar)o(gument)g(t)o(ail)24 39 y(is)i(used.)-18 121 y Fo(\017)21 b Fq(The)13 b(last)h(ar)o(gument)g (is)e(the)i(c)o(ommand)h(t)o(ail)e(\(a)h Fp(string)p Fq(\).)19 b(The)13 b(c)o(ommand)24 171 y(run)j(b)o(y)g(the)h Fp(e)o(x)o(ecut)o(e\(\))g Fq(function)f(is)g(post\014x)o(ed)h(with)f (this)g(string.)27 b(The)24 221 y(string)13 b(may)g(be)g(empt)o(y)i (\(i.e.,)f Ff("")p Fq(\),)g(in)f(which)g(c)o(ase)h(no)f(c)o(ommand)i(t) o(ail)e(is)24 271 y(used.)-18 360 y(Aft)o(er)f(e)o(x)o(ecution,)g Fp(e)o(x)o(ecut)o(e\(\))f Fq(r)o(eset)o(s)h(the)f(c)o(ommand)h(head,)g (c)o(ommand)g(t)o(ail,)-59 410 y(ar)o(gument)h(head)f(and)h(ar)o (gument)g(t)o(ail)f(t)o(o)i(empt)o(y)g(strings.)-18 460 y(The)21 b(following)e(listing)f(shows)i(an)g(e)o(x)o(ample)g(of)g(the) h(use)f(of)g Fp(e)o(x)o(ecut)o(e\(\))p Fq(.)-59 509 y(It)c(inv)o(olv)o (es)g(the)g(Micr)o(osoft)h(Libr)o(ar)o(y)g(Manager.)28 b(This)16 b(pr)o(ogr)o(am,)j(which)c(is)-59 559 y(c)o(alled)d Fp("lib")p Fq(,)h(has)e(always)h(the)g(libr)o(ar)o(y)h(name)f(t)o(o)h (pr)o(oc)o(ess)h(as)d(\014r)o(st)i(ar)o(gument)-59 609 y(\(the)h(c)o(ommand)g(head\).)19 b(Following)12 b(this)h(ar)o(gument,) h(all)f(object)i(\014les)d(which)-59 659 y(should)i(be)i(pr)o(oc)o (essed)h(ar)o(e)f(st)o(at)o(ed)h(pr)o(ec)o(eded)g(b)o(y)f(a)f(string)g (which)g(speci\014es)-59 709 y(the)j(t)o(ype)h(of)f(oper)o(ation.)35 b(The)18 b(t)o(ype)h(of)f(oper)o(ation)h(is,)g(e.g.,)h Fp("{+")e Fq(which)-59 758 y(speci\014es)c(that)h(an)f(object)i(should) d(be)h(r)o(eplac)o(ed)i(in)e(the)g(libr)o(ar)o(y.)23 b(Following)-59 808 y(this,)12 b(a)g(semic)o(olon)h(must)g(close)f(the) h(c)o(ommand)g(line)f(t)o(o)h(pr)o(e)o(v)o(ent)h(the)e(libr)o(ar)o(y) -59 858 y(manager)h(of)f(asking)g(for)g(the)h(new)f(libr)o(ar)o(y)h (name)g(et)o(c..)154 937 y Fe(list)225 977 y(objfiles;)154 1055 y(//)18 b(objfiles)e(is)h(set)g(to)g(a)h(list)f(of)g(all)g (objects)154 1095 y(objfiles)f(=)i(makelist)e(\("*.obj"\);)154 1174 y(execute)g(\(0,)195 b(//)18 b(REQUIRE_ZERO)314 1213 y("lib",)123 b(//)18 b(the)f(program)f(name)314 1253 y("prog.lib",)33 b(//)18 b(the)f(command)f(head)314 1292 y("-+",)141 b(//)18 b(the)f(argument)f(head:)g(replacement)314 1331 y(objfiles,)69 b(//)53 b(of)18 b(all)f(object)f(files)314 1371 y("",)177 b(//)18 b(no)f(argument)f(tail)314 1410 y(";"\);)141 b(//)18 b(command)e(tail:)h(semicolon)154 1489 y(//)h(this)e(may)i(lead)e(to)i(e.g.:)154 1529 y(//)g("lib)e (prog.lib)g(-+a.obj)h(-+b.obj)f(-+c.obj)g(;")-18 1657 y Fq(The)e(same)f(e\013ect)i(using)c(function)i Fp(e)o(x)o(ec\(\))g Fq(c)o(ould)h(be)f(ac)o(c)o(omplished)h(in)e(the)-59 1707 y(following)f(manner:)154 1786 y Fe(list)225 1826 y(objfiles;)p eop %%Page: 36 37 36 36 bop -59 -127 a Fn(36)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)154 29 y Fe(objfiles)16 b(=)i(makelist)e (\("*.obj"\);)154 107 y(cmdhead)g(\("prog.lib"\);)f(//)j(set)f(command) f(head)154 147 y(cmdtail)g(\(";"\);)141 b(//)35 b(and)18 b(tail)154 186 y(arghead)e(\("-+"\);)123 b(//)18 b(set)f(argument)f (head)154 226 y(argtail)g(\(""\);)159 b(//)35 b(and)18 b(tail)154 265 y(exec)f(\(0,)g("lib",)g(objfiles\);)154 305 y(cmdhead)f(\(""\);)159 b(//)18 b(clear)e(command)h(head)154 344 y(cmdtail)f(\(""\);)159 b(//)35 b(and)18 b(tail)154 384 y(arghead)e(\(""\);)159 b(//)18 b(clear)e(argument)g(head)154 423 y(argtail)g(\(""\);)159 b(//)35 b(and)18 b(tail)154 502 y(//)g(this)e(may)i(lead)e(to)i(e.g.:)154 541 y(//)g("lib)e (prog.lib)g(-+a.obj)h(-+b.obj)f(-+c.obj)g(;")-18 671 y Fq(Both)10 b(the)g Fp(e)o(x)o(ec\(\))f Fq(and)g Fp(e)o(x)o(ecut)o (e\(\))h Fq(function)f(t)o(erminat)o(e)i(the)f(making)e(pr)o(oc)o(ess) -59 721 y(if)17 b(err)o(or)j(checking)e(is)f(turned)h(on)g(\(mode)h (\015ag)e Fp(P)p 806 721 13 2 v 14 w(CHECK)p Fq(\))i(and)f(if)f(the)h (run)-59 771 y(c)o(ommand)12 b(e)o(xit)o(s)e(with)h(a)g(non-zer)o(o)g (e)o(xit)f(v)o(alue.)16 b(If)10 b(err)o(or)i(checking)f(is)f(o\013,)i (the)-59 821 y(e)o(xit)g(st)o(atus)h(of)f(the)h(child)f(pr)o(oc)o(ess)h (is)f(r)o(eturned.)-59 928 y Fn(e)o(xists)-59 1005 y Fp(\(int\))i(e)o(xist)o(s)f(\(string\):)26 b Fq(This)14 b(function)f(t)o(est)o(s)j(if)d(a)h(\014le)g(e)o(xist)o(s.)21 b(The)14 b(\014le)g(name)-59 1055 y(is)f(supplied)g(as)h(ar)o(gument.) 23 b(A)14 b(non-zer)o(o)h(v)o(alue)f(is)g(r)o(eturned)h(when)e(the)i (\014le)-59 1105 y(e)o(xist)o(s,)d(else,)h(zer)o(o)g(is)f(r)o(eturned.) -18 1154 y(Ex)o(ample:)154 1235 y Fe(if)18 b(\(exists)e(\("main.c"\)\)) 225 1274 y(printf)h(\("file)f(main.c)h(found\\n"\);)154 1314 y(else)225 1353 y(printf)g(\("file)f(main.c)h(not)g(found\\n"\);) -59 1500 y Fn(fgets)-59 1577 y Fp(\(list\))g(fget)o(s)f(\(string,)i (int\):)32 b Fq(This)17 b(function)g(r)o(eads)h(a)f(line)g(of)g(t)o(e)o (xt)h(fr)o(om)g(the)-59 1626 y(\014le)12 b(whose)g(name)h(is)f(giv)o (en)g(as)g(it)o(s)g(\014r)o(st)h(\(string\))g(ar)o(gument.)k(R)o (eading)12 b(st)o(art)o(s)-59 1676 y(at)j(the)f(o\013setposition)h (speci\014ed)e(in)g(the)i(sec)o(ond)f(\(int\))h(ar)o(gument.)22 b(A)14 b(list)f(is)-59 1726 y(r)o(eturned,)19 b(c)o(ont)o(aining)e(as)f (it)o(s)h(\014r)o(st)g(element)h(the)f(string)f(which)g(was)g(r)o(ead,) -59 1776 y(including)g(the)i(\014nal)f(newline)g(char)o(act)o(er)k (\(as)d(it)h(is)e(r)o(eturned)i(b)o(y)f(the)g Fn(C++)-59 1826 y Fq(function)e Fp(fget)o(s\(\))7 b Fq(\).)30 b(The)17 b(sec)o(ond)g(element)h(of)f(the)g(r)o(eturned)h(list)e(c)o(ont)o(ains) p eop %%Page: 37 38 37 37 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(37)-59 -11 y Fq(the)17 b(string)f(r)o(epr)o(esent)o(ation)i(of)f (the)f(o\013set)i(of)e(the)h(\014le)f Fp(aft)o(er)24 b Fq(the)17 b(line)f(was)-59 39 y(r)o(ead.)h(This)12 b(string)g(c)o(an)h(be)f(c)o(ast)i(t)o(o)g(an)e(int.)-18 91 y(Ex)o(ample:)154 184 y Fe(//)18 b(showing)e(the)h(file)g(info.doc)f (on)h(the)g(screen:)154 223 y(int)225 263 y(offset;)154 302 y(list)225 342 y(l;)154 421 y(for)154 460 y(\()225 499 y(offset)g(=)g(0;)296 539 y(l)h(=)g(fgets\("info.do)o(c",)d (offset\);)368 578 y(offset)h(=)i(\(int\)element\(1)o(,)d(l\))154 618 y(\))225 657 y(printf\(element\(0,)f(l\)\);)-59 817 y Fn(fprintf)-59 898 y Fp(\(int\))j(fprintf)e(\(string,)i Fl(:)7 b(:)g(:)e Fp(\):)33 b Fq(This)16 b(function)h(appends)f (information)h(t)o(o)h(the)-59 948 y(\014le)c(whose)g(name)h(is)f(giv)o (en)g(as)g(it)o(s)h(\014r)o(st)g(string)f(ar)o(gument.)23 b(The)15 b(r)o(emaining)-59 997 y(ar)o(gument)o(s)i(de\014ne)g(the)g (information)g(which)g(is)f(writt)o(en)i(t)o(o)g(the)f(\014le.)29 b(The)-59 1047 y(information)11 b(is)f(always)g(appended)g(t)o(o)i(an)f (e)o(xisting)d(\014le,)j(which)f(is)g(opened)h(in)-59 1097 y(t)o(e)o(xtmode.)-18 1149 y Fp(fprintf\(\))20 b Fq(act)o(s)14 b(analogously)e(t)o(o)j Fp(printf\(\))20 b Fq(\(see)14 b(below\),)g(but)f(the)h(informa-)-59 1199 y(tion)f(is)e(writt)o(en)j(t)o(o)f(\014le,)g(r)o(ather)h(than)e(t)o(o)i (scr)o(een.)-18 1251 y(The)e(ar)o(gument)o(s)g(be)o(y)o(ond)g(the)g (\014r)o(st)g(ar)o(gument)g(of)f Fp(fprintf\(\))18 b Fq(de\014ne)11 b(the)h(in-)-59 1301 y(formation)h(t)o(o)h(print)e(and)g (may)h(be)g Fp(int)p Fq(s,)e Fp(list)p Fq(s)g(or)i Fp(string)p Fq(s.)-18 1353 y(Ex)o(ample:)154 1446 y Fe(fprintf)j(\("file.txt",)g (1,)314 1485 y(")i(line)f(written)f(to)h(file.txt\\n"\);)-59 1645 y Fn(get)p 4 1645 13 2 v 15 w(base)-59 1726 y Fp(\(string\))c(get) p 158 1726 V 15 w(base)h(\(string\):)26 b Fq(This)13 b(function)g(r)o(eturns)h(the)g(basename)h(of)e(the)-59 1776 y(\014lename)f(st)o(or)o(ed)i(in)e(the)g(string)g(ar)o(gument.)17 b(The)12 b(empt)o(y)h(string)f(is)g(r)o(eturned)-59 1826 y(if)g(the)i(ar)o(gument)f(c)o(ont)o(ains)h(no)f(basename.)19 b(This)12 b(happens)h(when)f(a)h(disk)g(or)p eop %%Page: 38 39 38 38 bop -59 -127 a Fn(38)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fq(a)g(r)o(oot)h(dir)o(ect)o(or)o(y)h(is) d(speci\014ed)g(in)g Fp(string.)k Fq(It)d(may)g(also)f(happen)g(if)g (the)h(s)o(ynt)o(ax)-59 39 y(rules)h(for)h(a)f(\014lename)h(speci\014c) o(ation)g(ar)o(e)g(violat)o(ed.)-18 93 y(Ex)o(ample:)154 193 y Fe(printf\(get_base)i(\("c:/path/main.)o(c"\)\))o(;)154 233 y(//)j(prints)e(`main')154 312 y(printf\(get_base)f (\("c:main.c"\)\);)154 351 y(//)j(prints)e(`main')154 430 y(printf\("No)g(basename:)g(",)h(get_base)f(\("c:/"\)\);)154 469 y(//)i(prints)e(`No)h(basename:)f(')-59 638 y Fn(getch)-59 721 y Fp(\(string\))d(get)o(ch)f(\(\):)25 b Fq(This)12 b(function)h(r)o(eturns)h(one)f(char)o(act)o(er)j(as)d(a)g(ministring.) -59 771 y(The)d(char)o(act)o(er)i(is)d(r)o(ead)h(fr)o(om)g(the)g(st)o (andar)o(d)h(input)d(str)o(eam)j(\(usually)d(the)i(k)o(e)o(y-)-59 821 y(boar)o(d\).)-18 875 y(Under)17 b(UNIX,)g(this)f(function)f(wait)o (s)i(until)f(a)g(k)o(e)o(y)h(and)g(the)f(ent)o(er)i(k)o(e)o(y)f(is)-59 925 y(pr)o(essed.)g(Under)12 b(DOS,)h(only)f(one)h(k)o(e)o(y)g(needs)f (t)o(o)i(be)e(pr)o(essed.)-18 978 y(Ex)o(ample:)154 1079 y Fe(printf\(getch\(\)\);)32 b(//)18 b(prints)e(a)i(character)474 1118 y(//)g(\(or)f(an)g(empty)g(string\))-59 1287 y Fn(get)p 4 1287 13 2 v 15 w(e)o(xt)-59 1370 y Fp(\(string\))g(get)p 162 1370 V 15 w(e)o(xt)g(\(string\):)34 b Fq(This)17 b(function)g(r)o(eturns)i(the)f(e)o(xt)o(ension)f(in)g(the)-59 1420 y(string)12 b(ar)o(gument)h(of)f(the)h(function.)-18 1474 y(The)e(empt)o(y)g(string)e(is)h(r)o(eturned)h(if)f(the)g(ar)o (gument)h(c)o(ont)o(ains)g(no)f(e)o(xt)o(ension.)-18 1528 y(Ex)o(ample:)154 1628 y Fe(printf\(get_ext)15 b (\("c:/path/main.c)o("\)\);)154 1668 y(//)j(prints)e(`c')154 1747 y(printf\(get_ext)f(\("c:main"\)\);)154 1786 y(//)j(returns)e (empty)g(string)p eop %%Page: 39 40 39 39 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(39)-59 -11 y(get)p 4 -11 13 2 v 15 w(path)-59 66 y Fp(\(string\))10 b(get)p 155 66 V 15 w(path)g(\(string\):)23 b Fq(This)10 b(function)g(r)o(eturns)h(the)h(path)f(st)o(or)o(ed)h(in)e (the)-59 116 y(string)h(ar)o(gument)i(of)f(the)g(function.)k(An)c(empt) o(y)h(string)e(is)h(r)o(eturned)h(if)e Fp(string)-59 165 y Fq(c)o(ont)o(ains)h(neither)g(a)g(disk)f(speci\014er)h(nor)g(a)g (dir)o(ect)o(or)o(y)i(separ)o(at)o(or)g(\(a)e(forwar)o(d-)-59 215 y(or)j(backwar)o(d)h(slash\).)22 b(The)15 b(function)f(r)o(eturns)h (the)g(longest)f(possible)g(path-)-59 265 y(name)f(which)f(c)o(an)h(be) f(deriv)o(ed)h(fr)o(om)g(the)g(string)f(ar)o(gument.)-18 315 y(Ex)o(ample:)154 396 y Fe(printf\(get_path)j(\("c:/path/main.)o (c"\)\))o(;)154 436 y(//)j(prints)e(`c:/path/')154 515 y(printf\(get_path)f(\("c:main.c"\)\);)154 554 y(//)j(prints)e(`c:')154 633 y(printf\(get_path)f(\("c:/"\)\);)154 672 y(//)j(prints)e(`c:/')-59 820 y Fn(getpid)-59 897 y Fp(\(int\))9 b(getpid)f(\(\))h Fq(This)f(function)h(r)o(eturns)g(under)g(UNIX)g(the)g(pr)o(oc)o(ess)h (number)f(of)-59 946 y(the)i(curr)o(ently)g(e)o(x)o(ecuting)f Fp(icmak)o(e)i Fq(pr)o(ogr)o(am.)17 b(Under)11 b(MS-DOS,)f(wher)o(e)h (pr)o(o-)-59 996 y(c)o(ess)k(ID)f(number)o(s)h(hav)o(e)g(no)f(special)h (meaning)f(sinc)o(e)h(no)f(par)o(allel)h(pr)o(ogr)o(am)-59 1046 y(may)i(be)g(run,)i Fp(getpid)d(\(\))i Fq(r)o(eturns)g(the)f (segment)g(of)g(the)h(memor)o(y)g(loc)o(ation)-59 1096 y(wher)o(e)11 b(the)g(e)o(x)o(ecut)o(or)i Fp(icm-e)o(x)o(ec)d Fq(is)f(loaded)i(\(this)g(v)o(alue)f(is)g(the)h(PSP)g(addr)o(ess\).)-18 1146 y(Ex)o(ample:)83 1227 y Fe(//)18 b(this)e(function)g(kills)h(the)g (current)f(process..)83 1266 y(//)i(analogous)d(to)j(exit\(\))83 1306 y(//)g(works)e(only)h(under)g(UNIX)83 1345 y(void)g(harakiri)f (\(\))83 1385 y({)154 1424 y(exec)h(\("kill",)f("-9",)h(getpid)f (\(\)\);)83 1464 y(})83 1542 y(//)i(this)e(function)g(returns,)g(under) h(UNIX,)83 1582 y(//)h(a)f(name)g(for)g(a)h(temporary)d(file)83 1621 y(//)j(based)e(on)h(the)h(process)e(ID)h(number)83 1661 y(//)h(file)e(names)h(are,)g(eg:)g("/tmp/_TMPFILE.1)o(256")83 1700 y(string)g(tempfilename)e(\(\))83 1740 y({)154 1779 y(return)i(\("/tmp/")f(+)h("_TMPFILE.")f(+)h(\(string\))f(getpid)h (\(\)\);)83 1819 y(})p eop %%Page: 40 41 40 40 bop -59 -127 a Fn(40)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fn(gets)-59 73 y Fp(\(string\))j(get)o(s) h(\(\):)29 b Fq(This)14 b(function)g(r)o(eturns)h(the)g(r)o(eturnv)o (alue)h(of)f(the)g Fn(C)g Fq(func-)-59 123 y(tion)21 b Fp(get)o(s\(\))29 b Fq(as)21 b(a)g(string.)42 b(The)21 b(function)g(ac)o(c)o(ept)o(s)i(char)o(act)o(er,)k(including)-59 173 y(backspac)o(es)15 b(allowing)d(c)o(orr)o(ections,)17 b(until)12 b(the)i Fp(ent)o(er-k)o(e)o(y)22 b Fq(is)13 b(pr)o(essed.)19 b(The)-59 222 y(ent)o(er)o(ed)14 b(char)o(act)o(er)o (s)h(ar)o(e)f(r)o(eturned)f(in)f(a)h(string.)-18 276 y(Ex)o(ample:)154 377 y Fe(printf\(gets\(\)\);)32 b(//)18 b(prints)e(a)i(string)456 416 y(//)g(\(or)f(an)g(empty)g(string\))-59 584 y Fn(makelist)-59 668 y Fp(\(list\))12 b(mak)o(elist)h(\(int,)e (string\):)23 b Fq(This)12 b(function)g(mak)o(es)h(a)g(list)f(of)g (strings,)g(r)o(ep-)-59 718 y(r)o(esenting)g(\014lenames)g(which)g(mat) o(ch)i(the)f(e)o(xpanded)e(form)i(of)f(it)o(s)h(ar)o(gument.)-59 768 y(The)c(ar)o(gument)o(s)h(ar)o(e)g(an)g(optional)f Fp(int)p Fq(,)g(specifying)f(the)h(t)o(ype)h(of)f(dir)o(ect)o(or)o(y)j (en-)-59 818 y(tries)e(t)o(o)h(sear)o(ch)f(for,)h(and)f(a)g Fp(string)p Fq(,)f(specifying)f(the)i(\014le)g(mask.)16 b(The)10 b(r)o(eturned)-59 867 y(list)i(may)h(hold)f(zer)o(o)h(or)g (mor)o(e)h(names.)-18 921 y(The)f(\014r)o(st)g Fp(int)f Fq(ar)o(gument)h(speci\014es)f(the)h(t)o(ype)g(of)g(entries)f(t)o(o)i (sear)o(ch)f(for.)18 b(It)-59 971 y(may)13 b(be)f Fp(O)p 129 971 13 2 v 15 w(FILE)g Fq(\(when)g(sear)o(ching)g(for)h(\014les\),) g Fp(O)p 791 971 V 14 w(DIR)g Fq(\(when)f(sear)o(ching)g(for)-59 1021 y(dir)o(ect)o(ories\))19 b(or)f Fp(O)p 271 1021 V 15 w(SUBDIR)f Fq(\(when)g(sear)o(ching)f(for)i(subdir)o(ect)o (ories\).)31 b(The)-59 1071 y(di\013er)o(enc)o(e)13 b(between)f(the)f (sear)o(ching)g(for)h(dir)o(ect)o(ories)h(and)e(the)g(sear)o(ching)g (for)-59 1120 y(subdir)o(ect)o(ories)k(lies)f(in)g(the)h(fact)g(that)g (the)g(curr)o(ent)h(dir)o(ect)o(or)o(y,)i(denot)o(ed)e(b)o(y)-59 1170 y(".",)k(and)d(the)i(par)o(ent)g(dir)o(ect)o(or)o(y,)j(denot)o(ed) d(b)o(y)f("..",)h(ar)o(e)g(not)g(c)o(onsider)o(ed)-59 1220 y(subdir)o(ect)o(ories)14 b(but)f(ar)o(e)g(c)o(onsider)o(ed)h(dir) o(ect)o(ories.)20 b(This)12 b(ar)o(gument)h(may)g(be)-59 1270 y(absent,)g(in)f(which)f(c)o(ase)j Fp(O)p 399 1270 V 14 w(FILE)f Fq(is)e(assumed.)-18 1324 y(A)f(fourth)g(t)o(ype)g(is)f Fp(O)p 321 1324 V 14 w(ALL)p Fq(.)h(When)g(this)f(t)o(ype)h(is)f(giv)o (en,)h Fp(mak)o(elist)g(\(\))g Fq(sear)o(ches)-59 1373 y(for)15 b(all)g(dir)o(ect)o(or)o(y)i(entries)f(irr)o(espectiv)o(e)g (of)f(their)g(t)o(ype.)25 b(E.g.,)16 b(under)f(DOS,)-59 1423 y(hidden)23 b(and)h(s)o(yst)o(em)i(\014les)d(ar)o(e)j(mat)o(ched)g (as)e(well)g(as)g(normal)h(\014les)f(or)-59 1473 y(\(sub\)dir)o(ect)o (ories.)-18 1527 y(The)e(behavior)g(of)f Fp(mak)o(elist\(\))i Fq(is)d(dependent)i(on)f(the)h(used)f(platform.)-59 1577 y(E.g.,)h(t)o(o)f(sear)o(ch)f(for)g(all)f(\014les)g(or)i(\(sub\)dir)o (ect)o(ories)g(under)f(DOS,)g(the)g(\014le)-59 1626 y(mask)15 b(")p Fo(\003)p Fl(:)p Fo(\003)p Fq(")e(must)i(be)f(giv)o(en.)22 b(The)14 b(\014le)g(mask)h(")p Fo(\003)p Fq(")f(will)g(fail)f(t)o(o)j (\014nd)d(\014les)h(or)-59 1676 y(\(sub\)dir)o(ect)o(ories)f(with)f(an) f(e)o(xt)o(ension.)16 b(Furthermor)o(e,)e Fp(mak)o(elist)e(\(\))h Fq(behav)o(es)-59 1726 y(under)k(DOS)f(similar)h(t)o(o)h(the)f Fn(C)g Fq(run-time)g(functions)p 894 1726 V 31 w Fp(dos)p 978 1726 V 14 w(\014nd\014r)o(st)f(\(\))i Fq(and)p -59 1776 V -47 1776 a Fp(dos)p 24 1776 V 15 w(\014ndne)o(xt)12 b(\(\))p Fq(:)21 b(e.g.,)15 b Fp(mak)o(elist)g(\(O)p 600 1776 V 15 w(DIR,)f("."\))h Fq(r)o(eturns)g(a)g(list)f(c)o(ont)o (aining)-59 1826 y(the)f(name)g(of)f(the)h(curr)o(ent)h(dir)o(ect)o(or) o(y.)p eop %%Page: 41 42 41 41 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(41)-18 -11 y Fq(In)12 b(a)h(similar)f(v)o(ein,)g(the)h(\014lemask) g(")p Fo(\003)p Fq(")f(under)g(UNIX)g(will)g(fail)f(t)o(o)j(\014nd)d (\014les)-59 39 y(or)i(\(sub\)dir)o(ect)o(ories)h(st)o(arting)f(with)f (a)h(dot.)-18 89 y(Ex)o(ample:)154 155 y Fe(list)225 194 y(l;)154 273 y(l)18 b(=)f(makelist)f(\("*.c"\);)154 313 y(printf)h(\("All)f(found)h(*.c)g(files)g(are:)g(",)314 352 y(l,)h("\\n"\);)154 391 y(l)g(=)f(makelist)f(\(IS_SUBDIR,)g ("*.*"\);)154 431 y(printf)h(\("All)f(found)h(subdirectories)e(are:)i (",)314 470 y(l,)h("\\n"\);)-59 615 y Fn(makelist)-59 691 y Fq(The)13 b(function)f Fp(mak)o(elist\(\))i Fq(furthermor)o(e)h (has)d(o)o(v)o(erloaded)i(v)o(er)o(sions,)g(which,)-59 741 y(apart)g(fr)o(om)f(a)g(\014r)o(st)g(optional)g Fp(int)e Fq(indic)o(ating)h(the)h(t)o(ype)g(of)f(entries)h(t)o(o)h(sear)o(ch)-59 791 y(for,)j(e)o(xpect)f(thr)o(ee)h(ar)o(gument)o(s)486 773 y Fj(10)518 791 y Fq(.)26 b(The)16 b(ar)o(gument)o(s)g(of)f(these)h (v)o(er)o(sions)g(ar)o(e)-59 841 y(a)c Fp(string)g(mask)p Fq(;)h(a)f(c)o(omparison)i(oper)o(at)o(or)h(which)c(must)i(be)f Fp(y)o(ounger)p Fq(,)h Fp(newer)-59 891 y Fq(or)g Fp(older)p Fq(;)e(and)h(a)g Fp(string)f(r)o(efer)o(enc)o(e\014le)p Fq(.)18 b(The)12 b(function)g(r)o(eturns)g(a)g(list)g(of)f(\014les)-59 941 y(mat)o(ching)h(the)h(mask)f(which)f(ar)o(e)i(older)g(or)f(newer)h (than)f(the)g(r)o(efer)o(enc)o(e\014le)1227 923 y Fj(11)1261 941 y Fq(.)-59 990 y(An)j(optional)h(\014r)o(st)f Fp(int)f Fq(ar)o(gument,)j(which)e(speci\014es)g(the)g(t)o(ype)h(of)f(dir)o(ect) o(or)o(y)-59 1040 y(entr)o(y)e(\()p Fp(O)p 104 1040 13 2 v 15 w(FILE,)f(O)p 268 1040 V 14 w(DIR)h Fq(or)g Fp(O)p 460 1040 V 15 w(SUBDIR)p Fq(\))g(may)f(be)h(pr)o(esent.)-18 1090 y(Ex)o(ample:)154 1156 y Fe(list)225 1195 y(l;)154 1274 y(l)18 b(=)f(makelist)f(\("*.c",)h(newer,)f("myprog.lib"\);)154 1314 y(printf)h(\("All)f(.c)i(files)e(newer)h(than)g(")296 1353 y("myprog.lib)f(are:)h(",)g(l,)g("\\n"\);)-59 1498 y Fn(printf)-59 1574 y Fp(\(int\))e(printf)g(\(int,)h(...\):)31 b Fq(This)15 b(function)g(displays)f(information.)27 b(The)16 b(ar)o(gu-)-59 1624 y(ment)o(s)10 b(de\014ne)f(the)h (information)g(t)o(o)g(print)g(and)f(may)g(be)h Fp(int)p Fq(s,)f Fp(list)p Fq(s)f(or)i Fp(string)p Fq(s.)-18 1674 y(A)f(list)f(is)g(print)o(ed)h(as)f(a)h(series)f(of)g(all)g(it)o(s)h (element)o(s)g(with)f(spac)o(es)h(in)f(between.)p -59 1706 534 2 v -35 1734 a Fi(10)1 1745 y Fh(The)h(o)o(v)o(erloaded)h(v)o (er)o(sions)f(ar)o(e)h(in)g(fact)g(macr)o(os,)e(e)o(xpanded)h(b)o(y)h (the)g(c)o(ompiler.)-35 1774 y Fi(11)1 1786 y Fh(The)f(o)o(v)o (erloaded)h(functions)e(ar)o(e)i(handled)f(b)o(y)h(the)g(c)o(ompiler)f Fg(icm-c)o(omp)p Fh(,)h(which)g(gener)o(at)o(es)-59 1826 y(appr)o(opriat)o(e)f(c)o(ode)h(t)o(o)g(mak)o(e)f(a)h(list)g(of)g (\014les)f(and)g(t)o(o)i(weed)e(out)h(a)f(part)h(of)f(this)h(list.)p eop %%Page: 42 43 42 42 bop -59 -127 a Fn(42)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fn(putenv)-59 66 y Fp(put)o(env)i (\(string\):)25 b Fq(This)12 b(function)h(may)h(be)g(used)e(t)o(o)j (set)f(envir)o(onment)g(v)o(ari-)-59 116 y(ables)k(during)f(the)h(e)o (x)o(ecution)h(of)f Fp(icmak)o(e)26 b Fq(pr)o(ogr)o(ams.)36 b(The)18 b(envir)o(onment)-59 166 y(v)o(ariables)12 b(r)o(emain)h (activ)o(e)h(during)d(the)i(c)o(omplet)o(e)i Fp(icmak)o(e)20 b Fq(run.)-18 213 y(Ex)o(ample:)83 287 y Fe(main\(\))83 326 y({)154 366 y(putenv\("CL=/c"\);)32 b(//)18 b(set)f(variable)154 405 y(system\("set"\);)68 b(//)18 b(show)e(settings)83 444 y(})-59 592 y Fn(sizeof)-59 669 y Fp(\(int\))j(sizeof)f(\(list\):) 37 b Fq(This)19 b(function)f(performs)i(the)g(same)g(action)g(as)f Fp(size-)-59 719 y(o\015ist\(\))p Fq(.)-59 828 y Fn(sizeo\015ist)-59 904 y Fp(\(int\))14 b(sizeo\015ist)f(\(list\):)28 b Fq(This)13 b(function)i(det)o(ermines)g(the)g(number)g(of)g(names)-59 954 y(held)d(in)g(a)g(list.)-18 1004 y(Ex)o(ample:)154 1086 y Fe(list)225 1125 y(l;)154 1165 y(int)225 1204 y(i;)154 1283 y(list)17 b(=)h(makelist)e(\("*.c"\);)154 1323 y(i)i(=)f(sizeoflist)f(\(l\);)154 1362 y(printf)h(\("There)f(are)h (",)g(i,)296 1402 y(")h(names)f(in)g(the)g(list.\\n"\);)-59 1550 y Fn(stat)-59 1626 y Fp(\(list\))8 b(st)o(at)g(\(int,)h(string\))p Fq(:)14 b(This)8 b(function)g(att)o(empt)o(s)j(t)o(o)f(r)o(etrie)o(v)o (e)h(\014le)d(attribut)o(es)-59 1676 y(of)j(the)h(\014le)g(speci\014ed) f(b)o(y)g(the)h(sec)o(ond)g Fp(string)f Fq(ar)o(gument.)17 b(The)11 b(\014r)o(st)h Fp(int)f Fq(ar)o(gu-)-59 1726 y(ment)16 b(may)g(be)f Fp(P)p 247 1726 13 2 v 15 w(CHECK)h Fq(or)g Fp(P)p 506 1726 V 15 w(NOCHECK)p Fq(.)g(When)f(absent,)i Fp(P)p 1073 1726 V 14 w(CHECK)f Fq(is)-59 1776 y(assumed.)g(The)c (making)f(pr)o(oc)o(ess)i(is)e(abort)o(ed)i(when)f Fp(st)o(at)f(\(\))h Fq(fails)f(t)o(o)h(r)o(etrie)o(v)o(e)-59 1826 y(\014le)g(attribut)o(es) i(and)e(when)g Fp(P)p 448 1826 V 14 w(CHECK)h Fq(is)f(giv)o(en)g(for)g (the)h(\014r)o(st)g(ar)o(gument.)p eop %%Page: 43 44 43 43 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(43)-59 -11 y Fq(The)13 b(r)o(eturned)g(list)f(holds)g(the)g (following)f(information:)-18 98 y Fo(\017)21 b Fq(The)c(\014r)o(st)g (element)h(is)e(a)h Fp(string)e Fq(r)o(epr)o(esent)o(ation)k(of)e(the)g (mode)h(of)e(the)24 148 y(\014le)11 b(or)h(dir)o(ect)o(or)o(y.)19 b(This)11 b(string)f(c)o(an)i(be)g(c)o(onv)o(ert)o(ed)i(t)o(o)e(an)g Fp(int)e Fq(wher)o(e)i(the)24 198 y(following)f(bit)o(s)h(r)o(epr)o (esent)i(the)f(modes:)74 312 y Fn({)20 b Fq(The)13 b(bit)f Fp(S)p 291 312 13 2 v 15 w(IFDIR)g Fq(is)g(set)h(when)f(the)g(entr)o(y) i(is)d(a)i(dir)o(ect)o(or)o(y.)74 387 y Fn({)20 b Fq(The)11 b(bit)g Fp(S)p 288 387 V 15 w(IFCHR)g Fq(is)f(set)h(when)f(the)h(entr)o (y)g(is)f(a)h(char)o(act)o(er-special.)74 462 y Fn({)20 b Fq(The)13 b(bit)f Fp(S)p 291 462 V 15 w(IFREG)h Fq(is)f(set)h(when)f (the)g(entr)o(y)i(is)d(a)i(r)o(egular)g(\014le.)74 538 y Fn({)20 b Fq(The)13 b(bit)f Fp(S)p 291 538 V 15 w(IREAD)i Fq(is)d(set)i(when)f(the)h(entr)o(y)g(is)f(r)o(eadable.)74 613 y Fn({)20 b Fq(The)13 b(bit)f Fp(S)p 291 613 V 15 w(IWRITE)h Fq(is)e(set)i(when)f(the)h(entr)o(y)g(is)f(writ)o(eable.)74 689 y Fn({)20 b Fq(The)13 b(bit)f Fp(S)p 291 689 V 15 w(IEXEC)h Fq(is)e(set)i(when)f(the)h(entr)o(y)g(is)f(e)o(x)o(ecut)o (able.)-18 802 y Fo(\017)21 b Fq(The)13 b(sec)o(ond)g(element)g(is)f (the)g(\014le)g(size,)h(also)f(r)o(epr)o(esent)o(ed)j(as)d(a)h Fp(string)p Fq(.)-59 934 y Fn(strlen)-59 1018 y Fp(\(int\))e(strlen)g (\(string\))p Fq(:)16 b(This)10 b(function)h(r)o(eturns)h(the)g(number) f(of)h(char)o(act)o(er)o(s)i(in)-59 1068 y(the)d(string)g(which)f(is)h (supplied)e(as)i(it)o(s)g(ar)o(gument.)17 b(It)o(s)11 b(working)g(is)f(analogous)-59 1118 y(t)o(o)k(the)e(function)g Fp(strlen\(\))h Fq(in)f Fn(C)471 1100 y Fj(12)503 1118 y Fq(.)-59 1249 y Fn(strlwr)-59 1334 y Fp(\(string\))d(strlwr)g (\(string\))p Fq(:)14 b(This)8 b(function)h(r)o(eturns)h(a)f(c)o(op)o (y)h(of)f(the)h(string)e(which)-59 1384 y(is)k(supplied)f(as)h(ar)o (gument)h(in)f(lower)h(c)o(ase)666 1366 y Fj(13)699 1384 y Fq(.)-59 1515 y Fn(strupr)-59 1600 y Fp(\(string\))8 b(strupr)h(\(string\))p Fq(:)14 b(This)8 b(function)g(r)o(eturns)i(a)e (c)o(op)o(y)i(of)f(the)g(string)f(which)-59 1650 y(is)k(supplied)f(as)h (ar)o(gument)h(in)f(upper)g(c)o(ase.)p -59 1706 534 2 v -35 1734 a Fi(12)1 1745 y Fh(This)e(function)e(is)i(a)g(macr)o(o,)f (e)o(xpanded)f(b)o(y)i(the)g(c)o(ompiler.)-35 1774 y Fi(13)1 1786 y Fh(The)15 b(string)h(functions)e Fg(strlwr\(\))k Fh(and)d Fg(strupr\(\))i Fh(ar)o(e)e(in)h(fact)f(macr)o(o's,)i(e)o (xpanded)d(b)o(y)i(the)-59 1826 y(c)o(ompiler.)p eop %%Page: 44 45 44 44 bop -59 -127 a Fn(44)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -11 y Fn(strtok)-59 67 y Fp(\(list\))17 b(strt)o(ok)h(\(string,)g(string\):)34 b Fq(This)17 b(function)g(par)o (ses)h(the)h(\014r)o(st)f(string)f(in)-59 116 y(substrings,)c(separ)o (at)o(ed)k(fr)o(om)e(each)g(other)g(b)o(y)g(the)g(separ)o(at)o(or)o(s)h (speci\014ed)e(in)-59 166 y(the)g(sec)o(ond)h(string.)20 b(Each)15 b(substring)d(is)h(an)h(element)h(of)f(the)g(r)o(eturned)h (list.)-59 216 y(If)g(no)h(separ)o(at)o(or)o(s)i(ar)o(e)g(speci\014ed)d (\(i.e.,)j(the)e(sec)o(ond)h(string)e(is)h(empt)o(y\),)i(the)-59 266 y(individual)c(char)o(act)o(er)o(s)20 b(of)c(the)h(\014r)o(st)g (string)f(bec)o(ome)i(the)f(element)o(s)h(of)e(the)-59 316 y(r)o(eturned)d(list.)-18 366 y(Ex)o(ample:)154 449 y Fe(list)225 489 y(l;)154 528 y(int)225 567 y(i;)154 646 y(l)18 b(=)f(strtok\("Hello-worl)o(d\\n")o(,)e("-"\);)154 686 y(printf\("Two)h(elements:)f(",)j(l,)f("\\n"\);)154 765 y(l)h(=)f(strtok\("Hello-worl)o(d\\n")o(,)e(""\);)154 804 y(printf\("A)h(string)g(of)i(",)f(sizeof\(l\),)279 844 y(")g(characters\\n"\);)-59 1033 y Fn(substr)-59 1110 y Fp(\(int\))10 b(substr)e(\(string,)i(string\):)k Fq(This)9 b(function)g(sear)o(ches)i(for)f(the)g(string)f(which)-59 1160 y(is)i(giv)o(en)h(as)f(the)i(sec)o(ond)f(ar)o(gument)h(in)f(the)g (string)f(giv)o(en)h(as)f(\014r)o(st)i(ar)o(gument.)-59 1210 y(The)i(position)g(wher)o(e)h(the)f(sec)o(ond)g(string)g(oc)o(cur) o(s)h(in)f(the)g(\014r)o(st)g(string)g(is)f(r)o(e-)-59 1259 y(turned.)31 b(The)18 b(v)o(alue)f(-1)g(is)f(r)o(eturned)j(when)d (the)i(sec)o(ond)g(string)f(does)g(not)-59 1309 y(oc)o(cur)d(in)e(the)h (\014r)o(st)f(string)382 1291 y Fj(14)414 1309 y Fq(.)-59 1419 y Fn(system)-59 1497 y Fp(\(int\))j(s)o(yst)o(em)h(\(int,)g (string\):)29 b Fq(This)15 b(function)g(activ)o(at)o(es)j(the)e(oper)o (ating)h(s)o(ys-)-59 1547 y(t)o(em's)12 b(c)o(ommand)h(int)o(erpr)o(et) o(er)g(t)o(o)g(run)d(the)i(c)o(ommand)h(de\014ned)d(b)o(y)h(the)h(ar)o (gu-)-59 1596 y(ment.)26 b(The)16 b(string)e(holds)h(the)h(c)o(ommand)h (t)o(o)f(e)o(x)o(ecut)o(e)h(and,)f(if)f(needed,)i(it)o(s)-59 1646 y(ar)o(gument)o(s.)-18 1696 y(The)12 b(\014r)o(st)g(ar)o(gument)g (speci\014es)e(whether)i(a)f(failur)o(e)g(of)h(the)f Fp(s)o(yst)o(em)h(\(\))g Fq(func-)-59 1746 y(tion)h(should)f(t)o (erminat)o(e)k(the)d(making)g(pr)o(oc)o(ess.)20 b(The)13 b(v)o(alue)g(of)h(this)e Fp(int)g Fq(may)p -59 1786 534 2 v -35 1814 a Fi(14)1 1826 y Fh(This)e(function)e(is)i(a)g(macr)o(o,)f (which)h(is)g(e)o(xpanded)e(b)o(y)i(the)g(c)o(ompiler.)p eop %%Page: 45 46 45 45 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(45)-59 -11 y Fq(be)10 b Fp(P)p 28 -11 13 2 v 15 w(CHECK)h Fq(or)g Fp(P)p 277 -11 V 14 w(NOCHECK)p Fq(.)g(This)f(ar)o (gument)g(may)h(be)f(absent,)i(in)d(which)-59 39 y(c)o(ase)j Fp(P)p 63 39 V 14 w(CHECK)g Fq(is)e(assumed.)16 b(The)11 b(r)o(eturn)h(v)o(alue)f(of)g Fp(s)o(yst)o(em)g(\(\))h Fq(is)e(zer)o(o)i(when)-59 89 y(the)g(c)o(ommand)i(c)o(ould)e(suc)o(c)o (essfully)f(be)h(e)o(x)o(ecut)o(ed.)17 b(A)12 b(r)o(eturn)h(v)o(alue)f (which)f(is)-59 139 y(not)16 b(zer)o(o)g(c)o(an)h(only)e(be)g(r)o(ec)o (eiv)o(ed)i(b)o(y)f(the)f(mak)o(e\014le)i(when)e Fp(P)p 1007 139 V 14 w(NOCHECK)h Fq(is)-59 188 y(giv)o(en)c(as)g(\014r)o(st)h (ar)o(gument.)-18 247 y(The)k(de\014nition)e(of)h(a)g(suc)o(c)o(ess)h (or)f(failur)o(e)g(of)g Fp(s)o(yst)o(em)g(\(\))h Fq(depends)e(on)h(the) -59 297 y(used)e(platform.)26 b(Under)15 b(MS-DOS,)f Fp(s)o(yst)o(em)i(\(\))f Fq(suc)o(c)o(eeds)h(if)f(the)g(c)o(ommand)-59 347 y(c)o(ould)c(be)g(e)o(x)o(ecut)o(ed,)i(but)e(no)g(checks)h(on)f (the)g(r)o(eturn)h(v)o(alue)f(of)g(the)g(c)o(ommand)-59 397 y(it)o(self)i(c)o(an)g(be)h(made.)19 b(Under)13 b(UNIX,)h Fp(s)o(yst)o(em)f(\(\))h Fq(suc)o(c)o(eeds)g(if)f(the)g(c)o(ommand)-59 447 y(c)o(ould)18 b(be)f(e)o(x)o(ecut)o(ed)i(and)e(if)g(the)h(r)o (eturn)g(v)o(alue)g(of)f(the)h(c)o(ommand)h(it)o(self)e(is)-59 496 y(zer)o(o.)-59 661 y Fk(3.7)50 b(Pr)o(eloaded)16 b(s)o(ymbols)-59 754 y Fq(Sinc)o(e)d Fp(icmak)o(e)g Fq(c)o(an)h(be)e (used)h(on)f(a)h(v)o(ariet)o(y)h(of)e(platforms,)i(the)f(pr)o(epr)o(oc) o(essor)-59 804 y Fp(icm-pp)i Fq(tries)g(t)o(o)h(mak)o(e)h(an)e(educ)o (at)o(ed)i(guess)d(c)o(onc)o(erning)i(this)e(platform)i(in)-59 854 y(or)o(der)j(t)o(o)f(pr)o(ede\014ne)g(s)o(ymbols,)g(which)f(then)g (c)o(an)h(be)f(used)g(t)o(o)h(c)o(ontr)o(ol)h(the)-59 904 y(\015ow)12 b(of)h(the)g(mak)o(e\014le.)-18 963 y(The)18 b(s)o(ymbols)e(which)h(ar)o(e)h(pr)o(eloaded)g(b)o(y)f Fp(icm-pp)g Fq(ar)o(e)h Fp(MSDOS,)e(UNIX,)-59 1012 y(unix,)d(LINUX,)h (linux,)f(M)p 386 1012 V 14 w(SYSV,)h(M)p 574 1012 V 15 w(UNIX)g Fq(and)p 801 1012 V 29 w Fp(POSIX)p 945 1012 V 13 w(SOURCE)1124 995 y Fj(15)1156 1012 y Fq(.)g(Each)-59 1062 y(of)g(these)g(s)o(ymbols)g(is)f(r)o(ede\014ned)h(t)o(o)i(a)e (number:)20 b(r)o(espectiv)o(ely)15 b(1)e(when)h(`on')-59 1112 y(or)f(0)f(when)g(`o\013'.)17 b(E.g.,)c(the)g(c)o(ode)g(fr)o (agment)12 1239 y Fe(if)k(\(MSDOS\))83 1278 y(printf)g(\("Hey,)f(we're) h(running)f(under)h(DOS!\\n"\);)12 1317 y(else)83 1357 y(printf)g(\("Hmmm..)f(no)h(DOS..\\n"\);)-59 1524 y Fq(should)11 b(print)h(a)g(message)g(c)o(onc)o(erning)h(the)g(usage)e(of)h(an)g (MSDOS)g(platform.)-18 1583 y(Not)o(e)i(that)e Fp(icmak)o(e)h Fq(support)o(s)f(no)g Fp(#ifdef)e Fq(-)i Fp(#else)f Fq(-)h Fp(#endif)f Fq(c)o(onstructions:)-59 1633 y(the)i(pr)o(eloaded)g(s)o (ymbols)f(must)h(be)f(used)g(in)g Fp(if)g Fq(-)g Fp(else)g Fq(c)o(onstruct)o(s.)p -59 1707 534 2 v -35 1735 a Fi(15)1 1747 y Fh(These)g(names)g(ar)o(e)h(v)o(alid)g(for)g(the)f(default)h (inst)o(allation)f(of)h Fg(icmak)o(e)p Fh(.)22 b(An)12 b(actual)g(inst)o(alla-)-59 1786 y(tion)f(on)f(an)h(`e)o(x)o(otic')h (platform)e(may)h(use)g(an)g(additional)f(or)h(slightly)h(di\013er)o (ent)f(s)o(ymbol)h(name,)-59 1826 y(depending)d(on)g(the)h(c)o (ompilation)f(of)g(the)h Fg(icmak)o(e)p Fh(.)j(pr)o(ogr)o(ams)p eop %%Page: 46 47 46 46 bop -59 -127 a Fn(46)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)-59 -10 y Fm(4)60 b(Summar)o(y)-59 109 y(A)f(K)o(e)o(ywor)o(ds)-59 203 y Fq(The)13 b(following)d(t)o(able) k(shows)d(the)i(k)o(e)o(ywor)o(ds)h(of)e(the)h Fp(icmak)o(e)h Fq(language.)p -23 271 1262 2 v 2 306 a(ar)o(ghead)71 b(ar)o(gt)o(ail)84 b(ascii)202 b(br)o(eak)148 b(chdir)2 356 y(cmdhead)51 b(cmdt)o(ail)64 b(change)p 570 356 13 2 v 15 w(base)50 b(change)p 857 356 V 15 w(e)o(xt)f(change)p 1113 356 V 15 w(path)2 406 y(echo)136 b(element)50 b(else)211 b(e)o(x)o(ec)175 b(e)o(x)o(ecut)o(e)2 456 y(e)o(xist)o(s)117 b(fget)o(s)e(for)232 b(fprintf)132 b(get)p 1039 456 V 16 w(base)2 505 y(get)p 64 505 V 16 w(e)o(xt)91 b(get)o(ch)105 b(get)p 496 505 V 16 w(path)123 b(get)o(s)178 b(if)2 555 y(int)171 b(list)146 b(mak)o(elist)123 b(newer)137 b(older)2 605 y(printf)115 b(put)o(env)72 b(r)o(eturn)166 b(sizeof)147 b(sizeo\015ist)2 655 y(st)o(at)153 b(string)95 b(strlwr)172 b(strt)o(ok)142 b(strupr)2 705 y(s)o(yst)o(em)91 b(while)101 b(y)o(ounger)p -23 721 1262 2 v -59 844 a Fm(B)60 b(S)o(ymbolic)18 b(c)o(onst)o(ant)o(s)-59 939 y Fq(The)13 b(following)d(s)o(ymbolic)j(c)o(onst)o(ant)o(s)h(ar)o(e)f (de\014ned:)p 175 1007 866 2 v 200 1042 a(Name)143 b(v)o(alue)50 b(Name)186 b(v)o(alue)p 175 1058 V 200 1093 a(OFF)258 b(0)50 b(ON)317 b(1)p 175 1110 V 200 1144 a(P)p 229 1144 13 2 v 16 w(CHECK)153 b(0)50 b(P)p 641 1144 V 15 w(NOCHECK)132 b(2)p 175 1161 866 2 v 200 1196 a(O)p 233 1196 13 2 v 16 w(FILE)201 b(1)50 b(O)p 645 1196 V 15 w(DIR)257 b(2)200 1246 y(O)p 233 1246 V 16 w(SUBDIR)130 b(4)50 b(O)p 645 1246 V 15 w(ALL)260 b(8)p 175 1262 866 2 v 200 1297 a(S)p 225 1297 13 2 v 15 w(IFDIR)180 b(1)50 b(S)p 637 1297 V 14 w(IFCHR)212 b(2)200 1347 y(S)p 225 1347 V 15 w(IFREG)176 b(4)50 b(S)p 637 1347 V 14 w(IREAD)213 b(8)200 1397 y(S)p 225 1397 V 15 w(IWRITE)127 b(16)50 b(S)p 637 1397 V 14 w(IEXEC)199 b(32)p 175 1413 866 2 v -59 1532 a Fm(C)60 b(Binar)o(y)18 b(oper)o(at)o(or)o(s)-59 1626 y Fq(In)d(the)g(following) f(t)o(able,)k(`all')d(means)g(that)h(the)g(t)o(ype)g(of)g(the)f(oper)o (and)i(left)-59 1676 y(of)h(the)g(oper)o(at)o(or)j(must)d(be)g(equal)g (t)o(o)h(the)f(t)o(ype)h(of)f(the)g(oper)o(and)h(right)f(of)-59 1726 y(the)d(oper)o(at)o(or.)25 b(The)15 b(oper)o(at)o(or)o(s)i(at)f (the)e(t)o(op)i(of)f(the)f(t)o(able)i(hav)o(e)e(the)h(lowest)-59 1776 y(priorit)o(y.)30 b(The)17 b(assignment)e(oper)o(at)o(or)o(s)20 b(ar)o(e)d(right-associativ)o(e,)i(the)e(other)-59 1826 y(binar)o(y)12 b(oper)o(at)o(or)o(s)j(ar)o(e)f(left-associativ)o(e.)p eop %%Page: 47 48 47 47 bop -59 -127 a Fp(ICMAKE)p 124 -127 1094 2 v 1119 w Fn(47)p 102 -51 1014 2 v 178 -23 a Fc(Operator)100 b(Operation)243 b(Allowed)10 b(types)p 102 -10 V 242 18 a Fh(,)165 b(sequential)9 b(e)o(v)o(aluation)63 b(all)10 b(\(mix)o(ed\))p 102 31 V 234 59 a(=)157 b(assignment)221 b(all)140 99 y({=)9 b(+=)g Fb(\003)p Fh(=)h(/=)63 b(c)o(ompound)8 b(assignment)49 b(arithm.)10 b(oper)o(at)o(or)o(s)170 138 y(\045=)f(&=)g Fb(j)p Fh(=)224 177 y(^)g(=)p 102 191 V 237 219 a Fb(jj)161 b Fh(logic)o(al)10 b(or)254 b(all)10 b(\(mix)o(ed\))p 102 232 V 222 260 a(&&)146 b(logic)o(al)10 b(and)230 b(all)10 b(\(mix)o(ed\))p 102 273 V 242 301 a Fb(j)166 b Fh(bitwise)10 b(or)241 b Fg(int)p 102 314 V 242 342 a Fh(^)165 b(e)o(x)o(clusiv)o(e)10 b(or)215 b Fg(int)p 102 355 V 235 383 a Fh(&)158 b(bitwise)10 b(and)217 b Fg(int)p 102 396 V 151 424 a Fa(<)11 b(>)f(<)p Fh(=)f Fa(>)p Fh(=)75 b(c)o(omparison)216 b Fg(int,)10 b(string)126 463 y Fh(newer,)g(y)o(ounger)49 b(\014le)10 b(dat)o(e)271 b Fg(string)207 503 y Fh(older)129 b(\014le)10 b(dat)o(e)271 b Fg(string)p 102 516 V 220 544 a Fa(<<)144 b Fh(left)o(shift)277 b Fg(int)220 583 y Fa(>>)144 b Fh(right)o(shift)p 102 597 V 234 624 a(+)157 b(addition)266 b(all)239 664 y({)162 b(subtr)o(action)220 b Fg(int,)10 b(list)p 102 677 V 238 705 a Fb(\003)162 b Fh(multiplic)o(ation)179 b Fg(int)239 744 y Fh(/)162 b(division)274 b Fg(int)237 784 y Fh(\045)160 b(modulo)277 b Fg(int)p 102 797 V -59 903 a Fm(D)60 b(Unar)o(y)17 b(oper)o(at)o(or)o(s)-59 993 y Fq(All)25 b(unar)o(y)h(oper)o(at)o(or)o(s)i(ar)o(e)f (right-associativ)o(e.)56 b(The)26 b(e)o(x)o(c)o(eption)g(is)f(the)-59 1043 y(e)o(xpr)o(ession-nesting)7 b(oper)o(at)o(or,)14 b(which)9 b(surr)o(ounds)g(an)h(e)o(xpr)o(ession)f(and)g(does)-59 1093 y(not)k(associat)o(e.)p 182 1122 853 2 v 207 1150 a Fc(Operator)48 b(Operation)182 b(Allowed)10 b(types)p 182 1163 V 270 1191 a Fh(!)112 b(logic)o(al)10 b(not)174 b(all)271 1230 y(~)113 b(bitwise)11 b(not)160 b Fg(int)263 1269 y Fh(+)105 b(unar)o(y)10 b(plus)172 b(all)268 1309 y({)110 b(unar)o(y)10 b(minus)142 b Fg(int)250 1348 y Fh(++)91 b(incr)o(ement)179 b Fg(int)10 b Fh(\(v)o(ariable)h(only\))255 1388 y({)e({)97 b(decr)o(ement)171 b Fg(int)10 b Fh(\(v)o(ariable)h (only\))230 1427 y(\()p Fg(t)o(ype)p Fh(\))75 b(t)o(ype)11 b(c)o(ast)197 b(see)10 b(3.5)260 1467 y(\()g(\))103 b(e)o(xpr)o(ession) 9 b(nesting)49 b(all)p 182 1480 V -59 1585 a Fm(E)60 b(T)o(ype)18 b(c)o(ast)o(s)-59 1676 y Fq(The)12 b(following)f(t)o(able) i(shows)f(the)g(allowed)g(t)o(ype)h(c)o(ast)o(s.)18 b(\(Ok\))c(is)d (used)h(in)f(the)-59 1726 y(t)o(able)17 b(t)o(o)h(indic)o(at)o(e)f (that)h(no)e(special)h(action)g(is)f(needed.)29 b(The)17 b(c)o(onv)o(er)o(sions)-59 1776 y Fp(it)o(oa)p Fq(,)i Fp(at)o(oi)e Fq(and)g Fp(at)o(ol)g Fq(specify)g(r)o(espectiv)o(ely)i Fp(int)d(t)o(o)h(ascii)p Fq(,)i Fp(ascii)d(t)o(o)h(int)g Fq(and)-59 1826 y Fp(ascii)11 b(t)o(o)h(list)p Fq(.)p eop %%Page: 48 49 48 48 bop -59 -127 a Fn(48)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)p 280 -51 657 2 v 537 -11 2 40 v 653 -23 a Fh(c)o(ast)f(r)o(esult:)p 538 -10 399 2 v 537 28 2 40 v 563 16 a(\(int\))51 b(\(string\))f(\(list\))p 280 30 657 2 v 305 57 a(c)o(ast)10 b(oper)o(and:)p 537 69 2 40 v 280 71 259 2 v 387 97 a(int)p 537 109 2 40 v 135 w(\(ok\))79 b(it)o(oa)94 b(|)364 136 y(string)p 537 148 V 113 w(at)o(oi)78 b(\(ok\))j(at)o(ol)p 280 150 657 2 v 288 180 a(\(ok\))11 b(means:)h(no)d(special)h(c)o(asting)g (performed)-59 440 y Fm(F)59 b(Oper)o(and)18 b(matrix)p 375 584 2 40 v 443 573 a Fc(int)p 550 584 V 140 w(string)p 787 584 V 146 w(list)p 979 584 V 236 586 744 2 v 375 625 2 40 v 413 614 a Fg(all)10 b(but)p 550 625 V 787 625 V 979 625 V 375 665 V 416 653 a Fh(newer)p 550 665 V 787 665 V 979 665 V 261 693 a Fc(int)p 375 704 V 120 w Fh(older)p 550 704 V 148 w(|)p 787 704 V 181 w(|)p 979 704 V 375 744 V 401 732 a(y)o(ounger)p 550 744 V 787 744 V 979 744 V 375 783 V 550 783 V 787 783 V 979 783 V 236 785 744 2 v 375 824 2 40 v 550 824 V 599 812 a(==)g(!=)f Fa(>)p 787 824 V 979 824 V 375 864 V 550 864 V 592 852 a(<)h(<)p Fh(=)g Fa(>)p Fh(=)p 787 864 V 979 864 V 261 891 a Fc(string)p 375 903 V 97 w Fh(|)p 550 903 V 126 w(+)g(+=)f(=)p 787 903 V 134 w(|)p 979 903 V 375 943 V 550 943 V 576 931 a(newer)h(older)p 787 943 V 979 943 V 375 982 V 550 982 V 607 970 a(y)o(ounger)p 787 982 V 979 982 V 236 984 744 2 v 375 1023 2 40 v 550 1023 V 787 1023 V 979 1023 V 375 1063 V 550 1063 V 787 1063 V 832 1051 a(==)g(!=)p 979 1063 V 261 1090 a Fc(list)p 375 1102 V 138 w Fh(|)p 550 1102 V 173 w(|)p 787 1102 V 171 w(+)g({)p 979 1102 V 375 1141 V 550 1141 V 787 1141 V 813 1130 a(+=)f({=)g(=)p 979 1141 V 375 1181 V 550 1181 V 787 1181 V 979 1181 V 236 1183 744 2 v -59 1419 a Fm(G)60 b(Number)o(s)18 b(and)f(identi\014er)o(s)-59 1553 y Fq(Number)o(s)c(ar)o(e)h(int)o(egr)o(al)f(v)o(alues)g(of)f(at)i (most)g(32767)e(\(negativ)o(e)h(number)o(s)g(ar)o(e)-59 1603 y(obt)o(ained)g(using)e(e.g.,)h(the)h(unar)o(y)f(minus.)-18 1676 y(Identi\014er)o(s)22 b(ar)o(e)h Fn(C)p Fq(-lik)o(e)e (identi\014er)o(s:)35 b(the)o(y)22 b(st)o(art)h(with)e(an)h(under)o(sc) o(or)o(e)-59 1726 y(or)i(lett)o(er,)29 b(and)23 b(c)o(onsist)h (furthermor)o(e)h(of)f(alphanumeric)f(char)o(act)o(ers)j(or)-59 1776 y(under)o(sc)o(or)o(es.)49 b(The)23 b Fp(icm-c)o(omp)29 b Fq(c)o(ompiler)24 b(int)o(erpr)o(et)o(s)g(identi\014er)o(s)f(c)o (ase-)-59 1826 y(sensitiv)o(ely.)p eop %%Page: 49 50 49 49 bop -59 -127 a Fp(Inde)o(x)p 61 -127 1156 2 v 1180 w Fn(49)-59 -10 y Fm(H)60 b(Esc)o(ape)18 b(sequenc)o(es)p 238 52 740 2 v 263 80 a Fc(Escape)10 b(sequence)48 b(Action)p 238 93 V 374 121 a Fb(n)p Fh(a)161 b(alert)9 b(\(bell\))373 161 y Fb(n)p Fh(b)160 b(backspac)o(e)8 b(char)o(act)o(er)378 200 y Fb(n)p Fh(f)164 b(formfeed)8 b(char)o(act)o(er)373 239 y Fb(n)p Fh(n)160 b(newline)376 279 y Fb(n)p Fh(r)j(c)o(arriage)9 b(r)o(eturn)h(char)o(act)o(er)377 318 y Fb(n)p Fh(t)163 b(t)o(ab)374 358 y Fb(n)p Fh(v)e(v)o(ertic)o(al)10 b(t)o(ab)341 397 y Fb(n)p Fg(other)127 b Fh(lit)o(er)o(al)11 b Fg(other)p 238 411 V eop %%Page: 50 51 50 50 bop -59 -127 a Fn(50)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)p eop %%Page: 51 52 51 51 bop -59 -127 a Fp(Inde)o(x)p 61 -127 1156 2 v 1180 w Fn(51)p eop %%Page: 52 53 52 52 bop -59 -127 a Fn(52)p -1 -127 937 2 v 961 w Fp(Act)o(a)13 b(Ic)o(cis)e(1994-1)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF icmake-9.02.06/doc/icmake.doc0000644000175000017500000001727313176557635014626 0ustar frankfrank============================================================================= ICMAKE the Intelligent C-like MAKEr, or the ICce MAKE utility Copyright (c) Frank B. Brokken and Karel Kubat frank@icce.rug.nl, karel@icce.rug.nl ICCE, State University of Groningen, Netherlands This document is part of distribution 6.20 of ICMAKE ============================================================================= Introduction ------------ Icmake is a hybrid between a 'make' utility and a 'shell script' language. Originally, it was concocted to provide a useful tool for automatic program maintenance and system administrative tasks on MS-DOS platforms. As we learned to appreciate its flexibility, Icmake was eventually ported to Unix platforms (SCO and Linux). By now Icmake also runs on a HP-Unix platform. To give an impression of "what Icmake does", take a look at the following makefile. It is used for automatic program maintenance, where it is assumed that in some directory all files with the extension ".c" (C source files) constitute a program "myprog". The automatic maintenance makes sure that, once Icmake is invoked, C source files which are more recent (newer) than a library file "libmyprog.a" are recompiled and placed in the library. A new program is then made and installed in a directory "/home/user/bin". void main () { list cfiles; // list of .c files int i; // counter variable string sourcefile; // string with name of // 1 source file cfiles = makelist ("*.c", younger, // cfiles is now a list of "libmyprog.a"); // all files to recompile if (cfiles) // if there are any files.. for (i = 0; i < sizeof (cfiles), // recompile them i++) { sourcefile = element (i, cfiles); // get the name from the list exec ("gcc", "-c -Wall", sourcefile); // recompile } if (makelist ("*.o")) // any "*.o" files here? { exec ("ar", "rvs", "libmyprog.a", "*.o"); // add to library exec ("rm", "*.o"); // remove them exec ("gcc", "-o myprog", "libmyprog.a"); // re-link program exec ("mv", "myprog", "/home/user/bin"); // and install in bin dir } } The source files for Icmake look remarkably like C sourcefiles. The resemblance is so close that this cannot be pure chance! Yes, we have implemented Icmake to be a language with a syntax which largely overlaps C. Since we know how to program in C, we decided that we didn't want to learn some new macro language. The Icmake language is a "subset" of C in the sence that not all operators or functions of C are implemented (but a good deal are, e.g., gets(), getch(), printf(), etc.). The Icmake language has its own extensions to make it a handy language for the purpose of maintenance: e.g., the operator "younger" compares two files in respect to their date of last modification, a type "list" is defined to hold several strings. The usage of Icmake is not restricted to program maintenance. The setup, which allows for functions, arguments, local or global variables, the calling of external programs, etc. makes Icmake also extremely suitable as a shell script language. E.g., it is easy to accomplish to let Icmake figure out which files need to be backupped since the last backup date and to start a process to do so, to send mail about it etc. This guide provides a short description how Icmake can be ported to new platforms. The documentation for the usage of Icmake, including a description of the grammar and of all built-in functions, comes with the distribution files. Installing Icmake ----------------- The icmake-X.YY.tgz contains all source files and installation information if you want to install icmake from scratch. You *need* this file if you want to install icmake on systems not running Linux or Ms-DOS. The icmake-X.YY.bin.tgz contains linux and ms-dos executables. If you only want to use the icmake programs, you can get this file, unpack it and start using icmake. See the file INSTALL for details. INSTALL is in icmake-X.YY.tgz, containing all other files necessary for installing icmake. To unpack the archives use (GNU-tar 1.11.2): tar xzvf icmake-X.YY.tgz and/or: tar xzvf icmake-X.YY.bin.tgz which unpacks into an 'icmake' subdirectory below the current subdirectory. Also, separate gzip and tar steps could be used, as in: gzip -c -d icmake-X.YY.tgz | tar xvf - and/or: gzip -c -d icmake-X.YY.bin.tgz | tar xvf - The Documentation ----------------- Icmake is documented in a Postscript file, "icmake.ps", located in the directory "doc". This file is generated from a .dvi file using dvips, and can be processed with GhostScript. Note that the file is generated for a printer resolution of 300 dpi, which suits a LaserJet family printer. If your site lacks the means to print this file, you can mail us at the address below to obtain a printed copy of the documentation. (However, we will charge you a small amount to cover our costs). The directory "doc" furthermore contains the file "icmake.1". This is a crude "man" page for Unix systems. You can install it by copying it to a directory which contains formatted manual pages. To use this feature, your "man" command must be able to show an already-formatted manual entry. E.g., on Linux systems you can copy this file to "/usr/man/cat1". Typing "man icmake" will then show the information. Some man systems also support compressed manual pages. On these systems you may achieve a lower disk usage by compressing the file "icmake.1" to "icmake.1.Z", using the Unix program "compress". A few makefiles are provided as examples in the directory "examples". You may wish to look at these to see how makefiles can be organized. Some Legal Stuff ---------------- You don't have to pay us for Icmake. This means that no fee is charged for it by us. As with everything that's free, there's no pay but also *absolutely no warranty*. Furthermore, you are allowed (and encouraged) to distribute Icmake, provided that you include this information with each distribution. It is strongly suggested that you do *not* charge money for the distribution of Icmake (possibly not even the $5 for shipping). The source files and the documentation for Icmake are copyrighted by us. The reason for this is (a) that we'd like to have always the last version of Icmake, and (b) that we'd like to have the last word in all modifications. If you have requests (or even better, "working code" to include in Icmake) please mail us and we'll gladly oblige when we find the time. Requests, Bug Reports, etc. --------------------------- We'd very much appreciate it if you'd let us know if you encounter any bugs. Also, if you have requests or comments about the programs or the documentation, mail us. We can be reached at: Frank Brokken Karel Kubat e-mail: F.B.Brokken@icce.rug.nl K.Kubat@icce.rug.nl phone: (+31) 50 63 36 88 (+31) 50 63 36 47 address: Westerhaven 16 Westerhaven 16 Groningen Groningen Netherlands Netherlands ----------------------------------------------------------------------------- (end of icmake.doc) icmake-9.02.06/doc/manpage/0000755000175000017500000000000013237047127014270 5ustar frankfrankicmake-9.02.06/doc/manpage/trailer.inc0000644000175000017500000000030013176557635016432 0ustar frankfrankmanpagesection(COPYRIGHT) This is free software, distributed under the terms of the GNU General Public License (GPL). manpageauthor() Frank B. Brokken (bf(f.b.brokken@rug.nl)). icmake-9.02.06/doc/manpage/icmbuild.yo0000644000175000017500000002640013176557635016447 0ustar frankfrankincludefile(release.yo) htmlbodyopt(text)(#27408B) htmlbodyopt(bgcolor)(#FFFAF0) whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl)) DEFINEMACRO(sop)(3)(\ it() bf(-ARG1) ARG2 nl()ARG3\ ) DEFINEMACRO(itt)(1)(\ it()tt(ARG1)\ ) DEFINEMACRO(itb)(1)(\ it()bf(ARG1)nl()\ ) DEFINEMACRO(icb)(0)(tt(icmbuild)) DEFINEMACRO(Icb)(0)(tt(Icmbuild)) DELETEMACRO(tt) DEFINEMACRO(tt)(1)(em(ARG1)) COMMENT( man-request, section, date, distribution file, general name) manpage(icmbuild)(1)(_CurYrs_)(icmake._CurVers_.tar.gz) (Icmake's generic program maintenance facility) COMMENT( man-request, larger title ) manpagename(icmbuild)(A generic, C++/C program maintenance facility) COMMENT( all other: add after () ) manpagesynopsis() icb() [-h] [-c] tt(args) manpagedescription() Icb() is a small bf(C) program calling bf(icmake)(1) to do program maintenance as defined in the tt(icmbuild) script that's (commonly) found in tt(/usr/lib/icmake). tt(Icmbuild's) actions are tailored through a configuration file (tt(icmconf)) which must be present in the directory where program maintenance is requested. This file is automatically installed by bf(icmstart)(1). Refer to bf(icmconf)(7)'s man-page for details about this file. Icb() assumes that your sources exist in and below the current working directory. The file tt(icmconf) in bf(icmake)(1)'s distribution provides an example of an tt(icmconf) file that can be used by icb(). In that example tt(icmconf) file it is assumed that bf(C++) sources are maintained, but program maintenance for, e.g., bf(C) sources can easily be configured. If icb() is called, but tt(icmconf) is not available it displays a usage-summary after which icm() ends. Icb()() handles the maintenance for all sources in each of the subdirectories named in the file tt(CLASSES), and in addition the maintenance of all sources in the current working directory. `Maintenance' involves compiling all as yet uncompiled source files, recompilation of modified source files, and optionally library maintenance and the pre-compilation of header files, which commonly results in a marked reduction of source compilation times. When source files are compiled object modules are produced which may be stored in a library, against which the object module of the program's tt(main) function is linked. It is also possible to specify additional libraries against which the program must be linked. If a library is constructed it is kept up to date by icb(). When a source is successfully compiled its new object module replaces the old one that is found in the library. At that point the separate object files are no longer required and are removed by icb(). Up to tt(icmake) version 9.01.00 icb() was installed as an executable tt(icmake) script in (commonly) tt(/usr/bin). The dependency of this script on the file tt(icmconf) made it difficult to provide usage information if tt(icmconf) was absent. Since version 9.02.00 the tt(icmbuild) script has been moved to (commonly) tt(/usr/lib/icmake), and tt(icmbuild) now is a little bf(C) program providing the usage information when necessary or requested, but otherwise executes tt(icmake) to process the tt(icmbuild) script. manpagesection(KICK-STARTING ICMBUILD) To use icb() do as follows: itemization( it() Install icb() in your path (tt(icmake's) installation procedure should already have taken care of that); it() Copy tt(icmconf) (and probably a file tt(CLASSES)) to your project's base directory (i.e., the directory in which and where below the project's sources are found). Usually this has already been taken care of by the tt(icmstart) script; ) Next: itemization( it() Modify the tt(#defines) in the file tt(icmconf) to taste; it() Enter the names of subdirectories containing sources on separate lines in the file tt(CLASSES) Note that the order of the classes mentioned in tt(CLASSES) em(is) relevant in that new class (subdirectory) names can always be added at the end of the file tt(CLASSES), but reordering the lines in the tt(CLASSES) file should be avoided. If reordering is necessary, then first run the command tt(icmbuild clean) to remove all files that were thus far created by icb(). Recompilation is necessary as the names of the object files contain class order-numbers for identification. These class-order numbers prevent file-name collisions (e.g., two classes might use a file tt(data.cc)) and because of the number-prefixes replacement of a file tt(x.o) from class tt(A) by file tt(x.o) from class tt(B) is prevented; it() Start tt(icmbuild). ) The next section covers tt(icmbuild's) modes of operation. manpageoptions() Icb() supports two options, at most one should be specified: itemization( itt(-h): Display a usage summary (also automatically shown when the current directory does not contain a file tt(icmconf)); itt(-c): Clear the screen (using tt(tput clear)) before starting the maintenance process. ) Next (after optionally specifying tt(-c)) icb() can be provided with the following arguments: itemization( it() No arguments at all: if tt(icmconf) contains the line verb( #define DEFCOM "program" ) then this is quivalent to the command icb() tt(program);nl() if tt(icmconf) contains the line verb( #define DEFCOM "strip" ) then this is quivalent to the command icb() tt(strip);nl() if if tt(icmconf) contains the line verb( #define DEFCOM "library" ) then this is quivalent to the command icb() tt(library).nl() (these commands are further elaborated in this section.) tt(DEFCOM) specifications are ignored when an explicit argument is passed to icb(). itt(clean)nl() clean up remnants of previous actions; itt(install program )nl() install the constructed program in the specified tt() (to be used after issuing icb() tt(program), see below). Example: verb( icmbuild install ~/bin/program ) This installs the constructed binary program in the user's tt(bin) direcotry with the name tt(program); itt(install static )nl() install the constructed static library in the specified path (to be used after issuing icb() tt(library), see below). Example: verb( icmbuild static /usr/lib/ ) This installs the constructed static library (e.g. tt(libspecial.a)) in tt(/usr/lib) as tt(/usr/lib/libspecial.a).nl() itt(install shared path) install the constructed shared library in the specified path (to be used after issuing icb() tt(library)), when tt(icmconf) defines tt(SHARED) (cf. bf(icmconf)(7)). Example: verb( icmbuild shared /usr/lib/ ) This installs the constructed binary shared library (e.g. tt(libspecial.so)) in tt(/usr/lib) as tt(/usr/lib/libspecial.so). In addition, the soft-links verb( libspecial.so -> libspecial.so.X libspecial.so.X -> libspecial.so.X.Y.Y.Z ) are defined in tt(/usr/lib), where tt(X.Y.Z) are the major, minor and subminor versions defined in the file tt(VERSION). itt(library)nl() do library maintenance (builds a static and optionally (if tt(icmconf) defines tt(SHARED)) a shared (dynamic) library); itt(program)nl() do program maintenance (builds a program from the sources in the current working directory and from the sources in the directories specified in the file tt(CLASSES)); itt(program strip)nl() same as tt(program), but the final program is stripped (using the linker's tt(-s) option); ) manpagesection(ICM-DEP) Class dependencies are handled by tt(icmake)'s support program tt(icm-dep). It can be called from tt(icmake) by passing it the option tt(-d). All options and arguments following tt(-d) are forwared to tt(icm-dep). The program tt(icm-dep) is automatically called by tt(icmbuild) to handle class dependencies. Consider two classes tt(Options) and tt(Process). If tt(Process) uses tt(Options) and if precompiled header files are used, then in addition to tt(Option's) header file, tt(Process's) header must also be precompiled if tt(Option's) header file changes. Likewise, if tt(Option's) data organization is changed and tt(Option) defines inline members used by tt(Process) or tt(Process) defines an tt(Option) data member then, in addition to tt(Option's) sources sources tt(Process's) sources must also be compiled. For the latter case tt(icmconf) uses the tt(USE_ALL) specification: if a tt(`USE_ALL') file exists in a directory, then all sources of that directory are recompiled. The program tt(icm_dep) determines all such class dependencies, and will recompile class header files of all classes depending on classes whose header files must be recompiled. Furthermore, if a tt(`USE_ALL') file exists in a directory then all sources of classes depending on that directory's class are also recompiled. tt(Icm-dep's) options are described in bf(icmake)(1)'s man-page. To start its work, tt(icm_dep) needs one command-line argument: tt(go). Any other argument results in tt(icm_dep) performing a `dry run': it will perform all its duties (and verbose messages are displayed as if tt(go) had been specified), but no files (precompiled headers or tt(USE_ALL) files) will be touched or removed. If neither options nor arguments are specified tt(icm_dep) writes its usage summary to the standard output. By default tt(icmbuild) calls tt(icmake -d -V go): tt(icm_dep) is called to perform its duties and to show its actions on the standard output stream. By specifying a tt(#define ICM_DEP) parameter in the tt(icmconf) file this default can be overruled (cf. bf(icmconf)(7)). manpagefiles() The mentioned paths are sugestive only and may be installation dependent: itemization( it() bf(/usr/share/icmake/icmconf) Unabbreviated example of an icb() configuration file; it() bf(/usr/share/icmake/CLASSES) Example of an icb() tt(CLASSES) file. ) manpagesection(EXAMPLES) Here is an example of the configuration file tt(icmconf) for a concrete program, using facilities of the tt(bobcat) library: verb( #define CLS #define LIBRARY "modules" #define MAIN "main.cc" #define SOURCES "*.cc" #define OBJ_EXT ".o" #define SHAREDREQ "" #define TMP_DIR "tmp" #define USE_ALL "a" #define USE_ECHO ON #define CXX "g++" #define CXXFLAGS " --std=c++14 -Wall -O2 -pthread" \ " -fdiagnostics-color=never " #define IH ".ih" #define PRECOMP "-x c++-header" #define REFRESH #define LDFLAGS "" #define ADD_LIBRARIES "bobcat" #define ADD_LIBRARY_PATHS "" #define DEFCOM "program" ) manpageseealso() bf(icmake)(1), bf(icmconf)(7), bf(icmstart)(1), bf(icmstart.rc)(7) manpagebugs() None reported includefile(trailer.inc) icmake-9.02.06/doc/manpage/icmstart.rc.yo0000644000175000017500000001134413176557635017111 0ustar frankfrankincludefile(release.yo) htmlbodyopt(text)(#27408B) htmlbodyopt(bgcolor)(#FFFAF0) whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl)) DEFINEMACRO(sop)(3)(\ it() bf(-ARG1) ARG2 nl()ARG3\ ) DEFINEMACRO(itt)(1)(\ it()tt(ARG1)\ ) DEFINEMACRO(itb)(1)(\ it()bf(ARG1)nl()\ ) DELETEMACRO(tt) DEFINEMACRO(tt)(1)(em(ARG1)) COMMENT( man-request, section, date, distribution file, general name) manpage(icmstart.rc)(7)(_CurYrs_)(icmake._CurVers_.tar.gz) (icmstart resource file) COMMENT( man-request, larger title ) manpagename(icmstart.rc)(The icmstart(1) resource file) manpagedescription() The bf(icmstart.rc) file specifies the files that are installed by bf(icmstart)(1). By default bf(icmstart.rc) is found in tt(/etc/icmake/icmstart.rc), but if a file tt($HOME/.icmake/icmstart.rc) is found then the latter file is used by bf(icmstart)(1). tt($HOME/.icmake/icmstart.rc) in turn is overruled by specifying a tt(-c) option when invoking bf(icmstart)(1). The default resource file contains the following specifications, preparing for the construction of a bf(C++) program using bf(icmbuild)(1): verb( CLASSES icmconf P main.cc P main.ih P usage.cc P version.cc P ? scanner P ? parser ) The tt(icmstart.rc) file may contain: itemization( it() empty lines, which are ignored; it() lines beginning with a hash-character (tt(#)), also ignored; it() an optional installation mode followed by a source-destination specification. ) manpagesection(INSTALLATION MODE) An installation mode consists of a combination of: itemization( it() either a P (don't install with tt(icmstart xxx library)) or an L (don't install with tt(icmstart xxx program)); it() a D, indicating that the source must also be installed by default, i.e., if neither `program' or `library' was specified as second argument. it() a b, indicating that the file must em(not) be installed if the tt(-b) (basic installation) option was specified when calling tt(icmstart). it() Following the optional P, L, D, b combination a space delimited optional tt(?) may be specified. If specified the installation of the file or directory must be confirmed by the user. ) manpagesection(SOURCE-DESTINATION SPECIFICATIONS) The following source-destination specifications can be used in an tt(icmstart.rc) file: itemization( it() tt(source)nl() A plain name must exist in the tt(icmstart's) skeleton directory. It is installed in the destination directory tt(`dest') specified when calling bf(icmstart)(1). Example: verb( CLASSES ) tt(skeletondir/CLASSES) is installed as tt(dest/CLASSES) it() tt(pathspec)nl() If `pathspec' does not begin with a slash it must exist in tt(icmstart's) skeleton directory. It is installed as `pathspec' in the destination directory specified when calling bf(icmstart)(1). Example: verb( dir/file ) tt(skeletondir/dir/file) is installed as tt(dest/dir/file) it() tt(/pathspec) or tt(~/pathspec) The tt(~)-character is expanded to the user's home directory. The pathspec's final element is installed in the destination directory specified when calling bf(icmstart)(1). Example: verb( ~/.icmake/file ) tt($HOME/.icmake/file) is installed as tt(dest/file) ) When the above source specifications are followed by a destination specification tt(destspec) (a file or non-absolute directory specification) then the source specification is installed as dest/destspec) below the destination directory specified when calling bf(icmstart)(1). Examples: verb( CLASSES CLASSES # skeletondir/CLASSES is installed as # dest/CLASSES dir/file dir/file # skeletondir/dir/file is installed as # dest/dir/file ~/.icmake/file .icmake/file # $HOME/.icmake/file is installed as # dest/.icmake/file ) Icmstart conveerts the destination specification to a full path specification. If this full path specification does not begin with tt(dest's) full path specification an error message is displayed and tt(icmstart) ends. manpagefiles() The mentioned paths are sugestive only and may be installation dependent: itemization( it() bf(/usr/share/icmake/icmconf) Example of an bf(icmbuild) configuration file; it() bf(/usr/share/icmake/CLASSES) Example of an bf(icmbuild) tt(CLASSES) file. it() bf(/usr/share/icmake/icmstart.rc) Default skeleton resource file. ) manpageseealso() bf(icmake)(1), bf(icmbuild)(1), bf(icmconf)(7), bf(icmstart)(1) manpagebugs() None reported includefile(trailer.inc) icmake-9.02.06/doc/manpage/icmake.yo0000644000175000017500000014702113176557635016113 0ustar frankfrankincludefile(release.yo) htmlbodyopt(text)(#27408B) htmlbodyopt(bgcolor)(#FFFAF0) whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl)) DEFINEMACRO(lsvoption)(3)(\ bf(--ARG1)=tt(ARG3) (bf(-ARG2))\ ) DEFINEMACRO(lsoption)(2)(\ bf(--ARG1) (bf(-ARG2))\ ) DEFINEMACRO(lvoption)(2)(\ bf(--ARG1)=tt(ARG2)\ ) DEFINEMACRO(loption)(1)(\ bf(--ARG1)\ ) DEFINEMACRO(svoption)(2)(\ bf(-ARG1) tt(ARG2)\ ) DEFINEMACRO(soption)(1)(\ bf(-ARG1)\ ) DEFINEMACRO(itt)(1)(\ it()tt(ARG1)\ ) DEFINEMACRO(itb)(1)(\ it()bf(ARG1)nl()\ ) DEFINEMACRO(icm)(0)(bf(icmake)) DEFINEMACRO(Icm)(0)(bf(Icmake)) DELETEMACRO(tt) DEFINEMACRO(tt)(1)(em(ARG1)) COMMENT( man-request, section, date, distribution file, general name) manpage(icmake)(1)(_CurYrs_)(icmake._CurVers_.tar.gz) (A program maintenance utility) COMMENT( man-request, larger title ) manpagename(icmake)(A program maintenance (em(make)) utility using a bf(C)-like grammar) COMMENT( all other: add after () ) manpagesynopsis() icm() [options] tt(source[.im] [dest[.bim]]) [-- [args]] bf(icmun) tt(bimfile) manpagedescription() Icm()(1) was designed as a generic tool that can be used as an alternative to bf(make)(1), handling program maintenance. It's a generic tool in that tt(icmake)-scripts, written in a language closely resembling the bf(C) programming language, can perform tasks that are traditionally the domain of scripting languages. Icm() allows programmers to use a programming language (closely resembling the well-known bf(C)-programming language) to define the actions that are required for (complex) program maintenance. For this, icm() offers various special operators as well as a set of support functions that have shown their usefulness in program maintenance. Although tt(icmake)-scripts can be written from scratch for handling program maintenance, often the required activities are highly comparable. This observation resulted in the construction of two tt(icmake)-scripts: bf(icmstart)(1), initializing a directory for program development and bf(icmbuild)(1), handling the actual program maintenance. Both come predefined as scripts tailored to initializing and maintaining bf(C++) programs (or, after minimal adaptation, bf(C) programs), but can easily be adapted to other programming languages. Both tt(icmstart) and tt(icmbuild) can be run without explicitly calling tt(icmake). This man-page covers tt(icmake) (the program), its support programs and the syntax and facilities offered by tt(icmake's) scripting language. Refer to the bf(icmstart)(1)) man-page for information about how a directory can be initialized (created) in which (by default) a bf(C++) or bf(C) program can be developed and refer to the bf(icmbuild)(1) man-page for information about how tt(icmbuild) can be used to handle program maintenance. It should be stressed that tt(icmake) and its support programs and scripts do not offer an em(Integrated Development Environment) (IDE). It merely performs tasks for which scripts can be written, and it offers just a few pre-defined scripts (tt(icmstart) and tt(icmbuild)) that repeatedly have shown to be extremely useful when developing and maintaining programs. In its standard operation mode, tt(icmake) calls the following programs: itemization( itt(icm-pp) to preprocess the icmake file itt(icm-comp) to byte-code compile the icm() file(s) it()tt(icm-dep) to handle class-dependencies (see section bf(ICM-DEP) in bf(icmbuild)(1)'s man-page for more information about tt(icm-dep)). it()tt(icm-exec) to execute the byte-code file ) The program bf(icmun)(1) can be used to disassemble the compiled byte-code (.bim) file. tt(Icmun) is mainly used for illustration, education, and debugging. As it is not required for tt(icmake)'s daily use it is not installed in a standard tt(PATH) directory but (since tt(icmake's) version 9.02.00) in tt(icmake's) tt(lib) directory, commonly tt(/usr/lib/icmake). Traditional make-utilities recompile sources once header files are modified. When developing bf(C++) programs this is often a bad idea, as adding a new member to a class does not normally require you to recompile all of the class's source files. To handle class dependencies bf(icmbuld)(1) may inspect class dependencies, (re)compiling sources of dependent classes whenever necessary. By default, class-dependencies are not interpreted, but this can easily be changed by activating the tt(PRECOMP) and/or tt(USE_ALL) defines in tt(icmconf). Refer to the bf(icmconf)(7) man-page for further details. Precompiled header files can also easily be used. Precompiled header files dramatically reduce the time that is required for compiling classes' source files. Refer to the bf(icmconf)(7) man-page (in particular the description of the tt(PRECOMP) define) for further details. tt(Icmake's) bf(C)-like scripting language is described in the upcoming sections of this man-page: itemization( itb(PREPROCESSOR DIRECTIVES) - supported preprocessor directives, like tt(#include) and tt(#define); itb(DATA TYPES) - tt(int, list, string), and tt(void) (for functions); itb(PREDEFINED CONSTANTS) - like tt(O_FILE, OFF), and tt(S_IFREG); itb(OPERATORS) - like tt(+, younger), and casts itb(FLOW CONTROL) - tt(if, for, while), etc. (the tt(switch) is not available); itb(PREDEFINED FUNCTIONS) - executing programs, changing directories, operations on tt(string) and tt(list) type variables, etc.; itb(USER DEFINED FUNCTIONS) - at least tt(main), with or without its common parameters tt(argc, argv,) and tt(envp). ) manpageoptions() Where available, single letter options are listed between parentheses beyond their associated long-option variants. The tt(--) option is special: itemization( itt(--): icm() arguments separator separating icm() arguments from arguments passed to the .bim filenl(). Those arguments are passed to the .bim file as-is, and are available from the tt(list argv) parameter available from the icm() script's tt(main) function's second parameter (see below at section bf(USER DEFINED FUNCTIONS)). For some options (see below) the tt(--) separator is not required. ) Icm() supports various options, and only one of these can be specified when icm() is invocated. itemization( it() lsoption(about)(a)nl() Show information about icm() and terminate. it() lsoption(compile)(c)nl() The icm() source file is compiled, generating a .bim file. it() lsoption(execute)(e)nl() Execute the icm() .bim file, given as icm()'s first file argument. Any additional arguments are passed to the .bim file as-is, and tt(--) should not be specified. it() lsoption(force)(f)nl() The icmake source file is recompiled (even if the tt(.bim) file is up-to-date) either when no other options are specified, or when in combination with options tt(--source) and tt(--tmpbin). it() lsoption(help)(h)nl() Provide usage info and terminate. it() lsoption(icm-dep)(d)nl() Calls tt(/usr/lib/icmake/icm-dep), passing it all remaining arguments. If no additional arguments are specified tt(icm-dep's) short usage information is shown to the std. output stream. See section bf(ICM-DEP) in bf(icbuild)(1)'s man-page for more information about the tt(icm-dep) support program. An overview of tt(icm-dep's) option follows below, next to this overview of icm()'s options. it() lsoption(preprocess)(p)nl() The icm() source file is only preprocessed, and the preprocessed file is written to icm()'s second file argument (by default tt(`source'.pim)). it() lsoption(source)(i)nl() The first argument is the icm() source file, the default binary file is constructed if necessary. Any additional arguments are passed to the .bim file as-is, and tt(--) should not be specified. it() lsoption(summary)(F)nl() The filenames and flags as well as an overview of all actions to be performed by icm() are shown on the standard output stream. it() svoption(t)(tmpbim)nl() The tt(tmpbim) argument following tt(-t) is the name of a temporary .bim file, which is removed after icm()'s call. When tt(.) is specified for tt(tmpbim) then the default temporary directory, followed by icm()'s process-id, followed by tt(.bim) is used. Following the name of the temporary .bim file the name of the icm() source script must be specified. Any additional arguments are passed to the .bim file as-is, and tt(--) should not be specified; After setting the source script file's executable flag (tt(chmod +x script)), and providing it with an initial line like this: verb( #!/usr/bin/icmake -t. ) the icm() script can directly be called: verb( script arg1 arg2 ) in which case the icm() script tt(`script') is executed while it receives the arguments tt(script arg1 arg2). it() svoption(T)(directory)nl() The specified directory is used to store temporary files. E.g., when compiling an icm() script, the output of icm()'s preprocessor is a temporary file which is removed on exit. By default tt(/tmp) is used, unless tt(/tmp) is not a writable directory, in which case the current user's tt($HOME) directory is used. Implicit temporary filenames always start with the process id of the current icm() process. it() lsoption(version)(v)nl() Displays icm()'s version number, and terminates. ) bf(Icmun): tt(bimfile): binary icm() script file. manpagesection(ICM-DEP invocation and options) To start its work, the dependencies-analyzer tt(icm_dep) needs one command-line argument: tt(go). Any other argument results in tt(icm_dep) performing a `dry run': it will perform all its duties (and verbose messages are displayed as if tt(go) had been specified), but no files (precompiled headers or tt(USE_ALL) files) will be touched or removed. If neither options nor arguments are specified tt(icm_dep) writes its usage summary to the standard output. Options of tt(icm-dep) can be specified immediately following icm()'s tt(--icm-dep) option. The following options are recognized by tt(icm-dep): itemization( it() lsvoption(classes)(c)(filename)nl() By default, tt(icm-dep) inspects dependencies of the classes whose directories are mentioned in the file tt(CLASSES). If specified in the bf(icmconf)(7) file, it will also consider dependencies of the classes tt(Parser) (directory tt(parser)) and tt(Scanner) (directory tt(scanner)), or it uses their actual names as defined in the bf(icmconf)(7) file. Use this option if instead of tt(CLASSES) another file should be inspected. it() lsoption(help)(h)nl() tt(Icm-dep) writes a summary of its usage to the standard output and terminates. it() lsvoption(icmconf)(i)(filename)nl() By default tt(icm-dep) inspects the contents of an tt(icmconf) file, looking for the tt(USE_ALL) and tt(PRECOMP) specifications. Use this option if instead of tt(icmconf) another file should be inspected. it() lsvoption(mainih)(m)(mainheader)nl() The tt(icmconf) file uses the tt(#define IH) parameter to specify the suffix of class header files that should be precompiled, their filenames being equal to the names of the classes mentioned in the tt(CLASSES) file. tt(CLASSES) does not specify a top-level directory. The name of the top-level header file to precompile can be specified using this option. By default it is tt(main.ih). it() loption(gch)nl() By default precompiled header files are inspected if tt(icmconf) contains a tt(#define PRECOMP) specification. If it does not, but precompiled headers should nonetheless be inspected, the option tt(--gch) can be specified. it() loption(no-gch)nl() By default precompiled header files are inspected if tt(icmconf) contains a tt(#define PRECOMP) specification. If so, but precompiled headers should em(not) be inspected, the option tt(--no-gch) can be specified. it() loption(no-use-all)nl() By default files named at the tt(#define USE_ALL) specification are inspected if tt(icmconf) contains such a specification. If it does, but the tt(`USE_ALL') files should not be inspected, this option can be specified. it() lvoption(use-all)(filename)nl() By default files named at the tt(#define USE_ALL) specification are inspected if tt(icmconf) contains such a specification. If it does not, but tt(`USE_ALL') files should nonetheless be inspected, this option can be specified, together with the name of files (existing in one or more directories that indicate that all the directory's source files must be recompiled). it() lsoption(verbose)(V)nl() This option can be specified multiple times. The number of times it is specified defines tt(icm_dep's) verbosity. If none is specified, tt(icm_dep) silently performs its duties. If specified once, then tt(icm_dep) reports to the standard output what actions it performs; if specified twice it reports the options it encountered; if specified three times it also reports the class dependencies; if specified more often it reports what files it encountered and what situations caused it to make its decisions. it() lsoption(version)(v)nl() tt(Icm_dep) reports its version number to the standard output and terminates. ) manpagesection(PREPROCESSOR DIRECTIVES) The following preprocessor directives are available: itemization( it() comment:nl() standard bf(C) comment (all between tt(/*) and tt(*/)) as well as comment-to-end-of-line (all line contents following tt(//)) are ignored. it() Shell startup: The first line of the icm()-script may start with tt(#!path), where tt(path) defines the absolute location of the icm() program. By making the script executable, it can be called without explicitly calling icm(). E.g., if the first line of an (executable) icmakefile 'icm' (without extension) contains verb( #!/usr/bin/icmake -i ) then tt(icm) may be issued as a command, thus executing verb( /usr/bin/icmake -i icm ... ) Alternatively, verb( #!/usr/bin/icmake -t /tmp/icm ) may be used, resulting in the execution of verb( #!/usr/bin/icmake -t /tmp/icm icm ... ) In this case the binary file is removed on exit. itt(#include "filename")nl() The file tt(filename) is included at the location of the directive itt(#include )nl() The file tt(filename) is included at the location of the tt(#include) directive; tt(filename) is searched in the colon-separated directories specified by the tt(IM) environment variable. The first occurrence of tt(filename) in the directories specified by the tt(IM) environment variable is used. itt(#define identifier [definition])nl() The text tt(identifier) will be replaced by tt(definition). The definition may contain references to already defined identifiers, using the tt(${identifier}) format. If the tt(${identifier}) hasn't been defined (yet), the text tt(${identifier}) is literally kept. To prevent infinite recursion at most 100 tt(${identifier}) replacements are allowed. Definitions continue at the next line if the last character on a line is a backslash (tt(\)). (which is not included in the definition). The preprocessor concatenates double-quuted strings, and double quoted strings may not span multiple lines. Multiple blanks (outside of double quoted strings) in definitions are contracted to a single blank space. The definition following the tt(#define's) identifier is optional. If omitted, the macro is defined, so it can be used in tt(#if(n)def) directives (see below), but they are not replaced by any text in icm() code statements. itt(#ifdef identifier)nl() If the tt(identifier) macro was defined the next block of code (until a matching tt(#else) or tt(#endif) directive was read) is byte-compiled. Otherwise, the block of code is ignored. itt(#ifndef identifier)nl() If the tt(identifier) macro was em(not) defined the next block of code (until a matching tt(#else) or tt(#endif) directive was detected) is byte-compiled. Otherwise, the block of code is ignored. itt(#else)nl() Terminates a tt(#ifdef) and tt(#ifndef) directive, reversing the acceptance decision about the following code. Only one tt(#else) directive can be associated with tt(#if(n)def) directives. itt(#endif)nl() Terminates the preprocessor block starting at the matching tt(#ifdef), tt(#ifndef) or tt(#else) directive. The tt(#endif) directory and its matching tt(#if(n)def) directive must be specified in the same file. itt(#undef identifier) nl() Remove tt(identifier) from the set of defined symbols. This does not affect the specification of any previously defined symbols in which tt(identifier's) definition has been used. If tt(identifier) hasn't been defined a warning is issued. ) manpagesection(DATA TYPES) Icm() supports these data types: itemization( itt(ASCII character constants)nl() ASCII character constants consist of one character, surrounded by single or double quotes. Single characters (e.g., tt('a')) represent the character itself. Standard escape sequences (e.g., tt('\n')) are supported and represent their standard converted value (e.g., tt('\n') represents ascii value 10 (decimal)). Non-standard escape sequences (e.g., tt('\x')) represent the ascii character following the escape character (so tt('\x') equals tt('x')). Escape sequences consisting of three octal digits represent the ascii character corresponding to the octal value modulo 256 (e.g., tt('\123')). Escape sequences consisting of an x followed by two hexadecimal digits represent the ascii character corresponding to the hexadecimal value (e.g., tt('\xa4')). itt(int)nl() Integral values, ranging from tt(-0x8000) through tt(0x7fff). tt(int) constants may be specified as decimal numbers (starting with digits 1 through 9), octal numbers (starting with 0, followed by one or more octal digits) hexadecimal numbers (starting with 0x, followed by one or more hexadecimal digits) or as tt(ASCII) character constants. itt(string)nl() Text variables. String constants are delimited by double quotes. Multiple string constants may be concatenated, but a single string constant may not span multiple lines. String constants separated by white space only (i.e., blanks, newlines, comment) are concatenated and represent one single string constant. To indicate an end-of-line in a string constant use the tt(\n) escape sequence. ASCII character constants surrounded by double quotes can also be used in arithmetic expressions if one of the operands is an tt(int). The single character string constant em(must) be a constant, and cannot be a tt(string) variable. Likewise, ASCII character constants surrounded by single quotes may be used in situations where a string operand is expected. itt(list)nl() A data structure containing a series of individually accessible tt(string) values. When a list contains elements, its first element is indicated by index 0. itt(void)nl() Used with function definitions to indicate that the function does not return a value. ) Variables can be defined at the global level as well as at any local level inside functions. When defined inside functions, the standard bf(C) scoping and visibility rules apply. E.g., local variables can only be used in their own or in more deeply nested blocks, their visibility is masked in more deeply nested blocks by defining an identically named variable inside those more deeply nested blocks. Variables are strongly typed, and cannot have type tt(void). Variables may be initialized when they are defined. Initializations are expressions, that can use pre- or user-defined functions, constant values, and values of variables that are visible at the point of definition. manpagesection(PREDEFINED CONSTANTS) The following constants are predefined by icm(). All are constant tt(int) values: table(3)(lll)( rowline() row(cell(symbol)cell(value)cell(intended for)) rowline() row(cell(O_ALL)cell(8)cell(makelist)) row(cell(O_DIR)cell(2)cell(makelist)) row(cell(O_FILE)cell(1)cell(makelist)) row(cell(O_SUBDIR)cell(4)cell(makelist)) rowline() row(cell(OFF)cell(0)cell(echo)) row(cell(ON)cell(1)cell(echo)) rowline() row(cell(P_CHECK)cell(0)cell(system calls)) row(cell(P_NOCHECK)cell(1)cell(system calls)) rowline() row(cell(S_IEXEC)cell(32)cell(stat)) row(cell(S_IFCHR)cell(1)cell(stat)) row(cell(S_IFDIR)cell(2)cell(stat )) row(cell(S_IFREG)cell(4)cell(stat)) row(cell(S_IREAD)cell(8)cell(stat )) row(cell(S_IWRITE)cell(16)cell(stat)) rowline() ) The following constants are architecture dependent: table(2)(ll)( rowline() row(cell(symbol)cell(1 when defined on the platform, otherwise 0)) rowline() row(cell(unix) cell(Unix, usually with GNU's gcc compiler)) row(cell(UNIX) cell(may alternatively be available)) row(cell(linux) cell(x86 running Linux (usually with gcc))) row(cell(LINUX) cell(may alternatively be available)) row(cell(M_SYSV, M_UNIX) cell(x86 running SCO/Unix)) row(cell(_POSIX)cell(_SOURCE Unix with Posix compliant compiler)) row(cell(__hpux)cell(HP-UX, with the native HP compiler)) rowline() ) manpagesection(OPERATORS) bf(int-typed operand(s):) All bf(C) operators are available (except for pointer operators, as icm() does not support pointers). They operate like their bf(C)-programming language counterparts. bf(string-typed operand(s):) For tt(string) type variables and/or constants the following operators are available (tt(a) and tt(b) represent tt(string) variables or constants): itemization( itt(a + b): returns a new tt(string) value containing the concatenation of tt(string) values tt(a) and tt(b). Note that tt(string) constants may be directly concatetated (without using the tt(+) operator), e.g., the following two lines both define the string tt("hello world"): verb( "hello " "world" "hello " + "world" ) itt(a += b): tt(a) must be a tt(string) variable, to which the tt(string) variable or value tt(b) is appended. it() string comparisons: operators tt(== != <= >= < > !=) and tt(==) may be applied to tt(string) values or variables, returning 1 if the comparison succeeds, otherwise 0. Comparison is case sensitively, and follows the ordering or characters as defined in the tt(ASCII) character set. itt(!a): the boolean tt(!) (not) operator returns 1 if the tt(string a) is empty, otherwise 0 is returned. itt(a younger b, a newer b): returns 1 if file tt(a) is more recent than file tt(b). E.g., tt("source.cc" newer "source.o"). The files tt(a) and tt(b) do not have to exist: if both don't exist 0 is returned; if tt(b) doesn't exist, 1 is returned; if tt(a) doesn't exist 0 is returned; if they are equally old 0 is returned. (the tt(exists()) predefined function (see below, section bf(PREDEFINED FUNCTIONS)) can be used to test explicitly whether a file exists). itt(a older b): turns 1 if file tt(a) is older than file tt(b). E.g., tt("libprog.a" older "source.o"). The files tt(a) and tt(b) do not have to exist: if both don't exist 0 is returned; if tt(a) doesn't exist, 1 is returned; if tt(b) doesn't exist 0 is returned; if they are equally old 0 is returned. itt([]): the index operator retrieves a character from a string variable or constant: it returns a string as an em(rvalue). Therefore, the following statement compiles OK: verb( // assume str1 and str2 are strings str1 = str2[3]; ) but the following statement won't compile: verb( str2[3] = "a"; ) An empty string is returned if an invalid index value is provided. it() The `backtick` operator (tt(`string cmd`))nl() A string placed between two backticks is executed by the tt(popen)(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's standard error stream output is not collected by the backtick operator. However, standard shell redirection could be used to collect the standard error stream's output. Example: verb( printf(`"ls"`); // prints the elements in // the current directory ) The predefined function tt(eval(string cmd)) behaves exactly like the backtick operator: they are synonyms. ) bf(list-typed operand(s):) For tt(list) type variables and/or values the following operators are available: itemization( itt(a + b): returns a new tt(list) value containing the concatenation of tt(list) values tt(a) and tt(b). This is em(not) a set operation: if an element appears both in tt(a) and in tt(b), they will appear twice in the resulting list (set-addition is provided by the built-in function tt(listunion)). itt(a - b): returns a new tt(list) value containing the elements in tt(a) that are not present in tt(b). This em(is) a set-difference operation: the returned list contains all elements in tt(a) that are not elements of tt(b). itt(a += b): elements in tt(b) are added to the elements in tt(a), which must be a tt(list) variable. This is em(not) a set operation. itt(a -= b): elements in tt(b) are removed from the elements in tt(a), which must be a tt(list) variable. This em(is) a set operation: all elements of tt(a) that are found in tt(b) are removed from tt(a). it() list equality comparisons: operators tt(!=) and tt(==) may be applied to tt(list) values or variables. Operator tt(==) returns 1 if both lists have element-by-element identical elements, otherwise 0 is returned. Operator tt(!=) reverses the result of tt(==). itt(!a): the boolean tt(!) operator returns 1 if the tt(list a) is empty, otherwise 0 is returned. itt([]): the index operator retrieves a list element from a list variable: it returns a string as an em(rvalue). Therefore, the following statement compiles OK: verb( // assume lst is a list, str is a string str = lst[3]; ) but the following statement won't compile: verb( lst[3] = str; ) An empty string is returned if an invalid index value is provided. ) bf(Casting:) Type-casts may be performed using the standard bf(C) cast-operator to cast: itemization( it() Strings to ints and vice versa (tt((int)"123", (string)55)) it() Strings to lists (tt(list lst = (list)"hello")) ) manpagesection(FLOW CONTROL) Icm() offers the following subset of bf(C)'s statements. They can be used as in the bf(C) programming language. itemization( itt(expression ;)nl() The plain expression statement; it() The compound statement nl() Variables of any type may be defined and initialized anywhere inside any compound statement. The em(visibility) of a variable starts at its point of definition. itt(if (condition) statement)nl() Inside the condition a variable may be defined and initialized. E.g, verb( if (string str = getText()) process(str); ) In this example, tt(process) is not called if tt(getText()) returns an empty string. The variable tt(str) does not exist either before or after the tt(if) statement. itt(if (condition) statement else statement)nl() As with the previous statement, inside the condition a variable may be defined and initialized. itt(for (init; condition; increment) statement)nl() Variables (of a single type) may be initialized (and optionally be defined) in the tt(init) section. The tt(init), tt(condition) and tt(increment) sections may remain empty. The empty condition section is interpreted as `always tt(true)'. itt(while (condition) statement)nl() Inside the condition a variable may be defined and initialized.nl() A complementary tt(do ... while()) statement is not available. Note that defining a variable, using an initialization expression means that the initialization expressing is executed at each iteration of the tt(while) statement. So the following statement will never end, and will display a never ending stream of values 10: verb( while (int x = 10) printf(x--, "\n"); ) itt(return;), and tt(return expression;)nl() Plain tt(return) statements can be used in tt(void) functions, and tt(return expression) statements are used in other type of functions. The function tt(main) has return type tt(void) and so in tt(main) only plain tt(return) statements can be used. By default an icm() script's exit value equals 0. Use the built-in function tt(exit) (see below) to specify any other exit value. bf(Be advised: ) the behavior of non-void functions not returning values is undefined. itt(break)nl() Leaves tt(for) and tt(while) statements, overruling the statement's condition. itt(continue)nl() Continues with the next iteration of a tt(for) or tt(while) statement. itt(exit(expression))nl() Ends the execution of an icm()-script. The tt(expression) must evaluate to an tt(int) value, which becomes the script's exit value. ) manpagesection(PREDEFINED FUNCTIONS) Icm() offers the following predefined functions, which can be used anywhere in icm() scripts. The following overview is ordered alphabetically by function name. itemization( itt(void arghead(string h))nl() Helper function of tt(exec()) (see also below at tt(exec())): defines the `argument head', to be used with tt(exec()). By default, the `argument head' is an empty string. itt(void argtail (string t))nl() Helper function of tt(exec()) (see also below at tt(exec())): defines the `argument tail', to be used with tt(exec()). By default, the `argument tail' is an empty string. itt(int ascii(string s))nl() Returns the first character of tt(s) as an int; e.g., tt(ascii("A")) returns 65; itt(string ascii(int i))nl() Returns tt(i) as a string, e.g., tt(ascii(65)) returns the string tt("A"); itt(string change_base(string file, string newbase))nl() Changes the basename of tt(file), returns the changed name. E.g, tt(change_base("/path/demo.im", "out")) returns tt("/path/out.im"); itt(string change_ext(string file, string newext))nl() Changes the extension of tt(file), returns the changed name. E.g, tt(rss_changeExt("source.cc", "o")) returns tt("source.o"); itt(string change_path(string file, string newpath))nl() Changes the path specification of tt(file), returns the changed name. E.g, tt(change_path("tmp/binary", "/usr/bin")) returns tt("/usr/bin/binary"). Note that the tt(/)-separator is inserted if required. itt(string chdir(string newdir))nl() Changes the script's working directory, returns the previous dir as an absolute path. Use tt(chdir(".")) to obtain the current working directory, tt(chdir("")) 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 icm()-script if the specified tt(newdir) does not exist. itt(string chdir(int checking, string newdir))nl() Same functionality as the previous function, but by specifying tt(checking) as tt(P_NOCHECK). the function won't terminate the script. Rather, it will return the script's current working directory. itt(cmdhead(string h))nl() Helper function of tt(exec()) (see also below at tt(exec())): Defines a `command head', to be used with tt(exec()). By default, the `command head' is an empty string. itt(cmdtail(string t))nl() Helper function of tt(exec()) (see also below at tt(exec())): Defines a `command tail', to be used with tt(exec()). By default, the `command tail' is an empty string. itt(echo(int opt))nl() Controls echoing of called programs (and their arguments), specify tt(OFF) if echoing is not requested. By default tt(echo(ON)) is used. itt(string element(int index, list (or string) var))nl() Acts identical to the index operator: refer to the index (tt([])) operator in the section bf(OPERATORS). itt(list eval(string str))nl() This function acts identically to the backtick operator. The example provided with the backtick operator could therefore also have been written like this: verb( printf(eval("ls")); // prints the elements in the current // directory ) itt(exec(string cmd, ...))nl() Executes command with arguments. Each argument will be prefixed by tt(arghead())'s argument and postfixed by tt(argtail())'s argument. Note that no blanks are inserted between tt(arghead())'s contents, the argument proper, and tt(argtail())'s argument. All thus modified arguments are concatenated, this time separated by single blanks, and then tt(cmdhead())'s contents are inserted between the command and the first argument (on either side delimited by single blanks) and tt(cmdtail())'s contents are appended to the arguments (again, separated by a single blank). tt(PATH) is searched to locate tt(cmd). 0 is returned. itt(exec(int checkcmd, string cmd, ...))nl() Same functionality as the previous function, but by specifying tt(checking) as tt(NOT_CHECKED) the function won't terminate the script. Rather, it will return the called command's exit status, or tt(0x7f00) if the command wasn't found. itt(execute(string cmd, string cmdhd, string arghd, ..., string argtl, string cmdtl))nl() Same as tt(exec()), but command head/tail and argument head/tail must be specified. The actually executed command starts with tt(cmd), followed by tt(cmdhd). Next is a series of arguments follows, each enclosed by tt(arghd) and tt(argtl). The command terminates with tt(cmdtl). 0 is returned itt(execute(int checking, string cmd, string cmdhd, string arghd, ..., string argtl, string cmdtl))nl() Same functionality as the previous function, but by specifying tt(checking) as tt(NOT_CHECKED) the function won't terminate the script. Rather, it will return the called command's exit status, or tt(0x7f00) if the command wasn't found. itt(int exists(string file))nl() Returns a non-zero value if tt(file) exists, otherwise 0 is returned. itt(list fgets(string file, list offset))nl() bf(NOTE:) in icm() version 8.00.00 the prototype of this function was changed from tt(list fgets(string file, int offset)) to tt(list fgets(string file, list offset)). The next line found at the offset contained in tt(offset) is read from tt(file). Pass an empty list to tt(fgets) to read tt(file) from its beginning. It returns a list containing as its first element the contents of the read line (without the tt(\n) line terminator), as its second element the line's terminator `tt(\n)' (if encountered), and as its third element the string tt(OK) if a line was successfully read, tt(FAIL) if reading from file failed. When reading at EOF an empty list is returned. The returned list may contain additional elements, which are internally used by tt(fgets) when reading the next line. To read multiple lines, start by passing an empty list as tt(gets's) second argument. To read subsequent lines, pass the previously returned list to tt(fgets's) second argument. Here is an example showing how to read a complete file: verb( list ret; while (1) { ret = fgets("filename", ret); if (!ret) break; process(ret[0], ret[1]); } ) itt(int fprintf(string filename, ...))nl() Appends all (comma separated) arguments to the file tt(filename). Returns the number of printed arguments. itt(int fprintf(string filename, string format, ...))nl() Appends all (comma separated) arguments to the file tt(filename). Returns the number of printed arguments. If tt(format) contains placeholders %1 .. %n the output is formatted (see also tt(strformat)). Note that in this case argument counting (also) starts beyond the format string: the first argument following tt(format) is referred to as tt(%1). itt(string get_base(string file))nl() Returns the base name of tt(file). 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. E.g., the base name of tt(a.b) equals tt(a), the base name of tt(a.b.c) equals tt(a.b), the base name of tt(a/b/c) equals tt(c). itt(string getch())nl() Returns the next pressed key as a string (pressing `Enter' is not required). itt(string get_dext(string file))nl() Returns the extension of tt(file), including the separating dot. The extension is all information starting at the filename's final dot. If no final dot is found, an empty string is returned. itt(list getenv(string envvar))nl() Returns the value of environment variable tt(envvar) in a list containing two elements: the first element indicates whether the environment variable was defined (value tt("1")) or not (value tt("0"));nl() the second element indicates the value of the environment variable. Enivironment variables are of the form tt(variable=value), and if defined the list's second element contains tt(value). If the value is empty, the variable is defined, but has no text associated with it. itt(string get_ext(string file))nl() Returns the extension of tt(file), except for the separating dot. The extension is all information starting at the final dot in the filename. If no final dot is found, an empty string is returned. itt(int getpid())nl() Returns the process-id of the icmake byte code interpreter bf(icm-exec). itt(string gets())nl() Returns the next line read from the keyboard as a tt(string). The line entered on the keyboard must be terminated by an `Enter' key, which is not stored in the returned string. itt(string get_path(string file))nl() Returns the path-prefix of tt(file). 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). If no path is found, an empty strring is returned. itt(int listfind(list lst, string str))nl() Returns the first index in tt(lst) where the string tt(str) is found, or -1 if tt(lst) does not contain tt(str). itt(int listlen(list l))nl() Returns the number of elements in tt(list). itt(list listunion(list lhs, list rhs))nl() Returns a list containing the union of the elements in tt(lhs) and tt(rhs). itt(list listunion(list lst, string str))nl() Returns a list containing the union of the elements in tt(lst) and tt(str). itt(list makelist(string mask))nl() Returns a list of all files matching tt(mask). E.g., tt(makelist("*.c")) returns a list containing all files ending in tt(.c). itt(list makelist(type, string mask))nl() Same as the previous function, but the type of the directory elements may be specified as its first argument: table()(ll)( rowline() row(cell(symbol)cell(meaning)) rowline() row(cell(O_ALL)cell(obtain all directory entries)) row(cell(O_DIR)cell(obtain all directories, including . and ..)) row(cell(O_FILE)cell(obtain a list of files)) row(cell(O_SUBDIR)cell(obtain all subdirectories)) rowline() ) Note that the pattern tt(*) will not match hidden entries under Unix-type operating systems. Use tt(.*) for that. itt(list makelist(string mask, newer, string comparefile))nl() Returns list of all files matching mask which are newer than a provided comparefile. Operator tt(younger) may be used instead of tt(newer). Note that tt(newer) and tt(younger) are operators, not strings. itt(list makelist([int = IS_FILE,] string mask, newer, string comparefile))nl() Same as the previous function, but tt(type) may be specified as in tt(list makelist(type, string mask)). itt(makelist(string mask, older, string comparefile))nl() See above; returns a list of files that are older than the comparefile. itt(makelist(type, string mask, older, string comparefile))nl() Same as the previous function, but tt(type) may be specified as in tt(list makelist(type, string mask)). itt(int printf(...))nl() Shows all (comma separated) arguments to screen (i.e., the standard output stream). Returns the number of printed arguments. itt(int printf(string format, ...))nl() Shows all (comma separated) arguments to screen (i.e., the standard output stream). Returns the number of printed arguments (the tt(format) string counts as one argument). If tt(format) contains placeholders %1 .. %n the output is formatted (see also tt(strformat)). itt(int putenv(string envvar))nl() Adds tt(envvar) to the current (bf(icmake)) environment Use the format: "VAR=value". Returns 0. itt(string resize(string str, int newlength)) Returns a copy of string tt(str), resized to tt(newlength) characters. If tt(newlength) is negative then an empty string is returned, if tt(newlength) exceeds tt(str's) length then the newly added characters are initialized to blank spaces. itt(int sizeof(list l))nl() Deprecated: use tt(listlen). itt(int sizeoflist(list l))nl() Deprecated: use tt(listlen). itt(list stat(string entry))nl() Returns bf(stat)(2) information of directory entry tt(entry) as a list. The returned list has two elements: element 0 is the em(attribute value), element 1 contains the size of the file. Attributes are returned as bit-flags, composed from the following predefined constants: verb( S_IFCHR S_IFDIR S_IFREG S_IREAD S_IWRITE S_IEXEC ) See the bf(stat)(2) manual page for the meanings of these constants. itt(list stat(checking, string entry))nl() Same as the previous function, but by specifying tt(checking) as tt(P_NOCHECK) the function won't terminate the script. Rather, it returns bf(stat)(2)'s return value. itt(int strchr(string str, string chars))nl() Returns the first index in tt(str) where any of the characters in tt(chars) is found, or -1 if tt(str) does not contain any of the characters in tt(chars). itt(int strlen(string str))nl() Returns the number of characters in tt(str) (not counting the final 0). itt(int strfind(string haystack, string needle))nl() Returns index in tt(haystack) where tt(needle) is found, or -1 if tt(needle) is not contained in tt(haystack).nl() bf(This function was called strstr() in versions before 7.00). itt(int strformat(string format,...))nl() Returns a formatted string using placeholders %1 .. %2 to address arguments following format.nl() Example:nl() verb( void main() { int i = 10; int j = 20; string s1; string s2; // traditional approach: s1 = (string)i + " " + (string)j + " " + (string)i; // using strformat: s2 = strformat("%1 %2 %1", i, j); printf("s1 = %1, s2 = %2\n", s1, s2); } ) itt(string strlwr(string s))nl() Returns a lower-case duplicate of tt(s). itt(list strtok(string str, string separators))nl() Returns a list containing all substrings of tt(str) separated by one or more (consecutive) characters in tt(separators). E.g., tt(strtok("hello icmake's+world", " +")) returns the list containing the three strings tt("hello"), tt("icmake's"), and tt("world"). itt(string strupr(string s))nl() Returns an upper-case duplicate of tt(s). itt(string substr(string text, int offset, int count))nl() Returns a substring of tt(text), starting at tt(offset), consisting of tt(count) characters. If tt(offset) exceeds (or equals) the string's size or if tt(count <= 0), then an empty string is returned. If tt(offset) is less than 0 then tt(offset = 0) is used. itt(int system(string command))nl() Executes tt(command). The return value indicates the executed command's exit value. The string tt(command) may contain redirection and/or piping characters. itt(int system(int checking, string command))nl() Same functionality as the previous function, but by specifying tt(checking) as tt(NOT_CHECKED) the function won't terminate the script. Rather, it will return the called command's exit status, or tt(0x7f00) if the command wasn't found. itt(string trim(string s))nl() Returns a copy of tt(s) without leading and trailing white spaces. itt(string trimleft(string str))nl() Returns a copy of tt(s) without leading white spaces. itt(string trim(string s))nl() Returns a copy of tt(s) without trailing white spaces. ) manpagesection(USER DEFINED FUNCTIONS) bf(void main) Icm() scripts must be provided with a user-defined function tt(main). The function tt(main) has three optional parameters, which may be omitted from the last one (tt(envp)) to the first (tt(argc)), like in bf(C). Its full prototype is (note: bf(void) return type): verb( void main(int argc, list argv, list envp) ) In tt(main()), itemization( itt(argc) represents the number of elements in tt(argv); itt(argv) contains the arguments, with element 0 being equal to the name of the .bim file; itt(envp) contains the `environment' variables. The function tt(listlen) can be used to determine the number of its elements. Elements in tt(envp) have the form tt(variable=value). Alternatively, the function tt(getenv) can be used to retrieve a specific environment variable immediately. ) Example: verb( void main(int argc, list argv) { list toCompile; int idx; if (argc == 1) usage(element(0, argv)); if (toCompile = altered("*.cc")) { for (idx = length(toCompile); idx--; ) compile(element(idx, toCompile)); if (getenv("dryrun")[0] == "0") linking(element(2, argv)); } } ) Having initialized all global variables in order of their definitions tt(main) is called by icm()'s run-time support system to perform additional tasks. bf(Additionally defined user functions) Additional functions may be defined. Once defined, these functions can be called. Forward referencing of either variables or functions is not supported, but recursively calling functions is. As function declarations are not supported indirect recursion is not supported either. User-defined functions must have the following elements: itemization( it() The function's return type, which must be one of tt(void, int, string) or tt(list). There is no default type. it() The function's name, e.g., tt(compile). it() A parameter list, defining zero or more comma-separated parameters. The parameters themselves consist of a type name (tt(int, string), or tt(list)) followed by the parameter's identifier. E.g., tt((string outfile, string source)). it() A em(body) surrounded by a pair of curly braces (tt({) and tt(})). ) 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. By default an tt(int) variable is initialized to 0, a tt(string) is initialized to an empty string (tt("")) and a tt(list) is initialized to a list of zero elements. In addition to variable definitions, bodies may contain zero or more statements (cf. section bf(FLOW CONTROL)). Note that variables may be defined (and optionally initialized) anywhere inside functions, and also in tt(if, for) and tt(while) statements. The behavior of icm()-scripts using non-void functions that do not return values is not defined. manpagefiles() The mentioned paths are sugestive only and may vary over different icm()-installations: itemization( it() bf(/usr/bin/icmake): the main icm() program; it() bf(/usr/bin/icmun): the icm() unassembler; it() bf(/usr/lib/icmake/icm-dep): the support program handling class- and precompiled header dependencies; it() bf(/usr/lib/icmake/icm-pp): the preprocessor called by icm(); it() bf(/usr/lib/icmake/icm-comp): the compiler called by icm(); it() bf(/usr/lib/icmake/icm-exec): the byte-code interpreter called by icm(); ) manpagesection(EXAMPLES) The distribution (usually in tt(/usr/share/doc/icmake)) contains a directory tt(examples) containing various examples of icm() script. Note in particular the tt(examples/icmbuild) subdirectory containing a general script for bf(C++) and bf(C) program maintenance. manpageseealso() bf(icmbuild)(1), bf(icmconf)(7), bf(icmstart)(1), bf(icmstart.rc)(7), bf(make)(1) manpagebugs() Standard comment starting on lines containing preprocessor directives may not extend over multiple lines. includefile(trailer.inc) icmake-9.02.06/doc/manpage/build0000755000175000017500000000170113176557635015330 0ustar frankfrank#!/usr/bin/icmake -t. void yodl(string dest, string src) { system("yodl2man --no-warnings -o " + dest + " " + src); } string release = "release.yo"; void rmrelease() { echo(OFF); system("rm -f " + release); echo(ON); } void main(int argc, list argv) { rmrelease(); string versionFile = "../../VERSION"; list line; while (listlen(line = fgets(versionFile, line))) { list cut = strtok(line[0], "= \t\n"); string key = cut[0]; string value = cut[1]; if (key == "VERSION") fprintf("release.yo", "SUBST(_CurVers_)(", value, ")\n"); else if (key == "YEARS") fprintf("release.yo", "SUBST(_CurYrs_)(", value, ")\n"); } yodl("../icmake.1", "-r 20000 icmake.yo"); yodl("../icmstart.1", "icmstart.yo"); yodl("../icmbuild.1", "icmbuild.yo"); yodl("../icmstart.rc.7", "icmstart.rc.yo"); yodl("../icmconf.7", "icmconf.yo"); rmrelease(); } icmake-9.02.06/doc/manpage/icmconf.yo0000644000175000017500000003711413232306656016265 0ustar frankfrankincludefile(release.yo) htmlbodyopt(text)(#27408B) htmlbodyopt(bgcolor)(#FFFAF0) whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl)) DEFINEMACRO(sop)(3)(\ it() bf(-ARG1) ARG2 nl()ARG3\ ) DEFINEMACRO(itt)(1)(\ it()tt(ARG1)\ ) DEFINEMACRO(itb)(1)(\ it()bf(ARG1)nl()\ ) DELETEMACRO(tt) DEFINEMACRO(tt)(1)(em(ARG1)) COMMENT( man-request, section, date, distribution file, general name) manpage(icmconf)(7)(_CurYrs_)(icmake._CurVers_.tar.gz) (configuration file for bf(icmbuild)(1)) COMMENT( man-request, larger title ) manpagename(icmconf)(Configuration file for the bf(icmbuild)(1) program maintenance script) manpagedescription() The tt(icmconf) configuration file is used to specify and fine-tune the program maintenance performed by the bf(icmbuild)(1) script. It can be used to activate and specify various directives that determine how the program or library maintenance is performed. The directives are biased towards the construction of a bf(C++) program, but program maintenance for other languages (e.g., bf(C)) can also easily be configured. The bf(icmbuild)(1) script ignores empty lines and lines whose first non-blank characters are two consecutive forward slashes (//). Long lines can be split over multiple lines by using a final backslash character at lines continuing at the next line (refer to the bf(icmake)(1) man-page for further details). manpagesection(CLASS DEPENDENCIES) Traditional make-utilities recompile all dependent sources once header files are modified. When developing bf(C++) programs this is hardly ever requird, as adding a new member function to a class does not require you to recompile already existing source files. Recompilation em(is) required when modifying the data member organization of classes. To handle class dependencies in a more sensible way, bf(icmake)(1) checks class dependencies using its support program tt(/usr/lib/icmake/icm-dep), visiting the classes listed in the tt(CLASSES) file if tt(icmconf's USE_ALL) directive was specified. If a directory mentioned in the tt(CLASSES) file contains a file having a name that's equal to the name specified at the tt(USE_ALL) parameter, then all sources of classes that depend on that particular class are also recompiled. Likewise, if the tt(PRECOMP) parameter was specified, then a similar action is performed for the precompiled headers: if a local header file that's (directly or indirectly) included by a class's internal header file has changed, then that class's precompiled header as well as all precompiled headers of dependent classes are recompiled. The bf(icmbuild)(1) script itself does not inspect these dependencies, but calls tt(/usr/lib/icmake/icm-dep) to perform the requird tests. The program tt(icm-dep's) short usage summary is written to the standard output stream when calling tt(icmake -d) (or directly: tt(/usr/lib/icmake/icm-dep)). manpagesection(ICMCONF PARAMETERS) itemization( itb(#define ADD_LIBRARIES "") When a program must be linked against additional libraries (other than the name of the program's library itself, if specified at tt(LIBRARY)) then those libraries should be specified, blank space separated, here. E.g., when a program is linked against tt(libbobcat) then the specification is: verb( #define ADD_LIBRARIES "bobcat" ) If your program is linked against multiple libraries, then use a blank-separated list of libraries (like tt("math bobcat")) itb(#define ADD_LIBRARY_PATHS "") When the additional libraries (specified at tt(ADD_LIBRARIES)) are located in non-standard library locations (e.g., not in tt(/lib) and tt(/usr/lib)) then these additional paths are (blank space separated) specified here. Specify only the paths, not the tt(-L) flags. It is stronly advised to specify full pathnames here, or remember that normally the location of the tt(icmconf) file is not the location where the compilation actually takes place, which is the location specified at the tt(TMP_DIR) parameter (see below). itb(#define CLS) The em(clear screen) directive. If defined tt(tput clear) is called to clear the terminal screen before starting the compilation. By default it is not defined. itb(#define CXX "g++") The C++ compiler to use. For a bf(C) compiler use, e.g., tt(#define CC "gcc"). Its setting is overruled by an identically named environment variable. itb(#define CXXFLAGS "--std=c++14 -Wall -O2") The compiler options to use. The default options are shown. When the bf(C) compiler is used, use tt(#define CFLAGS) rather than tt(CXXFLAGS). Its setting is overruled by an identically named environment variable. itb(#define DEFCOM "...") A tt(DEFCOM) directive may be added to the tt(icmconf) file (the bf(icmstart)(1) script can do this for you). It may be defined as: verb( #define DEFCOM "program" ) in which case tt(icmbuild) will do program maintenance. It may also be defined as: verb( #define DEFCOM "program strip" ) in which case tt(icmbuild) does program maintenance, creating a stripped binary program. Alternatively it may also be defined as: verb( #define DEFCOM "library" ) in which case tt(icmbuild) does library maintenance. itb(//#define ICM_DEP "-V go") The existence and implied existence of tt(USE_ALL) files (see the description of the tt(USE_ALL) directive), as well as the correct ages of precompiled headers can be checked by tt(icmake's) support program tt(icm_dep). By default tt(icm_dep) is called with the shown default arguments. If tt(icm_dep) should not be called define tt(ICM_DEP) as an empty string (tt("")). bf(Icmake)(1)'s man-page contains a separate section about the tt(icm_dep) support program. itb(#define IH ".ih") The extension used for internal header files. See tt(#define PRECOMP) below. itb(#define LDFLAGS "") The linker options to use. By default no options are passed to the linker. Its setting is overruled by an identically named environment variable. itb(#define LIBRARY "modules") By default this directive is not defined. If defined a local library is constructed. When a binary program is built it will be linked against this library rather than to the individual object modules. If a library must be constructed (see also the tt(DEFCOM) directive), then the tt(LIBRARY) directive must specify the library's base name (without the tt(lib) prefix and without the tt(.a) extension). After a library has been constructed tt(icmbuild install static dir) installs the static library at tt(dir), while tt(icmbuild install shared dir) installs the shared library (see below at tt(#define SHARED)) at tt(dir). itb(#define MAIN "main.cc") The source file in which the tt(int main) function is defined. This specification may be left as-is or may completely be removed if bf(icmbuild)(1) is used for library maintenance rather than program maintenance. itb(//#define NO_PRECOMP_WARNING") When tt(PRECOMP) is defined (see below) a warning is issued when a class-directory does not contain a tt(IH) file. Such warnings are suppressed when defining tt(NO_PRECOMP_WARNING). This option is ignored unless tt(PRECOMP) has been defined. itb(#define OBJ_EXT ".o") The extension of object modules created by the compiler. itb(//#define PRECOMP "-x c++-header") When activated internal header files (see tt(#define IH)) are precompiled when they are more recent than their precompiled versions. Also, when a precompiled header file is (re)compiled the precompiled header files of all dependent classes are also recompiled. Precompiled headers are removed by tt(icmbuild clean). To specify internal header files for other languages change the tt(-x) specification accordingly. By default this tt(#define) is not active. itb(#define REFRESH) Define tt(REFRESH) to relink the binary program at every tt(icmbuild program) call. By default tt(REFRESH) is em(not) defined. itb(#define SHARED) This directive is only interpreted if tt(LIBRARY) was also specified. If defined a static library (extension tt(.a)) as well as a shared library (extension tt(.so*)) is built. If not specified, but tt(LIBRARY) was specified, only the static library is built. By default tt(SHARED) is not defined. The shared library receives as its major version number tt(VERSION)'s major version number, and receives tt(VERSION) as its full version number. E.g., if tt(VERSION) is defined as tt(1.02.03) and tt(LIBRARY) is defined as tt(demo) then the shared library tt(libdemo.so.1.02.03) is constructed, with tt(libdemo.so.1) soft-linking to it, with tt(libdemo.so) in turn soft-linking to tt(libdemo.so.1). itb(#define SHAREDREQ "") When creating a shared library tt(SHAREDREQ) specifies the names of libraries and library paths that are required by the shared library. E.g., if a library is found in tt(/usr/lib/special), assuming that the name of the required library is tt(libspecial.so), then use the specification tt("-L/usr/lib/special -lspecial"). The tt(/lib) and tt(/usr/lib) paths are usually predefined and need not be specified. This directive is only interpreted if tt(SHARED) and tt(LIBRARY) were also defined. itb(#define SOURCES "*.cc") The pattern to locate sources in a directory. The default value is shown. itb(#define TMP_DIR "tmp") The directory in which intermediate results are stored. Relative to the current working directory unless an absolute path is specified. itb(#define USE_ALL "a") After defining this directive (by default it is em(not) defined) class dependencies are interpreted. In this case, when a directory contains a file having a name that's equal to the name specified at the tt(USE_ALL) directive, then all sources of that class as well as all sources of classes that depend on it are (re)compiled. Following the successful recompilations the file(s) specified at tt(#define USE_ALL) are removed. When the tt(USE_ALL) directive was specified the command tt(icmbuild clean) also removes any leftover tt(USE_ALL) files from the program's subdirectories. itb(#define USE_ECHO ON) When specified as tt(ON) (rather than tt(OFF)) commands executed by tt(icmbuild) are echoed. itb(#define USE_VERSION) If defined (which is the default) the file tt(VERSION) is read by tt(icmconf) to determine the program/library's version, and the project's release years. ) manpagesection(PARSER MAINTENANCE) The following directives are available in cases where a program uses a parser generator creating a parser class from a grammar specification: itemization( itb(#define PARSER_DIR "") The subdirectory containing the parser's specification file. If parser maintenance is not required, then this directive can be omitted. If omitted, then all other directives, that begin with tt(PARS), can also be omitted. itb(#define PARSFILES "") If the parser specification file named at tt(PARSSPEC) itself includes additional specification files, then patterns matching these additional grammar specification files should be specified here. The pattern is interpreted in the directory specified at tt(PARSER_DIR) and could contain a subdirectory name (e.g. tt(specs/*)). When files matching the pattern are modified then a new parser will be created. By default no additional specification files are used. itb(#define PARSFLAGS "-V") The flags to use when calling the program specified at tt(PARSGEN). itb(#define PARSGEN "bisonc++") The name of the program generating the parser. itb(#define PARSOUT "parse.cc") The name of the file generated by the parser generator (which is used by tt(icmbuild) to compare the timestamps of the parser specification file(s) against). itb(#define PARSSPEC "grammar") The name of the parser specification file. This file is expected in the directory specified at tt(PARSER_DIR). ) manpagesection(SCANNER MAINTENANCE) The following directives are available in cases where a program uses a scanner generator creating a lexical scanner class from a set of regular expressions: itemization( itb(#define SCANNER_DIR "") The subdirectory containing the scanner's specification file. If lexical scanner maintenance is not required, then this directive can be omitted. If omitted, then all other directives, that begin with tt(SCAN), can also be omitted. itb(#define SCANFILES "") If the lexical scanner specification file named at tt(SCANSPEC) itself includes additional specification files, then patterns matching these additional lexer specification files should be specified here. The pattern is interpreted in the directory specified at tt(SCANNER_DIR) and could contain a subdirectory name (e.g. tt(specs/*)). When files matching the pattern are modified then a new lexical scanner will be created. By default no additional specification files are used. itb(#define SCANFLAGS "") The flags to use when calling the program specified at tt(SCANGEN). itb(#define SCANGEN "flexc++") The name of the program generating the lexical scanner. itb(#define SCANOUT "lex.cc") The name of the file generated by the lexical scanner (which is used by tt(icmbuild) to compare the timestamps of the scanner specification file(s) against). itb(#define SCANSPEC "lexer") The name of the lexical scanner specification file. This file is expected in the directory specified at tt(SCANNER_DIR). ) manpagefiles() The mentioned paths are sugestive only and may be installation dependent: itemization( itb(/usr/share/icmake/CLASSES) Example of an bf(icmconf) tt(CLASSES) file. itb(/usr/share/icmake/icmconf) Default skeleton bf(icmbuild) resource file. itb(/etc/icmake) Directory containing the default system-wide bf(icmake)(1) configuration files (like tt(VERSION) and tt(icmstart.rc)) itb($HOME/.icmake) Optional directory containing user-defined specifications overruling the system-wide definitions. This directory is the proper location for a file tt(AUTHOR) defining the tt(AUTHOR) directive with the user's name. E.g., my tt(.icmake/AUTHOR) file contains: verbinclude(/home/frank/.icmake/AUTHOR) ) manpageseealso() bf(icmake)(1), bf(icmbuild)(1), bf(icmstart)(1), bf(icmstart.rc)(7). manpagebugs() bf(icmbuild)(1) ends displaying a fatal error message if the current working directory does not contain a file tt(icmconf). includefile(trailer.inc) icmake-9.02.06/doc/manpage/icmstart.yo0000644000175000017500000001763613176557635016520 0ustar frankfrankincludefile(release.yo) htmlbodyopt(text)(#27408B) htmlbodyopt(bgcolor)(#FFFAF0) whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl)) DEFINEMACRO(sop)(3)(\ it() bf(-ARG1) ARG2 nl()ARG3\ ) DEFINEMACRO(itt)(1)(\ it()tt(ARG1)\ ) DEFINEMACRO(itb)(1)(\ it()bf(ARG1)nl()\ ) DELETEMACRO(tt) DEFINEMACRO(tt)(1)(em(ARG1)) COMMENT( man-request, section, date, distribution file, general name) manpage(icmstart)(1)(_CurYrs_)(icmake._CurVers_.tar.gz) (starts icmbuild program maintenance) COMMENT( man-request, larger title ) manpagename(icmstart)(A startup script for icmbuild program maintenance) COMMENT( all other: add after () ) manpagesynopsis() bf(icmstart) tt([Options]) top-dir [program|library] manpagedescription() Although tt(icmake)-scripts can be written from scratch for handling program maintenance, often the required actions are highly comparable. This observation resulted in the construction of two tt(icmake)-tools: bf(icmstart)(1), initializing a directory for program development and bf(icmbuild)(1), handling the actual program maintenance. Both come predefined with tt(icmake's) distribution, to initialize and maintain bf(C++) programs (or, after minimal adaptation, bf(C)) programs). They can also easily be tailored to other programming languages. The tt(icmstart) script and tt(icmbuild) program can directly be called: tt(icmstart) is an tt(icmake) script, for which the command-shell calls tt(icmake); tt(icmbuild) is a small bf(C) program that calls tt(icmake) to process the tt(icmbuild) script in (commonly) tt(/usr/lib/icmake). This man-page covers the bf(icmstart) script; refer to the bf(icmbuild)(1) man-page for information about how tt(icmbuild) can be used. The bf(icmstart) script is a generic script that can be used to initialize a directory with a basic set of files that are commonly used when developing a bf(C++) or bf(C) program. bf(Icmstart) creates an initial directory (here named `tt(top-dir)') and installs the files tt(CLASSES, VERSION) and tt(icmconf) below tt(top-dir). A second argument `tt(program)' or `tt(library)' may be specified as the default mode of operation of the bf(icmbuild)(1) script, usually resulting in the addition of additional skeleton source files. If the predefined set of files doesn't fit your needs, then the default set can easily be tailored to your needs. The default set of skeleton files is listed in the file tt(/etc/icmake/icmstart.rc). Refer to the bf(icmstart.rc)(7) man-page for information about how this file is structured and how it can be adapted. After changing to the directory created by bf(icmstart) bf(icmbuild)(1) may be used for program maintenance. manpageoptions() tt(Icmstart) supports the following options, which (when specified) must be tt(icmstart's) first arguments: itemization( itt(-b)nl() Basic installation: the files VERSION, usage.cc and version.cc are not installed, and the #define USE_VERSION entry in icmconf is commented out. itt(-c confpath)nl() Use the configuration files (tt(icmstart.rc, AUTHOR, YEARS) and tt(VERSION)) if found in `confpath' rather than in tt(~/.icmake) and/or tt(/etc/icmake/). Once a file is found it is used allowing partial overrides of the default files provided by bf(icmake)(1). itt(-d)nl() Do not execute any commands, but show the commands that would have been executed on the standard output. itt(-I)nl() Do not install files. itt(-r) Unconditionally replace existing files. If tt(-r) is not provided bf(icmstart) will ask the user to confirm that an existing file must be overwritten. If a skeleton specification refers to a directory, the full directory and its subdirectories will be replaced. itt(-s skeleton-path) nl() By default skeleton files are listed in the skeleton resource file tt(/usr/share/icmake/icmstart.rc). Alternatively, the skeleton resource file may be specified by the tt(ICM) environment variable, which -in turn- may be overruled by the path specified with the tt(-s) option. The skeleton path may be specified as a full file-path or as a directory, in which case the skeleton resource file is assumed to be tt(icmstart.rc) (see below at bf(SKELETON FILES)). ) Since bf(icmstart) uses tt(cp) to install files, tt(cp) must be available when bf(icmstart) should install skeleton files. manpagesection(SKELETON FILES) Skeleton resource files may contain comment (empty lines and lines beginning with the hash-mark (tt(#))) which is ignored, and should otherwise contain specifications of resource file(s) to install. The default resource specification file is tt(/etc/icmake/icmstart.rc), containing: verb( CLASSES icmconf P main.cc P main.ih P usage.cc P version.cc P ? scanner P ? parser ) This file is overruled by tt(~/.icmake/icmstart.rc). The tt(~/.icmake) directory (called `configuration directory' below) can be prepared using the following system command: verb( cp -r /etc/icmake ~/.icmake ) This directory can be provided with skeleton files. Default skeleton files are commonly found in tt(/usr/share/icmake), and could be copied to the configuration directory and referred to by the configuration directory's file tt(icmstart.rc). See bf(icmstart.rc)(7) for details about how skeleton files can be referred to tt(icmstart.rc). manpagesection(CONFIGURATION FILES) The configuration directory's files tt(icmstart.rc, AUTHOR, YEARS) and tt(VERSION) are recognized as skeleton files and are, if available, processed by tt(icmstart). If the tt(-c) option was specified configuration files found in the path specified at this option are used. If not specified or if a file isn't found then the path tt(~/icmake) is inspected. If a configuration file isn't found in tt(~/icmake) either, configuration files in tt(/etc/icmake) are used. Configuration files are optional; if absent tt(icmstart) can still be used, but in normal cases at least tt(icmstart.rc) is provided. In addition to tt(icstart.rc) consider defining the files tt(AUTHOR, VERSION,) and tt(YEARS) in the configuration directory: itemization( it() If the file tt(AUTHOR) exists it should have one line, defining the author of the program. E.g., verb( #define AUTHOR "Frank B. Brokken " ) If it does not exist tt(icmstart) uses the default tt(#define AUTHOR ""). it() If the file tt(VERSION) exists it should have one line, defining the program's version. E.g., verb( #define VERSION "1.00.00" ) If it does not exist tt(icmstart) uses the default tt(#define VERSION "0.00.00"). it() If the file tt(YEARS) exists it should have one line, defining the program's initial release year or range of release years. E.g., verb( #define YEARS "2016" ) or a range of years can be defined: verb( #define YEARS "1992-2016" ) If it does not exist tt(icmstart) uses the default tt(#define YEARS "yyyy") where tt(yyyy) is the current year. ) The tt(AUTHOR, VERSION,) and tt(YEARS) definitions are concatenated to one file, called tt(VERSION), which is installed in the top-level directory. If the file tt(icmstart.rc) does not exist (or is empty) tt(icmstart) merely installs the top-level directory, tt(icmconf) and tt(VERSION). manpagefiles() The mentioned paths are sugestive only and may be installation dependent: itemization( it() bf(/usr/share/icmake/icmconf) Example of a bf(icmbuild) configuration file; it() bf(/usr/share/icmake/CLASSES) Example of a bf(icmbuild) tt(CLASSES) file. it() bf(/etc/icmake/icmstart.rc) Default skeleton resource file. ) manpageseealso() bf(icmake)(1), bf(icmbuild)(1), bf(icmconf)(7), bf(icmstart.rc)(7). manpagebugs() None reported includefile(trailer.inc) icmake-9.02.06/doc/icmconf.70000644000175000017500000003720413237047127014374 0ustar frankfrank.TH "icmconf" "7" "1992\-2018" "icmake\&.9\&.02\&.06\&.tar\&.gz" "configuration file for \fBicmbuild\fP(1)" .PP .SH "NAME" icmconf \- Configuration file for the \fBicmbuild\fP(1) program maintenance script .PP .SH "DESCRIPTION" .PP The \fIicmconf\fP configuration file is used to specify and fine\-tune the program maintenance performed by the \fBicmbuild\fP(1) script\&. It can be used to activate and specify various directives that determine how the program or library maintenance is performed\&. .PP The directives are biased towards the construction of a \fBC++\fP program, but program maintenance for other languages (e\&.g\&., \fBC\fP) can also easily be configured\&. .PP The \fBicmbuild\fP(1) script ignores empty lines and lines whose first non\-blank characters are two consecutive forward slashes (//)\&. Long lines can be split over multiple lines by using a final backslash character at lines continuing at the next line (refer to the \fBicmake\fP(1) man\-page for further details)\&. .PP .SH "CLASS DEPENDENCIES" .PP Traditional make\-utilities recompile all dependent sources once header files are modified\&. When developing \fBC++\fP programs this is hardly ever requird, as adding a new member function to a class does not require you to recompile already existing source files\&. Recompilation \fIis\fP required when modifying the data member organization of classes\&. .PP To handle class dependencies in a more sensible way, \fBicmake\fP(1) checks class dependencies using its support program \fI/usr/lib/icmake/icm\-dep\fP, visiting the classes listed in the \fICLASSES\fP file if \fIicmconf\(cq\&s USE_ALL\fP directive was specified\&. If a directory mentioned in the \fICLASSES\fP file contains a file having a name that\(cq\&s equal to the name specified at the \fIUSE_ALL\fP parameter, then all sources of classes that depend on that particular class are also recompiled\&. .PP Likewise, if the \fIPRECOMP\fP parameter was specified, then a similar action is performed for the precompiled headers: if a local header file that\(cq\&s (directly or indirectly) included by a class\(cq\&s internal header file has changed, then that class\(cq\&s precompiled header as well as all precompiled headers of dependent classes are recompiled\&. .PP The \fBicmbuild\fP(1) script itself does not inspect these dependencies, but calls \fI/usr/lib/icmake/icm\-dep\fP to perform the requird tests\&. The program \fIicm\-dep\(cq\&s\fP short usage summary is written to the standard output stream when calling \fIicmake \-d\fP (or directly: \fI/usr/lib/icmake/icm\-dep\fP)\&. .PP .SH "ICMCONF PARAMETERS" .PP .IP o \fB#define ADD_LIBRARIES \(dq\&\(dq\&\fP .br When a program must be linked against additional libraries (other than the name of the program\(cq\&s library itself, if specified at \fILIBRARY\fP) then those libraries should be specified, blank space separated, here\&. E\&.g\&., when a program is linked against \fIlibbobcat\fP then the specification is: .nf #define ADD_LIBRARIES \(dq\&bobcat\(dq\& .fi If your program is linked against multiple libraries, then use a blank\-separated list of libraries (like \fI\(dq\&math bobcat\(dq\&\fP) .IP .IP o \fB#define ADD_LIBRARY_PATHS \(dq\&\(dq\&\fP .br When the additional libraries (specified at \fIADD_LIBRARIES\fP) are located in non\-standard library locations (e\&.g\&., not in \fI/lib\fP and \fI/usr/lib\fP) then these additional paths are (blank space separated) specified here\&. Specify only the paths, not the \fI\-L\fP flags\&. .IP It is stronly advised to specify full pathnames here, or remember that normally the location of the \fIicmconf\fP file is not the location where the compilation actually takes place, which is the location specified at the \fITMP_DIR\fP parameter (see below)\&. .IP .IP o \fB#define CLS\fP .br The \fIclear screen\fP directive\&. If defined \fItput clear\fP is called to clear the terminal screen before starting the compilation\&. By default it is not defined\&. .IP .IP o \fB#define CXX \(dq\&g++\(dq\&\fP .br The C++ compiler to use\&. For a \fBC\fP compiler use, e\&.g\&., \fI#define CC \(dq\&gcc\(dq\&\fP\&. Its setting is overruled by an identically named environment variable\&. .IP .IP o \fB#define CXXFLAGS \(dq\&\-\-std=c++14 \-Wall \-O2\(dq\&\fP .br The compiler options to use\&. The default options are shown\&. When the \fBC\fP compiler is used, use \fI#define CFLAGS\fP rather than \fICXXFLAGS\fP\&. Its setting is overruled by an identically named environment variable\&. .IP .IP o \fB#define DEFCOM \(dq\&\&.\&.\&.\(dq\&\fP .br A \fIDEFCOM\fP directive may be added to the \fIicmconf\fP file (the \fBicmstart\fP(1) script can do this for you)\&. It may be defined as: .nf #define DEFCOM \(dq\&program\(dq\& .fi in which case \fIicmbuild\fP will do program maintenance\&. It may also be defined as: .nf #define DEFCOM \(dq\&program strip\(dq\& .fi in which case \fIicmbuild\fP does program maintenance, creating a stripped binary program\&. .IP Alternatively it may also be defined as: .nf #define DEFCOM \(dq\&library\(dq\& .fi in which case \fIicmbuild\fP does library maintenance\&. .IP .IP o \fB//#define ICM_DEP \(dq\&\-V go\(dq\&\fP .br The existence and implied existence of \fIUSE_ALL\fP files (see the description of the \fIUSE_ALL\fP directive), as well as the correct ages of precompiled headers can be checked by \fIicmake\(cq\&s\fP support program \fIicm_dep\fP\&. By default \fIicm_dep\fP is called with the shown default arguments\&. If \fIicm_dep\fP should not be called define \fIICM_DEP\fP as an empty string (\fI\(dq\&\(dq\&\fP)\&. \fBIcmake\fP(1)\(cq\&s man\-page contains a separate section about the \fIicm_dep\fP support program\&. .IP .IP o \fB#define IH \(dq\&\&.ih\(dq\&\fP .br The extension used for internal header files\&. See \fI#define PRECOMP\fP below\&. .IP .IP o \fB#define LDFLAGS \(dq\&\(dq\&\fP .br The linker options to use\&. By default no options are passed to the linker\&. Its setting is overruled by an identically named environment variable\&. .IP .IP o \fB#define LIBRARY \(dq\&modules\(dq\&\fP .br By default this directive is not defined\&. If defined a local library is constructed\&. When a binary program is built it will be linked against this library rather than to the individual object modules\&. .IP If a library must be constructed (see also the \fIDEFCOM\fP directive), then the \fILIBRARY\fP directive must specify the library\(cq\&s base name (without the \fIlib\fP prefix and without the \fI\&.a\fP extension)\&. .IP After a library has been constructed \fIicmbuild install static dir\fP installs the static library at \fIdir\fP, while \fIicmbuild install shared dir\fP installs the shared library (see below at \fI#define SHARED\fP) at \fIdir\fP\&. .IP .IP o \fB#define MAIN \(dq\&main\&.cc\(dq\&\fP .br The source file in which the \fIint main\fP function is defined\&. This specification may be left as\-is or may completely be removed if \fBicmbuild\fP(1) is used for library maintenance rather than program maintenance\&. .IP .IP o \fB//#define NO_PRECOMP_WARNING\(dq\&\fP .br When \fIPRECOMP\fP is defined (see below) a warning is issued when a class\-directory does not contain a \fIIH\fP file\&. Such warnings are suppressed when defining \fINO_PRECOMP_WARNING\fP\&. This option is ignored unless \fIPRECOMP\fP has been defined\&. .IP .IP o \fB#define OBJ_EXT \(dq\&\&.o\(dq\&\fP .br The extension of object modules created by the compiler\&. .IP .IP o \fB//#define PRECOMP \(dq\&\-x c++\-header\(dq\&\fP .br When activated internal header files (see \fI#define IH\fP) are precompiled when they are more recent than their precompiled versions\&. Also, when a precompiled header file is (re)compiled the precompiled header files of all dependent classes are also recompiled\&. .IP Precompiled headers are removed by \fIicmbuild clean\fP\&. To specify internal header files for other languages change the \fI\-x\fP specification accordingly\&. By default this \fI#define\fP is not active\&. .IP .IP o \fB#define REFRESH\fP .br Define \fIREFRESH\fP to relink the binary program at every \fIicmbuild program\fP call\&. By default \fIREFRESH\fP is \fInot\fP defined\&. .IP .IP o \fB#define SHARED\fP .br This directive is only interpreted if \fILIBRARY\fP was also specified\&. If defined a static library (extension \fI\&.a\fP) as well as a shared library (extension \fI\&.so*\fP) is built\&. If not specified, but \fILIBRARY\fP was specified, only the static library is built\&. By default \fISHARED\fP is not defined\&. .IP The shared library receives as its major version number \fIVERSION\fP\(cq\&s major version number, and receives \fIVERSION\fP as its full version number\&. E\&.g\&., if \fIVERSION\fP is defined as \fI1\&.02\&.03\fP and \fILIBRARY\fP is defined as \fIdemo\fP then the shared library \fIlibdemo\&.so\&.1\&.02\&.03\fP is constructed, with \fIlibdemo\&.so\&.1\fP soft\-linking to it, with \fIlibdemo\&.so\fP in turn soft\-linking to \fIlibdemo\&.so\&.1\fP\&. .IP .IP o \fB#define SHAREDREQ \(dq\&\(dq\&\fP .br When creating a shared library \fISHAREDREQ\fP specifies the names of libraries and library paths that are required by the shared library\&. E\&.g\&., if a library is found in \fI/usr/lib/special\fP, assuming that the name of the required library is \fIlibspecial\&.so\fP, then use the specification \fI\(dq\&\-L/usr/lib/special \-lspecial\(dq\&\fP\&. The \fI/lib\fP and \fI/usr/lib\fP paths are usually predefined and need not be specified\&. This directive is only interpreted if \fISHARED\fP and \fILIBRARY\fP were also defined\&. .IP .IP o \fB#define SOURCES \(dq\&*\&.cc\(dq\&\fP .br The pattern to locate sources in a directory\&. The default value is shown\&. .IP .IP o \fB#define TMP_DIR \(dq\&tmp\(dq\&\fP .br The directory in which intermediate results are stored\&. Relative to the current working directory unless an absolute path is specified\&. .IP .IP o \fB#define USE_ALL \(dq\&a\(dq\&\fP .br After defining this directive (by default it is \fInot\fP defined) class dependencies are interpreted\&. In this case, when a directory contains a file having a name that\(cq\&s equal to the name specified at the \fIUSE_ALL\fP directive, then all sources of that class as well as all sources of classes that depend on it are (re)compiled\&. .IP Following the successful recompilations the \fBs\fP specified at \fI#define USE_ALL\fP are removed\&. .IP When the \fIUSE_ALL\fP directive was specified the command \fIicmbuild clean\fP also removes any leftover \fIUSE_ALL\fP files from the program\(cq\&s subdirectories\&. .IP .IP o \fB#define USE_ECHO ON\fP .br When specified as \fION\fP (rather than \fIOFF\fP) commands executed by \fIicmbuild\fP are echoed\&. .IP .IP o \fB#define USE_VERSION\fP .br If defined (which is the default) the file \fIVERSION\fP is read by \fIicmconf\fP to determine the program/library\(cq\&s version, and the project\(cq\&s release years\&. .PP .SH "PARSER MAINTENANCE" .PP The following directives are available in cases where a program uses a parser generator creating a parser class from a grammar specification: .PP .IP o \fB#define PARSER_DIR \(dq\&\(dq\&\fP .br The subdirectory containing the parser\(cq\&s specification file\&. .IP If parser maintenance is not required, then this directive can be omitted\&. If omitted, then all other directives, that begin with \fIPARS\fP, can also be omitted\&. .IP .IP o \fB#define PARSFILES \(dq\&\(dq\&\fP .br If the parser specification file named at \fIPARSSPEC\fP itself includes additional specification files, then patterns matching these additional grammar specification files should be specified here\&. The pattern is interpreted in the directory specified at \fIPARSER_DIR\fP and could contain a subdirectory name (e\&.g\&. \fIspecs/*\fP)\&. When files matching the pattern are modified then a new parser will be created\&. By default no additional specification files are used\&. .IP .IP o \fB#define PARSFLAGS \(dq\&\-V\(dq\&\fP .br The flags to use when calling the program specified at \fIPARSGEN\fP\&. .IP .IP o \fB#define PARSGEN \(dq\&bisonc++\(dq\&\fP .br The name of the program generating the parser\&. .IP .IP o \fB#define PARSOUT \(dq\&parse\&.cc\(dq\&\fP .br The name of the file generated by the parser generator (which is used by \fIicmbuild\fP to compare the timestamps of the parser specification \fBs\fP against)\&. .IP .IP o \fB#define PARSSPEC \(dq\&grammar\(dq\&\fP .br The name of the parser specification file\&. This file is expected in the directory specified at \fIPARSER_DIR\fP\&. .PP .SH "SCANNER MAINTENANCE" .PP The following directives are available in cases where a program uses a scanner generator creating a lexical scanner class from a set of regular expressions: .PP .IP o \fB#define SCANNER_DIR \(dq\&\(dq\&\fP .br The subdirectory containing the scanner\(cq\&s specification file\&. .IP If lexical scanner maintenance is not required, then this directive can be omitted\&. If omitted, then all other directives, that begin with \fISCAN\fP, can also be omitted\&. .IP .IP o \fB#define SCANFILES \(dq\&\(dq\&\fP .br If the lexical scanner specification file named at \fISCANSPEC\fP itself includes additional specification files, then patterns matching these additional lexer specification files should be specified here\&. The pattern is interpreted in the directory specified at \fISCANNER_DIR\fP and could contain a subdirectory name (e\&.g\&. \fIspecs/*\fP)\&. When files matching the pattern are modified then a new lexical scanner will be created\&. By default no additional specification files are used\&. .IP .IP o \fB#define SCANFLAGS \(dq\&\(dq\&\fP .br The flags to use when calling the program specified at \fISCANGEN\fP\&. .IP .IP o \fB#define SCANGEN \(dq\&flexc++\(dq\&\fP .br The name of the program generating the lexical scanner\&. .IP .IP o \fB#define SCANOUT \(dq\&lex\&.cc\(dq\&\fP .br The name of the file generated by the lexical scanner (which is used by \fIicmbuild\fP to compare the timestamps of the scanner specification \fBs\fP against)\&. .IP .IP o \fB#define SCANSPEC \(dq\&lexer\(dq\&\fP .br The name of the lexical scanner specification file\&. This file is expected in the directory specified at \fISCANNER_DIR\fP\&. .PP .SH "FILES" The mentioned paths are sugestive only and may be installation dependent: .IP o \fB/usr/share/icmake/CLASSES\fP .br Example of an \fBicmconf\fP \fICLASSES\fP file\&. .IP o \fB/usr/share/icmake/icmconf\fP .br Default skeleton \fBicmbuild\fP resource file\&. .IP o \fB/etc/icmake\fP .br Directory containing the default system\-wide \fBicmake\fP(1) configuration files (like \fIVERSION\fP and \fIicmstart\&.rc\fP) .IP o \fB$HOME/\&.icmake\fP .br Optional directory containing user\-defined specifications overruling the system\-wide definitions\&. This directory is the proper location for a file \fIAUTHOR\fP defining the \fIAUTHOR\fP directive with the user\(cq\&s name\&. E\&.g\&., my \fI\&.icmake/AUTHOR\fP file contains: .IP .nf #define AUTHOR \(dq\&Frank B\&. Brokken (f\&.b\&.brokken@rug\&.nl)\(dq\&; .fi .IP .SH "SEE ALSO" \fBicmake\fP(1), \fBicmbuild\fP(1), \fBicmstart\fP(1), \fBicmstart\&.rc\fP(7)\&. .PP .SH "BUGS" \fBicmbuild\fP(1) ends displaying a fatal error message if the current working directory does not contain a file \fIicmconf\fP\&. .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 icmake-9.02.06/doc/icmbuild.10000644000175000017500000002653513237047127014545 0ustar frankfrank.TH "icmbuild" "1" "1992\-2018" "icmake\&.9\&.02\&.06\&.tar\&.gz" "Icmake\(cq\&s generic program maintenance facility" .PP .SH "NAME" icmbuild \- A generic, C++/C program maintenance facility .PP .SH "SYNOPSIS" \fIicmbuild\fP [\-h] [\-c] \fIargs\fP .PP .SH "DESCRIPTION" .PP \fIIcmbuild\fP is a small \fBC\fP program calling \fBicmake\fP(1) to do program maintenance as defined in the \fIicmbuild\fP script that\(cq\&s (commonly) found in \fI/usr/lib/icmake\fP\&. .PP \fIIcmbuild\(cq\&s\fP actions are tailored through a configuration file (\fIicmconf\fP) which must be present in the directory where program maintenance is requested\&. This file is automatically installed by \fBicmstart\fP(1)\&. Refer to \fBicmconf\fP(7)\(cq\&s man\-page for details about this file\&. .PP \fIIcmbuild\fP assumes that your sources exist in and below the current working directory\&. The file \fIicmconf\fP in \fBicmake\fP(1)\(cq\&s distribution provides an example of an \fIicmconf\fP file that can be used by \fIicmbuild\fP\&. In that example \fIicmconf\fP file it is assumed that \fBC++\fP sources are maintained, but program maintenance for, e\&.g\&., \fBC\fP sources can easily be configured\&. If \fIicmbuild\fP is called, but \fIicmconf\fP is not available it displays a usage\-summary after which icm() ends\&. .PP \fIIcmbuild\fP() handles the maintenance for all sources in each of the subdirectories named in the file \fICLASSES\fP, and in addition the maintenance of all sources in the current working directory\&. `Maintenance\(cq\& involves compiling all as yet uncompiled source files, recompilation of modified source files, and optionally library maintenance and the pre\-compilation of header files, which commonly results in a marked reduction of source compilation times\&. .PP When source files are compiled object modules are produced which may be stored in a library, against which the object module of the program\(cq\&s \fImain\fP function is linked\&. It is also possible to specify additional libraries against which the program must be linked\&. .PP If a library is constructed it is kept up to date by \fIicmbuild\fP\&. When a source is successfully compiled its new object module replaces the old one that is found in the library\&. At that point the separate object files are no longer required and are removed by \fIicmbuild\fP\&. .PP Up to \fIicmake\fP version 9\&.01\&.00 \fIicmbuild\fP was installed as an executable \fIicmake\fP script in (commonly) \fI/usr/bin\fP\&. The dependency of this script on the file \fIicmconf\fP made it difficult to provide usage information if \fIicmconf\fP was absent\&. Since version 9\&.02\&.00 the \fIicmbuild\fP script has been moved to (commonly) \fI/usr/lib/icmake\fP, and \fIicmbuild\fP now is a little \fBC\fP program providing the usage information when necessary or requested, but otherwise executes \fIicmake\fP to process the \fIicmbuild\fP script\&. .PP .SH "KICK\-STARTING ICMBUILD" .PP To use \fIicmbuild\fP do as follows: .IP o Install \fIicmbuild\fP in your path (\fIicmake\(cq\&s\fP installation procedure should already have taken care of that); .IP o Copy \fIicmconf\fP (and probably a file \fICLASSES\fP) to your project\(cq\&s base directory (i\&.e\&., the directory in which and where below the project\(cq\&s sources are found)\&. Usually this has already been taken care of by the \fIicmstart\fP script; .PP Next: .IP o Modify the \fI#defines\fP in the file \fIicmconf\fP to taste; .IP o Enter the names of subdirectories containing sources on separate lines in the file \fICLASSES\fP .IP Note that the order of the classes mentioned in \fICLASSES\fP \fIis\fP relevant in that new class (subdirectory) names can always be added at the end of the file \fICLASSES\fP, but reordering the lines in the \fICLASSES\fP file should be avoided\&. .IP If reordering is necessary, then first run the command \fIicmbuild clean\fP to remove all files that were thus far created by \fIicmbuild\fP\&. Recompilation is necessary as the names of the object files contain class order\-numbers for identification\&. These class\-order numbers prevent file\-name collisions (e\&.g\&., two classes might use a file \fIdata\&.cc\fP) and because of the number\-prefixes replacement of a file \fIx\&.o\fP from class \fIA\fP by file \fIx\&.o\fP from class \fIB\fP is prevented; .IP o Start \fIicmbuild\fP\&. .PP The next section covers \fIicmbuild\(cq\&s\fP modes of operation\&. .PP .SH "OPTIONS" .PP \fIIcmbuild\fP supports two options, at most one should be specified: .IP o \fI\-h\fP: Display a usage summary (also automatically shown when the current directory does not contain a file \fIicmconf\fP); .IP o \fI\-c\fP: Clear the screen (using \fItput clear\fP) before starting the maintenance process\&. .PP Next (after optionally specifying \fI\-c\fP) \fIicmbuild\fP can be provided with the following arguments: .IP o No arguments at all: if \fIicmconf\fP contains the line .nf #define DEFCOM \(dq\&program\(dq\& .fi then this is quivalent to the command \fIicmbuild\fP \fIprogram\fP; .br if \fIicmconf\fP contains the line .nf #define DEFCOM \(dq\&strip\(dq\& .fi then this is quivalent to the command \fIicmbuild\fP \fIstrip\fP; .br if if \fIicmconf\fP contains the line .nf #define DEFCOM \(dq\&library\(dq\& .fi then this is quivalent to the command \fIicmbuild\fP \fIlibrary\fP\&. .br (these commands are further elaborated in this section\&.) \fIDEFCOM\fP specifications are ignored when an explicit argument is passed to \fIicmbuild\fP\&. .IP .IP o \fIclean\fP .br clean up remnants of previous actions; .IP .IP o \fIinstall program \fP .br install the constructed program in the specified \fI\fP (to be used after issuing \fIicmbuild\fP \fIprogram\fP, see below)\&. Example: .nf icmbuild install ~/bin/program .fi This installs the constructed binary program in the user\(cq\&s \fIbin\fP direcotry with the name \fIprogram\fP; .IP .IP o \fIinstall static \fP .br install the constructed static library in the specified path (to be used after issuing \fIicmbuild\fP \fIlibrary\fP, see below)\&. Example: .nf icmbuild static /usr/lib/ .fi This installs the constructed static library (e\&.g\&. \fIlibspecial\&.a\fP) in \fI/usr/lib\fP as \fI/usr/lib/libspecial\&.a\fP\&. .br .IP .IP o \fIinstall shared path\fP install the constructed shared library in the specified path (to be used after issuing \fIicmbuild\fP \fIlibrary\fP), when \fIicmconf\fP defines \fISHARED\fP (cf\&. \fBicmconf\fP(7))\&. Example: .nf icmbuild shared /usr/lib/ .fi This installs the constructed binary shared library (e\&.g\&. \fIlibspecial\&.so\fP) in \fI/usr/lib\fP as \fI/usr/lib/libspecial\&.so\fP\&. In addition, the soft\-links .nf libspecial\&.so \-> libspecial\&.so\&.X libspecial\&.so\&.X \-> libspecial\&.so\&.X\&.Y\&.Y\&.Z .fi are defined in \fI/usr/lib\fP, where \fIX\&.Y\&.Z\fP are the major, minor and subminor versions defined in the file \fIVERSION\fP\&. .IP .IP o \fIlibrary\fP .br do library maintenance (builds a static and optionally (if \fIicmconf\fP defines \fISHARED\fP) a shared (dynamic) library); .IP .IP o \fIprogram\fP .br do program maintenance (builds a program from the sources in the current working directory and from the sources in the directories specified in the file \fICLASSES\fP); .IP .IP o \fIprogram strip\fP .br same as \fIprogram\fP, but the final program is stripped (using the linker\(cq\&s \fI\-s\fP option); .PP .SH "ICM\-DEP" .PP Class dependencies are handled by \fIicmake\fP\(cq\&s support program \fIicm\-dep\fP\&. It can be called from \fIicmake\fP by passing it the option \fI\-d\fP\&. All options and arguments following \fI\-d\fP are forwared to \fIicm\-dep\fP\&. .PP The program \fIicm\-dep\fP is automatically called by \fIicmbuild\fP to handle class dependencies\&. Consider two classes \fIOptions\fP and \fIProcess\fP\&. If \fIProcess\fP uses \fIOptions\fP and if precompiled header files are used, then in addition to \fIOption\(cq\&s\fP header file, \fIProcess\(cq\&s\fP header must also be precompiled if \fIOption\(cq\&s\fP header file changes\&. Likewise, if \fIOption\(cq\&s\fP data organization is changed and \fIOption\fP defines inline members used by \fIProcess\fP or \fIProcess\fP defines an \fIOption\fP data member then, in addition to \fIOption\(cq\&s\fP sources sources \fIProcess\(cq\&s\fP sources must also be compiled\&. For the latter case \fIicmconf\fP uses the \fIUSE_ALL\fP specification: if a \fI`USE_ALL\(cq\&\fP file exists in a directory, then all sources of that directory are recompiled\&. .PP The program \fIicm_dep\fP determines all such class dependencies, and will recompile class header files of all classes depending on classes whose header files must be recompiled\&. Furthermore, if a \fI`USE_ALL\(cq\&\fP file exists in a directory then all sources of classes depending on that directory\(cq\&s class are also recompiled\&. .PP \fIIcm\-dep\(cq\&s\fP options are described in \fBicmake\fP(1)\(cq\&s man\-page\&. .PP To start its work, \fIicm_dep\fP needs one command\-line argument: \fIgo\fP\&. Any other argument results in \fIicm_dep\fP performing a `dry run\(cq\&: it will perform all its duties (and verbose messages are displayed as if \fIgo\fP had been specified), but no files (precompiled headers or \fIUSE_ALL\fP files) will be touched or removed\&. If neither options nor arguments are specified \fIicm_dep\fP writes its usage summary to the standard output\&. .PP By default \fIicmbuild\fP calls \fIicmake \-d \-V go\fP: \fIicm_dep\fP is called to perform its duties and to show its actions on the standard output stream\&. By specifying a \fI#define ICM_DEP\fP parameter in the \fIicmconf\fP file this default can be overruled (cf\&. \fBicmconf\fP(7))\&. .PP .SH "FILES" .PP The mentioned paths are sugestive only and may be installation dependent: .IP o \fB/usr/share/icmake/icmconf\fP Unabbreviated example of an \fIicmbuild\fP configuration file; .IP o \fB/usr/share/icmake/CLASSES\fP Example of an \fIicmbuild\fP \fICLASSES\fP file\&. .PP .SH "EXAMPLES" .PP Here is an example of the configuration file \fIicmconf\fP for a concrete program, using facilities of the \fIbobcat\fP library: .nf #define CLS #define LIBRARY \(dq\&modules\(dq\& #define MAIN \(dq\&main\&.cc\(dq\& #define SOURCES \(dq\&*\&.cc\(dq\& #define OBJ_EXT \(dq\&\&.o\(dq\& #define SHAREDREQ \(dq\&\(dq\& #define TMP_DIR \(dq\&tmp\(dq\& #define USE_ALL \(dq\&a\(dq\& #define USE_ECHO ON #define CXX \(dq\&g++\(dq\& #define CXXFLAGS \(dq\& \-\-std=c++14 \-Wall \-O2 \-pthread\(dq\& \(dq\& \-fdiagnostics\-color=never \(dq\& #define IH \(dq\&\&.ih\(dq\& #define PRECOMP \(dq\&\-x c++\-header\(dq\& #define REFRESH #define LDFLAGS \(dq\&\(dq\& #define ADD_LIBRARIES \(dq\&bobcat\(dq\& #define ADD_LIBRARY_PATHS \(dq\&\(dq\& #define DEFCOM \(dq\&program\(dq\& .fi .PP .SH "SEE ALSO" \fBicmake\fP(1), \fBicmconf\fP(7), \fBicmstart\fP(1), \fBicmstart\&.rc\fP(7) .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 icmake-9.02.06/doc/README.icmbuild0000644000175000017500000000477113176557635015354 0ustar frankfrankThe `icmbuild' script is a generic script that can be used to do program maintenance using icmake. The script expects two files to be available in the directory where program maintenance is required, and the icmbuild script should be available in your path or it should be started as, e.g., ./icmbuild The script assumes that your sources (currently C++ sources, but see the file `icmconfig') exist in the directory in which icmconfig and the file CLASSES live, and that the file CLASSES contains the names of all subdirectories in which class-specific sources are kept. The script compiles all sources in each of these subdirectories, and then all sources in the current working directory (except for the source containing main()) The compiled sources result in object modules which are then stored in a library, against which the main-source is linked. Additional libraries can be added to this linking process as well. Once a library is constructed it is kept up to date by the script. Changing a source will result in replacing its former module by its new module in the library. To use icmbuild the following is suggested: 1. Install icmbuild in your path 2. copy icmconf and CLASSES to your project's base directory (i.e., the directory in which and where below the project's sources are found) 3. Modify the #defines in the file icmconf to taste 4. Mention the subdirectories containing sources in the file CLASSES Note that the order of the classes mentioned in classes *is* relevant. It's no problem when classes are added, but reordering should be prevented. If reordering is required, recompile the library as the final object files contain class order-numbers. These class-order numbers prevent file-name collisions and thus prevent replacing file x.o from class A by file x.o from class B. 5. now simply run icmbuild from the project's base directory and let the help-info tell you what your options are. You should see something like: Usage: icmbuild mode Where `mode' is one of: clean - clean up remnants of previous activities library - build the static library tmp/libmodules.a program - build tmp/binary program strip - build stripped tmp/binary install - to install the software in the locations defined in the icmconf file, optionally below icmake-9.02.06/doc/icmstart.10000644000175000017500000001757213237047127014604 0ustar frankfrank.TH "icmstart" "1" "1992\-2018" "icmake\&.9\&.02\&.06\&.tar\&.gz" "starts icmbuild program maintenance" .PP .SH "NAME" icmstart \- A startup script for icmbuild program maintenance .PP .SH "SYNOPSIS" \fBicmstart\fP \fI[Options]\fP top\-dir [program|library] .PP .SH "DESCRIPTION" .PP Although \fIicmake\fP\-scripts can be written from scratch for handling program maintenance, often the required actions are highly comparable\&. This observation resulted in the construction of two \fIicmake\fP\-tools: \fBicmstart\fP(1), initializing a directory for program development and \fBicmbuild\fP(1), handling the actual program maintenance\&. Both come predefined with \fIicmake\(cq\&s\fP distribution, to initialize and maintain \fBC++\fP programs (or, after minimal adaptation, \fBC\fP) programs)\&. They can also easily be tailored to other programming languages\&. The \fIicmstart\fP script and \fIicmbuild\fP program can directly be called: \fIicmstart\fP is an \fIicmake\fP script, for which the command\-shell calls \fIicmake\fP; \fIicmbuild\fP is a small \fBC\fP program that calls \fIicmake\fP to process the \fIicmbuild\fP script in (commonly) \fI/usr/lib/icmake\fP\&. .PP This man\-page covers the \fBicmstart\fP script; refer to the \fBicmbuild\fP(1) man\-page for information about how \fIicmbuild\fP can be used\&. .PP The \fBicmstart\fP script is a generic script that can be used to initialize a directory with a basic set of files that are commonly used when developing a \fBC++\fP or \fBC\fP program\&. .PP \fBIcmstart\fP creates an initial directory (here named `\fItop\-dir\fP\(cq\&) and installs the files \fICLASSES, VERSION\fP and \fIicmconf\fP below \fItop\-dir\fP\&. A second argument `\fIprogram\fP\(cq\& or `\fIlibrary\fP\(cq\& may be specified as the default mode of operation of the \fBicmbuild\fP(1) script, usually resulting in the addition of additional skeleton source files\&. If the predefined set of files doesn\(cq\&t fit your needs, then the default set can easily be tailored to your needs\&. The default set of skeleton files is listed in the file \fI/etc/icmake/icmstart\&.rc\fP\&. Refer to the \fBicmstart\&.rc\fP(7) man\-page for information about how this file is structured and how it can be adapted\&. .PP After changing to the directory created by \fBicmstart\fP \fBicmbuild\fP(1) may be used for program maintenance\&. .PP .SH "OPTIONS" .PP \fIIcmstart\fP supports the following options, which (when specified) must be \fIicmstart\(cq\&s\fP first arguments: .IP o \fI\-b\fP .br Basic installation: the files VERSION, usage\&.cc and version\&.cc are not installed, and the #define USE_VERSION entry in icmconf is commented out\&. .IP o \fI\-c confpath\fP .br Use the configuration files (\fIicmstart\&.rc, AUTHOR, YEARS\fP and \fIVERSION\fP) if found in `confpath\(cq\& rather than in \fI~/\&.icmake\fP and/or \fI/etc/icmake/\fP\&. Once a file is found it is used allowing partial overrides of the default files provided by \fBicmake\fP(1)\&. .IP o \fI\-d\fP .br Do not execute any commands, but show the commands that would have been executed on the standard output\&. .IP o \fI\-I\fP .br Do not install files\&. .IP o \fI\-r\fP Unconditionally replace existing files\&. If \fI\-r\fP is not provided \fBicmstart\fP will ask the user to confirm that an existing file must be overwritten\&. If a skeleton specification refers to a directory, the full directory and its subdirectories will be replaced\&. .IP o \fI\-s skeleton\-path\fP .br By default skeleton files are listed in the skeleton resource file \fI/usr/share/icmake/icmstart\&.rc\fP\&. Alternatively, the skeleton resource file may be specified by the \fIICM\fP environment variable, which \-in turn\- may be overruled by the path specified with the \fI\-s\fP option\&. The skeleton path may be specified as a full file\-path or as a directory, in which case the skeleton resource file is assumed to be \fIicmstart\&.rc\fP (see below at \fBSKELETON FILES\fP)\&. Since \fBicmstart\fP uses \fIcp\fP to install files, \fIcp\fP must be available when \fBicmstart\fP should install skeleton files\&. .PP .SH "SKELETON FILES" .PP Skeleton resource files may contain comment (empty lines and lines beginning with the hash\-mark (\fI#\fP)) which is ignored, and should otherwise contain specifications of resource \fBs\fP to install\&. .PP The default resource specification file is \fI/etc/icmake/icmstart\&.rc\fP, containing: .nf CLASSES icmconf P main\&.cc P main\&.ih P usage\&.cc P version\&.cc P ? scanner P ? parser .fi This file is overruled by \fI~/\&.icmake/icmstart\&.rc\fP\&. The \fI~/\&.icmake\fP directory (called `configuration directory\(cq\& below) can be prepared using the following system command: .nf cp \-r /etc/icmake ~/\&.icmake .fi This directory can be provided with skeleton files\&. Default skeleton files are commonly found in \fI/usr/share/icmake\fP, and could be copied to the configuration directory and referred to by the configuration directory\(cq\&s file \fIicmstart\&.rc\fP\&. See \fBicmstart\&.rc\fP(7) for details about how skeleton files can be referred to \fIicmstart\&.rc\fP\&. .PP .SH "CONFIGURATION FILES" .PP The configuration directory\(cq\&s files \fIicmstart\&.rc, AUTHOR, YEARS\fP and \fIVERSION\fP are recognized as skeleton files and are, if available, processed by \fIicmstart\fP\&. .PP If the \fI\-c\fP option was specified configuration files found in the path specified at this option are used\&. If not specified or if a file isn\(cq\&t found then the path \fI~/icmake\fP is inspected\&. If a configuration file isn\(cq\&t found in \fI~/icmake\fP either, configuration files in \fI/etc/icmake\fP are used\&. .PP Configuration files are optional; if absent \fIicmstart\fP can still be used, but in normal cases at least \fIicmstart\&.rc\fP is provided\&. .PP In addition to \fIicstart\&.rc\fP consider defining the files \fIAUTHOR, VERSION,\fP and \fIYEARS\fP in the configuration directory: .IP o If the file \fIAUTHOR\fP exists it should have one line, defining the author of the program\&. E\&.g\&., .nf #define AUTHOR \(dq\&Frank B\&. Brokken \(dq\& .fi If it does not exist \fIicmstart\fP uses the default \fI#define AUTHOR \(dq\&\(dq\&\fP\&. .IP .IP o If the file \fIVERSION\fP exists it should have one line, defining the program\(cq\&s version\&. E\&.g\&., .nf #define VERSION \(dq\&1\&.00\&.00\(dq\& .fi If it does not exist \fIicmstart\fP uses the default \fI#define VERSION \(dq\&0\&.00\&.00\(dq\&\fP\&. .IP .IP o If the file \fIYEARS\fP exists it should have one line, defining the program\(cq\&s initial release year or range of release years\&. E\&.g\&., .nf #define YEARS \(dq\&2016\(dq\& .fi or a range of years can be defined: .nf #define YEARS \(dq\&1992\-2016\(dq\& .fi If it does not exist \fIicmstart\fP uses the default \fI#define YEARS \(dq\&yyyy\(dq\&\fP where \fIyyyy\fP is the current year\&. .PP The \fIAUTHOR, VERSION,\fP and \fIYEARS\fP definitions are concatenated to one file, called \fIVERSION\fP, which is installed in the top\-level directory\&. .PP If the file \fIicmstart\&.rc\fP does not exist (or is empty) \fIicmstart\fP merely installs the top\-level directory, \fIicmconf\fP and \fIVERSION\fP\&. .PP .SH "FILES" The mentioned paths are sugestive only and may be installation dependent: .IP o \fB/usr/share/icmake/icmconf\fP Example of a \fBicmbuild\fP configuration file; .IP o \fB/usr/share/icmake/CLASSES\fP Example of a \fBicmbuild\fP \fICLASSES\fP file\&. .IP o \fB/etc/icmake/icmstart\&.rc\fP Default skeleton resource file\&. .PP .SH "SEE ALSO" \fBicmake\fP(1), \fBicmbuild\fP(1), \fBicmconf\fP(7), \fBicmstart\&.rc\fP(7)\&. .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 icmake-9.02.06/doc/icmake.10000644000175000017500000014572313237047127014207 0ustar frankfrank.TH "icmake" "1" "1992\-2018" "icmake\&.9\&.02\&.06\&.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) was designed as a generic tool that can be used as an alternative to \fBmake\fP(1), handling program maintenance\&. It\(cq\&s a generic tool in that \fIicmake\fP\-scripts, written in a language closely resembling the \fBC\fP programming language, can perform tasks that are traditionally the domain of scripting languages\&. .PP \fBIcmake\fP allows programmers to use a programming language (closely resembling the well\-known \fBC\fP\-programming language) to define the actions that are required for (complex) program maintenance\&. For this, \fBicmake\fP offers various special operators as well as a set of support functions that have shown their usefulness in program maintenance\&. .PP Although \fIicmake\fP\-scripts can be written from scratch for handling program maintenance, often the required activities are highly comparable\&. This observation resulted in the construction of two \fIicmake\fP\-scripts: \fBicmstart\fP(1), initializing a directory for program development and \fBicmbuild\fP(1), handling the actual program maintenance\&. Both come predefined as scripts tailored to initializing and maintaining \fBC++\fP programs (or, after minimal adaptation, \fBC\fP programs), but can easily be adapted to other programming languages\&. Both \fIicmstart\fP and \fIicmbuild\fP can be run without explicitly calling \fIicmake\fP\&. .PP This man\-page covers \fIicmake\fP (the program), its support programs and the syntax and facilities offered by \fIicmake\(cq\&s\fP scripting language\&. Refer to the \fBicmstart\fP(1)) man\-page for information about how a directory can be initialized (created) in which (by default) a \fBC++\fP or \fBC\fP program can be developed and refer to the \fBicmbuild\fP(1) man\-page for information about how \fIicmbuild\fP can be used to handle program maintenance\&. .PP It should be stressed that \fIicmake\fP and its support programs and scripts do not offer an \fIIntegrated Development Environment\fP (IDE)\&. It merely performs tasks for which scripts can be written, and it offers just a few pre\-defined scripts (\fIicmstart\fP and \fIicmbuild\fP) that repeatedly have shown to be extremely useful when developing and maintaining programs\&. .PP In its standard operation mode, \fIicmake\fP 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\-dep\fP to handle class\-dependencies (see section \fBICM\-DEP\fP in \fBicmbuild\fP(1)\(cq\&s man\-page for more information about \fIicm\-dep\fP)\&. .IP o \fIicm\-exec\fP to execute the byte\-code file .PP The program \fBicmun\fP(1) can be used to disassemble the compiled byte\-code (\&.bim) file\&. \fIIcmun\fP is mainly used for illustration, education, and debugging\&. As it is not required for \fIicmake\fP\(cq\&s daily use it is not installed in a standard \fIPATH\fP directory but (since \fIicmake\(cq\&s\fP version 9\&.02\&.00) in \fIicmake\(cq\&s\fP \fIlib\fP directory, commonly \fI/usr/lib/icmake\fP\&. .PP Traditional make\-utilities recompile sources once header files are modified\&. When developing \fBC++\fP programs this is often a bad idea, as adding a new member to a class does not normally require you to recompile all of the class\(cq\&s source files\&. To handle class dependencies \fBicmbuld\fP(1) may inspect class dependencies, (re)compiling sources of dependent classes whenever necessary\&. By default, class\-dependencies are not interpreted, but this can easily be changed by activating the \fIPRECOMP\fP and/or \fIUSE_ALL\fP defines in \fIicmconf\fP\&. Refer to the \fBicmconf\fP(7) man\-page for further details\&. .PP Precompiled header files can also easily be used\&. Precompiled header files dramatically reduce the time that is required for compiling classes\(cq\& source files\&. Refer to the \fBicmconf\fP(7) man\-page (in particular the description of the \fIPRECOMP\fP define) for further details\&. .PP \fIIcmake\(cq\&s\fP \fBC\fP\-like scripting language is described in the upcoming sections of this man\-page: .IP o \fBPREPROCESSOR DIRECTIVES\fP .br \- supported preprocessor directives, like \fI#include\fP and \fI#define\fP; .IP o \fBDATA TYPES\fP .br \- \fIint, list, string\fP, and \fIvoid\fP (for functions); .IP o \fBPREDEFINED CONSTANTS\fP .br \- like \fIO_FILE, OFF\fP, and \fIS_IFREG\fP; .IP o \fBOPERATORS\fP .br \- like \fI+, younger\fP, and casts .IP o \fBFLOW CONTROL\fP .br \- \fIif, for, while\fP, etc\&. (the \fIswitch\fP is not available); .IP o \fBPREDEFINED FUNCTIONS\fP .br \- executing programs, changing directories, operations on \fIstring\fP and \fIlist\fP type variables, etc\&.; .IP o \fBUSER DEFINED FUNCTIONS\fP .br \- at least \fImain\fP, with or without its common parameters \fIargc, argv,\fP and \fIenvp\fP\&. .PP .SH "OPTIONS" .PP Where available, single letter options are listed between parentheses beyond their associated long\-option variants\&. .PP The \fI\-\-\fP option is special: .IP o \fI\-\-\fP: \fBicmake\fP arguments separator separating \fBicmake\fP arguments from arguments passed to the \&.bim filenl()\&. Those arguments are passed to the \&.bim file as\-is, and are available from the \fIlist argv\fP parameter available from the \fBicmake\fP script\(cq\&s \fImain\fP function\(cq\&s second parameter (see below at section \fBUSER DEFINED FUNCTIONS\fP)\&. For some options (see below) the \fI\-\-\fP separator is not required\&. .PP \fBIcmake\fP supports various options, and only one of these can be specified when \fBicmake\fP is invocated\&. .PP .IP o \fB\-\-about\fP (\fB\-a\fP) .br Show information about \fBicmake\fP and terminate\&. .IP .IP o \fB\-\-compile\fP (\fB\-c\fP) .br The \fBicmake\fP source file is compiled, generating a \&.bim file\&. .IP .IP o \fB\-\-execute\fP (\fB\-e\fP) .br Execute the \fBicmake\fP \&.bim file, given as \fBicmake\fP\(cq\&s first file argument\&. Any additional arguments are passed to the \&.bim file as\-is, and \fI\-\-\fP should not be specified\&. .IP .IP o \fB\-\-force\fP (\fB\-f\fP) .br The icmake source file is recompiled (even if the \fI\&.bim\fP file is up\-to\-date) either when no other options are specified, or when in combination with options \fI\-\-source\fP and \fI\-\-tmpbin\fP\&. .IP .IP o \fB\-\-help\fP (\fB\-h\fP) .br Provide usage info and terminate\&. .IP .IP o \fB\-\-icm\-dep\fP (\fB\-d\fP) .br Calls \fI/usr/lib/icmake/icm\-dep\fP, passing it all remaining arguments\&. If no additional arguments are specified \fIicm\-dep\(cq\&s\fP short usage information is shown to the std\&. output stream\&. See section \fBICM\-DEP\fP in \fBicbuild\fP(1)\(cq\&s man\-page for more information about the \fIicm\-dep\fP support program\&. An overview of \fIicm\-dep\(cq\&s\fP option follows below, next to this overview of \fBicmake\fP\(cq\&s options\&. .IP .IP o \fB\-\-preprocess\fP (\fB\-p\fP) .br The \fBicmake\fP source file is only preprocessed, and the preprocessed file is written to \fBicmake\fP\(cq\&s second file argument (by default \fI`source\(cq\&\&.pim\fP)\&. .IP .IP o \fB\-\-source\fP (\fB\-i\fP) .br The first argument is the \fBicmake\fP source file, the default binary file is constructed if necessary\&. Any additional arguments are passed to the \&.bim file as\-is, and \fI\-\-\fP should not be specified\&. .IP .IP o \fB\-\-summary\fP (\fB\-F\fP) .br The filenames and flags as well as an overview of all actions to be performed by \fBicmake\fP are shown on the standard output stream\&. .IP .IP o \fB\-t\fP \fItmpbim\fP .br The \fItmpbim\fP argument following \fI\-t\fP is the name of a temporary \&.bim file, which is removed after \fBicmake\fP\(cq\&s call\&. When \fI\&.\fP is specified for \fItmpbim\fP then the default temporary directory, followed by \fBicmake\fP\(cq\&s process\-id, followed by \fI\&.bim\fP is used\&. .IP Following the name of the temporary \&.bim file the name of the \fBicmake\fP source script must be specified\&. Any additional arguments are passed to the \&.bim file as\-is, and \fI\-\-\fP should not be specified; After setting the source script file\(cq\&s executable flag (\fIchmod +x script\fP), and providing it with an initial line like this: .nf #!/usr/bin/icmake \-t\&. .fi the \fBicmake\fP script can directly be called: .nf script arg1 arg2 .fi in which case the \fBicmake\fP script \fI`script\(cq\&\fP is executed while it receives the arguments \fIscript arg1 arg2\fP\&. .IP .IP o \fB\-T\fP \fIdirectory\fP .br The specified directory is used to store temporary files\&. E\&.g\&., when compiling an \fBicmake\fP script, the output of \fBicmake\fP\(cq\&s preprocessor is a temporary file which is removed on exit\&. By default \fI/tmp\fP is used, unless \fI/tmp\fP is not a writable directory, in which case the current user\(cq\&s \fI$HOME\fP directory is used\&. Implicit temporary filenames always start with the process id of the current \fBicmake\fP process\&. .IP .IP o \fB\-\-version\fP (\fB\-v\fP) .br Displays \fBicmake\fP\(cq\&s version number, and terminates\&. .PP \fBIcmun\fP: .PP \fIbimfile\fP: binary \fBicmake\fP script file\&. .PP .SH "ICM\-DEP invocation and options" .PP To start its work, the dependencies\-analyzer \fIicm_dep\fP needs one command\-line argument: \fIgo\fP\&. Any other argument results in \fIicm_dep\fP performing a `dry run\(cq\&: it will perform all its duties (and verbose messages are displayed as if \fIgo\fP had been specified), but no files (precompiled headers or \fIUSE_ALL\fP files) will be touched or removed\&. If neither options nor arguments are specified \fIicm_dep\fP writes its usage summary to the standard output\&. .PP Options of \fIicm\-dep\fP can be specified immediately following \fBicmake\fP\(cq\&s \fI\-\-icm\-dep\fP option\&. The following options are recognized by \fIicm\-dep\fP: .IP o \fB\-\-classes\fP=\fIfilename\fP (\fB\-c\fP) .br By default, \fIicm\-dep\fP inspects dependencies of the classes whose directories are mentioned in the file \fICLASSES\fP\&. If specified in the \fBicmconf\fP(7) file, it will also consider dependencies of the classes \fIParser\fP (directory \fIparser\fP) and \fIScanner\fP (directory \fIscanner\fP), or it uses their actual names as defined in the \fBicmconf\fP(7) file\&. Use this option if instead of \fICLASSES\fP another file should be inspected\&. .IP .IP o \fB\-\-help\fP (\fB\-h\fP) .br \fIIcm\-dep\fP writes a summary of its usage to the standard output and terminates\&. .IP .IP o \fB\-\-icmconf\fP=\fIfilename\fP (\fB\-i\fP) .br By default \fIicm\-dep\fP inspects the contents of an \fIicmconf\fP file, looking for the \fIUSE_ALL\fP and \fIPRECOMP\fP specifications\&. Use this option if instead of \fIicmconf\fP another file should be inspected\&. .IP .IP o \fB\-\-mainih\fP=\fImainheader\fP (\fB\-m\fP) .br The \fIicmconf\fP file uses the \fI#define IH\fP parameter to specify the suffix of class header files that should be precompiled, their filenames being equal to the names of the classes mentioned in the \fICLASSES\fP file\&. \fICLASSES\fP does not specify a top\-level directory\&. The name of the top\-level header file to precompile can be specified using this option\&. By default it is \fImain\&.ih\fP\&. .IP .IP o \fB\-\-gch\fP .br By default precompiled header files are inspected if \fIicmconf\fP contains a \fI#define PRECOMP\fP specification\&. If it does not, but precompiled headers should nonetheless be inspected, the option \fI\-\-gch\fP can be specified\&. .IP .IP o \fB\-\-no\-gch\fP .br By default precompiled header files are inspected if \fIicmconf\fP contains a \fI#define PRECOMP\fP specification\&. If so, but precompiled headers should \fInot\fP be inspected, the option \fI\-\-no\-gch\fP can be specified\&. .IP .IP o \fB\-\-no\-use\-all\fP .br By default files named at the \fI#define USE_ALL\fP specification are inspected if \fIicmconf\fP contains such a specification\&. If it does, but the \fI`USE_ALL\(cq\&\fP files should not be inspected, this option can be specified\&. .IP .IP o \fB\-\-use\-all\fP=\fIfilename\fP .br By default files named at the \fI#define USE_ALL\fP specification are inspected if \fIicmconf\fP contains such a specification\&. If it does not, but \fI`USE_ALL\(cq\&\fP files should nonetheless be inspected, this option can be specified, together with the name of files (existing in one or more directories that indicate that all the directory\(cq\&s source files must be recompiled)\&. .IP .IP o \fB\-\-verbose\fP (\fB\-V\fP) .br This option can be specified multiple times\&. The number of times it is specified defines \fIicm_dep\(cq\&s\fP verbosity\&. If none is specified, \fIicm_dep\fP silently performs its duties\&. If specified once, then \fIicm_dep\fP reports to the standard output what actions it performs; if specified twice it reports the options it encountered; if specified three times it also reports the class dependencies; if specified more often it reports what files it encountered and what situations caused it to make its decisions\&. .IP .IP o \fB\-\-version\fP (\fB\-v\fP) .br \fIIcm_dep\fP reports its version number to the standard output and terminates\&. .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 .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 \-i .fi then \fIicm\fP may be issued as a command, thus executing .nf /usr/bin/icmake \-i icm \&.\&.\&. .fi Alternatively, .nf #!/usr/bin/icmake \-t /tmp/icm .fi may be used, resulting in the execution of .nf #!/usr/bin/icmake \-t /tmp/icm icm \&.\&.\&. .fi In this case the binary file is removed on exit\&. .IP .IP o \fI#include \(dq\&filename\(dq\&\fP .br The file \fIfilename\fP is included at the location of the directive .IP .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 colon\-separated directories specified by the \fIIM\fP environment variable\&. The first occurrence of \fIfilename\fP in the directories specified by the \fIIM\fP environment variable is used\&. .IP .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\&. To prevent infinite recursion at most 100 \fI${identifier}\fP replacements are allowed\&. .IP Definitions continue at the next line if the last character on a line is a backslash (\fI\e\fP)\&. (which is not included in the definition)\&. The preprocessor concatenates double\-quuted strings, and double quoted strings may not span multiple lines\&. Multiple blanks (outside of double quoted strings) in definitions are contracted to a single blank space\&. .IP The definition following the \fI#define\(cq\&s\fP identifier is optional\&. If omitted, the macro is defined, so it can be used in \fI#if(n)def\fP directives (see below), but they are not replaced by any text in \fBicmake\fP code statements\&. .IP .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 read) is byte\-compiled\&. Otherwise, the block of code is ignored\&. .IP .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 .IP o \fI#else\fP .br Terminates a \fI#ifdef\fP and \fI#ifndef\fP directive, reversing the acceptance decision about the following code\&. Only one \fI#else\fP directive can be associated with \fI#if(n)def\fP directives\&. .IP .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\&. The \fI#endif\fP directory and its matching \fI#if(n)def\fP directive must be specified in the same file\&. .IP .IP o \fI#undef identifier\fP .br Remove \fIidentifier\fP from the set of defined symbols\&. This does not affect the specification of any previously defined symbols in which \fIidentifier\(cq\&s\fP definition has been used\&. If \fIidentifier\fP hasn\(cq\&t been defined a warning is issued\&. .PP .SH "DATA TYPES" .PP \fBIcmake\fP supports these data types: .IP o \fIASCII character constants\fP .br ASCII character constants consist of one character, surrounded by single or double quotes\&. Single characters (e\&.g\&., \fI\(cq\&a\(cq\&\fP) represent the character itself\&. Standard escape sequences (e\&.g\&., \fI\(cq\&\en\(cq\&\fP) are supported and represent their standard converted value (e\&.g\&., \fI\(cq\&\en\(cq\&\fP represents ascii value 10 (decimal))\&. Non\-standard escape sequences (e\&.g\&., \fI\(cq\&\ex\(cq\&\fP) represent the ascii character following the escape character (so \fI\(cq\&\ex\(cq\&\fP equals \fI\(cq\&x\(cq\&\fP)\&. Escape sequences consisting of three octal digits represent the ascii character corresponding to the octal value modulo 256 (e\&.g\&., \fI\(cq\&\e123\(cq\&\fP)\&. Escape sequences consisting of an x followed by two hexadecimal digits represent the ascii character corresponding to the hexadecimal value (e\&.g\&., \fI\(cq\&\exa4\(cq\&\fP)\&. .IP .IP o \fIint\fP .br Integral values, ranging from \fI\-0x8000\fP through \fI0x7fff\fP\&. \fIint\fP constants may be specified as decimal numbers (starting with digits 1 through 9), octal numbers (starting with 0, followed by one or more octal digits) hexadecimal numbers (starting with 0x, followed by one or more hexadecimal digits) or as \fIASCII\fP character constants\&. .IP .IP o \fIstring\fP .br Text variables\&. String constants are delimited by double quotes\&. Multiple string constants may be concatenated, but a single string constant may not span multiple lines\&. String constants separated by white space only (i\&.e\&., blanks, newlines, comment) are concatenated and represent one single string constant\&. To indicate an end\-of\-line in a string constant use the \fI\en\fP escape sequence\&. .IP ASCII character constants surrounded by double quotes can also be used in arithmetic expressions if one of the operands is an \fIint\fP\&. The single character string constant \fImust\fP be a constant, and cannot be a \fIstring\fP variable\&. .IP Likewise, ASCII character constants surrounded by single quotes may be used in situations where a string operand is expected\&. .IP .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 .IP o \fIvoid\fP .br Used with function definitions to indicate that the function does not return a value\&. .PP Variables can be defined at the global level as well as at any local level inside functions\&. When defined inside functions, the standard \fBC\fP scoping and visibility rules apply\&. E\&.g\&., local variables can only be used in their own or in more deeply nested blocks, their visibility is masked in more deeply nested blocks by defining an identically named variable inside those more deeply nested blocks\&. Variables are strongly typed, and cannot have type \fIvoid\fP\&. .PP Variables may be initialized when they are defined\&. Initializations are expressions, that can use pre\- or user\-defined functions, constant values, and values of variables that are visible at the point of definition\&. .PP .SH "PREDEFINED CONSTANTS" .PP The following constants 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 constants are architecture dependent: .TS tab(~); -- ll -- ll ll ll ll ll ll ll -- c. symbol~1 when defined on the platform, otherwise 0 unix~Unix, usually with GNU\(cq\&s gcc compiler UNIX~may alternatively be available linux~x86 running Linux (usually with gcc) LINUX~may alternatively be available M_SYSV, M_UNIX~x86 running SCO/Unix _POSIX~_SOURCE Unix with Posix compliant compiler __hpux~HP\-UX, with the native HP compiler .TE .PP .SH "OPERATORS" .PP \fBint\-typed operand(s):\fP .PP All \fBC\fP operators are available (except for pointer operators, as \fBicmake\fP does not support pointers)\&. They operate like their \fBC\fP\-programming language counterparts\&. .PP \fBstring\-typed operand(s):\fP .PP For \fIstring\fP type variables and/or constants the following operators are available (\fIa\fP and \fIb\fP represent \fIstring\fP variables or constants): .PP .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 directly concatetated (without using the \fI+\fP operator), e\&.g\&., the following two lines both define the string \fI\(dq\&hello world\(dq\&\fP: .nf \(dq\&hello \(dq\& \(dq\&world\(dq\& \(dq\&hello \(dq\& + \(dq\&world\(dq\& .fi .IP .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 .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 ordering or characters as defined in the \fIASCII\fP character set\&. .IP .IP o \fI!a\fP: the boolean \fI!\fP (not) operator returns 1 if the \fIstring a\fP is empty, otherwise 0 is returned\&. .IP .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\&. The files \fIa\fP and \fIb\fP do not have to exist: if both don\(cq\&t exist 0 is returned; if \fIb\fP doesn\(cq\&t exist, 1 is returned; if \fIa\fP doesn\(cq\&t exist 0 is returned; if they are equally old 0 is returned\&. (the \fIexists()\fP predefined function (see below, section \fBPREDEFINED FUNCTIONS\fP) can be used to test explicitly whether a file exists)\&. .IP .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\&. The files \fIa\fP and \fIb\fP do not have to exist: if both don\(cq\&t exist 0 is returned; if \fIa\fP doesn\(cq\&t exist, 1 is returned; if \fIb\fP doesn\(cq\&t exist 0 is returned; if they are equally old 0 is returned\&. .IP .IP o \fI[]\fP: the index operator retrieves a character from a string variable or constant: it returns a string as an \fIrvalue\fP\&. Therefore, the following statement compiles OK: .nf // assume str1 and str2 are strings str1 = str2[3]; .fi but the following statement won\(cq\&t compile: .nf str2[3] = \(dq\&a\(dq\&; .fi .IP An empty string is returned if an invalid index value is provided\&. .IP .IP o The `backtick` operator (\fI`string cmd`\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 collected by the backtick operator\&. However, standard shell redirection could be used to collect the standard error stream\(cq\&s output\&. Example: .nf printf(`\(dq\&ls\(dq\&`); // prints the elements in // the current directory .fi The predefined function \fIeval(string cmd)\fP behaves exactly like the backtick operator: they are synonyms\&. .PP \fBlist\-typed operand(s):\fP .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 (set\-addition is provided by the built\-in function \fIlistunion\fP)\&. .IP .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\-difference operation: the returned list contains all elements in \fIa\fP that are not elements of \fIb\fP\&. .IP .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 .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: all elements of \fIa\fP that are found in \fIb\fP are removed from \fIa\fP\&. .IP .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, otherwise 0 is returned\&. Operator \fI!=\fP reverses the result of \fI==\fP\&. .IP .IP o \fI!a\fP: the boolean \fI!\fP operator returns 1 if the \fIlist a\fP is empty, otherwise 0 is returned\&. .IP .IP o \fI[]\fP: the index operator retrieves a list element from a list variable: it returns a string as an \fIrvalue\fP\&. Therefore, the following statement compiles OK: .nf // assume lst is a list, str is a string str = lst[3]; .fi but the following statement won\(cq\&t compile: .nf lst[3] = str; .fi An empty string is returned if an invalid index value is provided\&. .PP \fBCasting:\fP .PP Type\-casts 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 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 statements\&. They can be used as in the \fBC\fP programming language\&. .IP o \fIexpression ;\fP .br The plain expression statement; .IP .IP o The compound statement .br Variables of any type may be defined and initialized anywhere inside any compound statement\&. The \fIvisibility\fP of a variable starts at its point of definition\&. .IP .IP o \fIif (condition) statement\fP .br Inside the condition a variable may be defined and initialized\&. E\&.g, .nf if (string str = getText()) process(str); .fi In this example, \fIprocess\fP is not called if \fIgetText()\fP returns an empty string\&. The variable \fIstr\fP does not exist either before or after the \fIif\fP statement\&. .IP .IP o \fIif (condition) statement else statement\fP .br As with the previous statement, inside the condition a variable may be defined and initialized\&. .IP .IP o \fIfor (init; condition; increment) statement\fP .br Variables (of a single type) may be initialized (and optionally be defined) in the \fIinit\fP section\&. The \fIinit\fP, \fIcondition\fP and \fIincrement\fP sections may remain empty\&. The empty condition section is interpreted as `always \fItrue\fP\(cq\&\&. .IP .IP o \fIwhile (condition) statement\fP .br Inside the condition a variable may be defined and initialized\&. .br A complementary \fIdo \&.\&.\&. while()\fP statement is not available\&. Note that defining a variable, using an initialization expression means that the initialization expressing is executed at each iteration of the \fIwhile\fP statement\&. So the following statement will never end, and will display a never ending stream of values 10: .nf while (int x = 10) printf(x\-\-, \(dq\&\en\(dq\&); .fi .IP .IP o \fIreturn;\fP, and \fIreturn expression;\fP .br Plain \fIreturn\fP statements can be used in \fIvoid\fP functions, and \fIreturn expression\fP statements are used in other type of functions\&. The function \fImain\fP has return type \fIvoid\fP and so in \fImain\fP only plain \fIreturn\fP statements can be used\&. By default an \fBicmake\fP script\(cq\&s exit value equals 0\&. Use the built\-in function \fIexit\fP (see below) to specify any other exit value\&. .IP \fBBe advised: \fP the behavior of non\-void functions not returning values is undefined\&. .IP .IP o \fIbreak\fP .br Leaves \fIfor\fP and \fIwhile\fP statements, overruling the statement\(cq\&s condition\&. .IP .IP o \fIcontinue\fP .br Continues with the next iteration of a \fIfor\fP or \fIwhile\fP statement\&. .IP .IP o \fIexit(expression)\fP .br Ends the execution of an \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 anywhere in \fBicmake\fP scripts\&. The following overview is ordered alphabetically by function name\&. .PP .IP o \fIvoid arghead(string h)\fP .br Helper function of \fIexec()\fP (see also below at \fIexec()\fP): defines the `argument head\(cq\&, to be used with \fIexec()\fP\&. By default, the `argument head\(cq\& is an empty string\&. .IP .IP o \fIvoid argtail (string t)\fP .br Helper function of \fIexec()\fP (see also below at \fIexec()\fP): defines the `argument tail\(cq\&, to be used with \fIexec()\fP\&. By default, the `argument tail\(cq\& is an empty string\&. .IP .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 .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; .IP .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 .IP o \fIstring change_ext(string file, string newext)\fP .br Changes the extension of \fIfile\fP, returns the changed name\&. E\&.g, \fIrss_changeExt(\(dq\&source\&.cc\(dq\&, \(dq\&o\(dq\&)\fP returns \fI\(dq\&source\&.o\(dq\&\fP; .IP .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\&. .IP .IP o \fIstring chdir(string newdir)\fP .br Changes the script\(cq\&s working directory, returns the previous dir as an absolute path\&. .IP Use \fIchdir(\(dq\&\&.\(dq\&)\fP to obtain the 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 .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\&. .IP .IP o \fIcmdhead(string h)\fP .br Helper function of \fIexec()\fP (see also below at \fIexec()\fP): Defines a `command head\(cq\&, to be used with \fIexec()\fP\&. By default, the `command head\(cq\& is an empty string\&. .IP .IP o \fIcmdtail(string t)\fP .br Helper function of \fIexec()\fP (see also below at \fIexec()\fP): Defines a `command tail\(cq\&, to be used with \fIexec()\fP\&. By default, the `command tail\(cq\& is an empty string\&. .IP .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 \fIecho(ON)\fP is used\&. .IP .IP o \fIstring element(int index, list (or string) var)\fP .br Acts identical to the index operator: refer to the index (\fI[]\fP) operator in the section \fBOPERATORS\fP\&. .IP .IP o \fIlist eval(string str)\fP .br This function acts identically to the backtick operator\&. The example provided with the backtick operator could therefore also have been written like this: .nf printf(eval(\(dq\&ls\(dq\&)); // prints the elements in the current // directory .fi .IP .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 .IP o \fIexec(int checkcmd, string cmd, \&.\&.\&.)\fP .br Same functionality as the previous function, but by specifying \fIchecking\fP as \fINOT_CHECKED\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 .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\&. .IP 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 .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 \fINOT_CHECKED\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 .IP o \fIint exists(string file)\fP .br Returns a non\-zero value if \fIfile\fP exists, otherwise 0 is returned\&. .IP .IP o \fIlist fgets(string file, list offset)\fP .br \fBNOTE:\fP in \fBicmake\fP version 8\&.00\&.00 the prototype of this function was changed from \fIlist fgets(string file, int offset)\fP to \fIlist fgets(string file, list offset)\fP\&. .IP The next line found at the offset contained in \fIoffset\fP is read from \fIfile\fP\&. Pass an empty list to \fIfgets\fP to read \fIfile\fP from its beginning\&. .IP It returns a list containing as its first element the contents of the read line (without the \fI\en\fP line terminator), as its second element the line\(cq\&s terminator `\fI\en\fP\(cq\& (if encountered), and as its third element the string \fIOK\fP if a line was successfully read, \fIFAIL\fP if reading from file failed\&. When reading at EOF an empty list is returned\&. The returned list may contain additional elements, which are internally used by \fIfgets\fP when reading the next line\&. .IP To read multiple lines, start by passing an empty list as \fIgets\(cq\&s\fP second argument\&. To read subsequent lines, pass the previously returned list to \fIfgets\(cq\&s\fP second argument\&. .IP Here is an example showing how to read a complete file: .nf list ret; while (1) { ret = fgets(\(dq\&filename\(dq\&, ret); if (!ret) break; process(ret[0], ret[1]); } .fi .IP .IP o \fIint fprintf(string filename, \&.\&.\&.)\fP .br Appends all (comma separated) arguments to the file \fIfilename\fP\&. Returns the number of printed arguments\&. .IP .IP o \fIint fprintf(string filename, string format, \&.\&.\&.)\fP .br Appends all (comma separated) arguments to the file \fIfilename\fP\&. Returns the number of printed arguments\&. .IP If \fIformat\fP contains placeholders %1 \&.\&. %n the output is formatted (see also \fIstrformat\fP)\&. Note that in this case argument counting (also) starts beyond the format string: the first argument following \fIformat\fP is referred to as \fI%1\fP\&. .IP .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\&. E\&.g\&., 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\&. .IP .IP o \fIstring getch()\fP .br Returns the next pressed key as a string (pressing `Enter\(cq\& is not required)\&. .IP .IP o \fIstring get_dext(string file)\fP .br Returns the extension of \fIfile\fP, including the separating dot\&. The extension is all information starting at the filename\(cq\&s final dot\&. .IP If no final dot is found, an empty string is returned\&. .IP .IP o \fIlist getenv(string envvar)\fP .br Returns the value of environment variable \fIenvvar\fP in a list containing two elements: .IP 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\&. .IP .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\&. .IP If no final dot is found, an empty string is returned\&. .IP .IP o \fIint getpid()\fP .br Returns the process\-id of the icmake byte code interpreter \fBicm\-exec\fP\&. .IP .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\&. .IP .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\&. .IP .IP o \fIint listfind(list lst, string str)\fP .br Returns the first index in \fIlst\fP where the string \fIstr\fP is found, or \-1 if \fIlst\fP does not contain \fIstr\fP\&. .IP .IP o \fIint listlen(list l)\fP .br Returns the number of elements in \fIlist\fP\&. .IP .IP o \fIlist listunion(list lhs, list rhs)\fP .br Returns a list containing the union of the elements in \fIlhs\fP and \fIrhs\fP\&. .IP .IP o \fIlist listunion(list lst, string str)\fP .br Returns a list containing the union of the elements in \fIlst\fP and \fIstr\fP\&. .IP .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 .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 .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 .IP o \fIlist makelist([int = IS_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 .IP o \fImakelist(string mask, older, string comparefile)\fP .br See above; returns a list of files that are older than the comparefile\&. .IP .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\&. .IP .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\&. .IP .IP o \fIint printf(string format, \&.\&.\&.)\fP .br Shows all (comma separated) arguments to screen (i\&.e\&., the standard output stream)\&. Returns the number of printed arguments (the \fIformat\fP string counts as one argument)\&. .IP If \fIformat\fP contains placeholders %1 \&.\&. %n the output is formatted (see also \fIstrformat\fP)\&. .IP .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\&. .IP .IP o \fIstring resize(string str, int newlength)\fP Returns a copy of string \fIstr\fP, resized to \fInewlength\fP characters\&. If \fInewlength\fP is negative then an empty string is returned, if \fInewlength\fP exceeds \fIstr\(cq\&s\fP length then the newly added characters are initialized to blank spaces\&. .IP .IP o \fIint sizeof(list l)\fP .br Deprecated: use \fIlistlen\fP\&. .IP .IP o \fIint sizeoflist(list l)\fP .br Deprecated: use \fIlistlen\fP\&. .IP .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 .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 returns \fBstat\fP(2)\(cq\&s return value\&. .IP .IP o \fIint strchr(string str, string chars)\fP .br Returns the first index in \fIstr\fP where any of the characters in \fIchars\fP is found, or \-1 if \fIstr\fP does not contain any of the characters in \fIchars\fP\&. .IP .IP o \fIint strlen(string str)\fP .br Returns the number of characters in \fIstr\fP (not counting the final 0)\&. .IP .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 .IP o \fIint strformat(string format,\&.\&.\&.)\fP .br Returns a formatted string using placeholders %1 \&.\&. %2 to address arguments following format\&. .br Example: .br .nf void main() { int i = 10; int j = 20; string s1; string s2; // traditional approach: s1 = (string)i + \(dq\& \(dq\& + (string)j + \(dq\& \(dq\& + (string)i; // using strformat: s2 = strformat(\(dq\&%1 %2 %1\(dq\&, i, j); printf(\(dq\&s1 = %1, s2 = %2\en\(dq\&, s1, s2); } .fi .IP .IP o \fIstring strlwr(string s)\fP .br Returns a lower\-case duplicate of \fIs\fP\&. .IP .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 .IP o \fIstring strupr(string s)\fP .br Returns an upper\-case duplicate of \fIs\fP\&. .IP .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 \fIoffset = 0\fP is used\&. .IP .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 .IP o \fIint system(int checking, string command)\fP .br Same functionality as the previous function, but by specifying \fIchecking\fP as \fINOT_CHECKED\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 .IP o \fIstring trim(string s)\fP .br Returns a copy of \fIs\fP without leading and trailing white spaces\&. .IP .IP o \fIstring trimleft(string str)\fP .br Returns a copy of \fIs\fP without leading white spaces\&. .IP .IP o \fIstring trim(string s)\fP .br Returns a copy of \fIs\fP without trailing white spaces\&. .PP .SH "USER DEFINED FUNCTIONS" .PP \fBvoid main\fP .PP \fBIcmake\fP scripts must be provided with a user\-defined function \fImain\fP\&. The function \fImain\fP has three optional parameters, which may be omitted from the last one (\fIenvp\fP) to the first (\fIargc\fP), like 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 .IP o \fIargv\fP contains the arguments, with element 0 being equal to the name of the \&.bim file; .IP .IP o \fIenvp\fP contains the `environment\(cq\& variables\&. The function \fIlistlen\fP can be used to determine the number of its elements\&. Elements in \fIenvp\fP have the form \fIvariable=value\fP\&. Alternatively, the function \fIgetenv\fP 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 = length(toCompile); idx\-\-; ) compile(element(idx, toCompile)); if (getenv(\(dq\&dryrun\(dq\&)[0] == \(dq\&0\(dq\&) linking(element(2, argv)); } } .fi .PP Having initialized all global variables in order of their definitions \fImain\fP is called by \fBicmake\fP\(cq\&s run\-time support system to perform additional tasks\&. .PP \fBAdditionally defined user functions\fP .PP Additional functions may be defined\&. Once defined, these functions can be called\&. Forward referencing of either variables or functions is not supported, but recursively calling functions is\&. As function declarations are not supported indirect recursion is not supported either\&. .PP User\-defined functions must have the following elements: .IP o The function\(cq\&s return type, which must be one of \fIvoid, int, string\fP or \fIlist\fP\&. There is no default type\&. .IP .IP o The function\(cq\&s name, e\&.g\&., \fIcompile\fP\&. .IP .IP o A parameter list, defining zero or more comma\-separated parameters\&. The parameters themselves consist of a type name (\fIint, string\fP, or \fIlist\fP) followed by the parameter\(cq\&s identifier\&. E\&.g\&., \fI(string outfile, string source)\fP\&. .IP .IP o A \fIbody\fP surrounded by a pair of curly braces (\fI{\fP and \fI}\fP)\&. .PP 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\&. By default an \fIint\fP variable is initialized to 0, a \fIstring\fP is initialized to an empty string (\fI\(dq\&\(dq\&\fP) and a \fIlist\fP is initialized to a list of zero elements\&. .PP In addition to variable definitions, bodies may contain zero or more statements (cf\&. section \fBFLOW CONTROL\fP)\&. Note that variables may be defined (and optionally initialized) anywhere inside functions, and also in \fIif, for\fP and \fIwhile\fP statements\&. .PP The behavior of \fBicmake\fP\-scripts using non\-void functions that do not return values is not defined\&. .PP .SH "FILES" .PP The mentioned paths are sugestive only and may vary over different \fBicmake\fP\-installations: .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/icmake/icm\-dep\fP: the support program handling class\- and precompiled header dependencies; .IP o \fB/usr/lib/icmake/icm\-pp\fP: the preprocessor called by \fBicmake\fP; .IP o \fB/usr/lib/icmake/icm\-comp\fP: the compiler called by \fBicmake\fP; .IP o \fB/usr/lib/icmake/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" Standard comment starting on lines containing preprocessor directives may not extend over multiple lines\&. .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 icmake-9.02.06/doc/icmstart.rc.70000644000175000017500000001104413237047127015201 0ustar frankfrank.TH "icmstart\&.rc" "7" "1992\-2018" "icmake\&.9\&.02\&.06\&.tar\&.gz" "icmstart resource file" .PP .SH "NAME" icmstart\&.rc \- The icmstart(1) resource file .PP .SH "DESCRIPTION" .PP The \fBicmstart\&.rc\fP file specifies the files that are installed by \fBicmstart\fP(1)\&. .PP By default \fBicmstart\&.rc\fP is found in \fI/etc/icmake/icmstart\&.rc\fP, but if a file \fI$HOME/\&.icmake/icmstart\&.rc\fP is found then the latter file is used by \fBicmstart\fP(1)\&. \fI$HOME/\&.icmake/icmstart\&.rc\fP in turn is overruled by specifying a \fI\-c\fP option when invoking \fBicmstart\fP(1)\&. .PP The default resource file contains the following specifications, preparing for the construction of a \fBC++\fP program using \fBicmbuild\fP(1): .nf CLASSES icmconf P main\&.cc P main\&.ih P usage\&.cc P version\&.cc P ? scanner P ? parser .fi The \fIicmstart\&.rc\fP file may contain: .IP o empty lines, which are ignored; .IP .IP o lines beginning with a hash\-character (\fI#\fP), also ignored; .IP .IP o an optional installation mode followed by a source\-destination specification\&. .PP .SH "INSTALLATION MODE" .PP An installation mode consists of a combination of: .IP o either a P (don\(cq\&t install with \fIicmstart xxx library\fP) or an L (don\(cq\&t install with \fIicmstart xxx program\fP); .IP .IP o a D, indicating that the source must also be installed by default, i\&.e\&., if neither `program\(cq\& or `library\(cq\& was specified as second argument\&. .IP .IP o a b, indicating that the file must \fInot\fP be installed if the \fI\-b\fP (basic installation) option was specified when calling \fIicmstart\fP\&. .IP .IP o Following the optional P, L, D, b combination a space delimited optional \fI?\fP may be specified\&. If specified the installation of the file or directory must be confirmed by the user\&. .PP .SH "SOURCE\-DESTINATION SPECIFICATIONS" .PP The following source\-destination specifications can be used in an \fIicmstart\&.rc\fP file: .IP o \fIsource\fP .br A plain name must exist in the \fIicmstart\(cq\&s\fP skeleton directory\&. It is installed in the destination directory \fI`dest\(cq\&\fP specified when calling \fBicmstart\fP(1)\&. Example: .nf CLASSES .fi \fIskeletondir/CLASSES\fP is installed as \fIdest/CLASSES\fP .IP .IP o \fIpathspec\fP .br If `pathspec\(cq\& does not begin with a slash it must exist in \fIicmstart\(cq\&s\fP skeleton directory\&. It is installed as `pathspec\(cq\& in the destination directory specified when calling \fBicmstart\fP(1)\&. Example: .nf dir/file .fi \fIskeletondir/dir/file\fP is installed as \fIdest/dir/file\fP .IP .IP o \fI/pathspec\fP or \fI~/pathspec\fP The \fI~\fP\-character is expanded to the user\(cq\&s home directory\&. The pathspec\(cq\&s final element is installed in the destination directory specified when calling \fBicmstart\fP(1)\&. Example: .nf ~/\&.icmake/file .fi \fI$HOME/\&.icmake/file\fP is installed as \fIdest/file\fP When the above source specifications are followed by a destination specification \fIdestspec\fP (a file or non\-absolute directory specification) then the source specification is installed as dest/destspec) below the destination directory specified when calling \fBicmstart\fP(1)\&. Examples: .nf CLASSES CLASSES # skeletondir/CLASSES is installed as # dest/CLASSES dir/file dir/file # skeletondir/dir/file is installed as # dest/dir/file ~/\&.icmake/file \&.icmake/file # $HOME/\&.icmake/file is installed as # dest/\&.icmake/file .fi Icmstart conveerts the destination specification to a full path specification\&. If this full path specification does not begin with \fIdest\(cq\&s\fP full path specification an error message is displayed and \fIicmstart\fP ends\&. .PP .SH "FILES" The mentioned paths are sugestive only and may be installation dependent: .IP o \fB/usr/share/icmake/icmconf\fP Example of an \fBicmbuild\fP configuration file; .IP o \fB/usr/share/icmake/CLASSES\fP Example of an \fBicmbuild\fP \fICLASSES\fP file\&. .IP o \fB/usr/share/icmake/icmstart\&.rc\fP Default skeleton resource file\&. .PP .SH "SEE ALSO" \fBicmake\fP(1), \fBicmbuild\fP(1), \fBicmconf\fP(7), \fBicmstart\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 icmake-9.02.06/etc/0000755000175000017500000000000013176557635012702 5ustar frankfrankicmake-9.02.06/etc/icmake/0000755000175000017500000000000013176557635014133 5ustar frankfrankicmake-9.02.06/etc/icmake/icmstart.rc0000644000175000017500000000112013176557635016301 0ustar frankfrank# This file contains lines mentioning frame files to install by icmstart # empty lines and lines starting with # are ignored. # Files and directories are installed by tar, see icmstart(1)'s man-page # Lines starting with P are not installed when 'icmstart xxx library' is # requested. # Lines starting with L are not installed when 'icmstart xxx program' is # requested. # User-confirmation to install is required for entries on lines having a ? # following the optional P or L. CLASSES icmconf P main.cc P main.ih P usage.cc P version.cc P ? scanner P ? parser icmake-9.02.06/examples/0000755000175000017500000000000013176557635013745 5ustar frankfrankicmake-9.02.06/examples/8.00/0000755000175000017500000000000013176557635014332 5ustar frankfrankicmake-9.02.06/examples/8.00/strformat.im0000644000175000017500000000036013176557635016701 0ustar frankfrank#!/usr/bin/icmake -qi int main(int argc, list argv) { int i; string str; for (i = 0 ; i != listlen(argv); ++i) { if (strlen(argv[i]) != 0) str += strformat("arg %1 is '%2'\n", i + 1, argv[i]); } printf("%1", str); return 0; } icmake-9.02.06/examples/defines0000755000175000017500000000042313176557635015307 0ustar frankfrank#!/usr/bin/icmake -t. #define FIRST "This text" #define SECOND "will be printed, starting with: " ${FIRST} #define TEXT ${FIRST} ${SECOND} "${UNCHANGED}\n" #define BASE /usr/local // #define BIN "${BASE}/bin" int main() { printf(TEXT); printf(BIN "\n"); } icmake-9.02.06/examples/7.00/0000755000175000017500000000000013176557635014331 5ustar frankfrankicmake-9.02.06/examples/7.00/strlwr.im0000644000175000017500000000037513176557635016222 0ustar frankfrankvoid main(int argc, list argv) { string line; if (argc == 1) { printf("provide string to be changed to lowercase\n"); exit(1); } line = element(1, argv); printf(line, ": ", strlwr(line), "\n"); exit(0); } icmake-9.02.06/examples/7.00/strfind.im0000644000175000017500000000050413176557635016330 0ustar frankfrankvoid main(int argc, list argv) { if (argc < 3) { printf("Argc = ", argc, ": provide needle (arg1) and haystack (arg2)\n"); exit(1); } printf(element(1, argv), ": `", element(2, argv), "' at ", strfind(element(1, argv), element(2, argv)), "\n"); exit(0); } icmake-9.02.06/examples/7.00/ifdef.im0000644000175000017500000000047313176557635015741 0ustar frankfrank//#define X #define Y void main(int argc, list argv) { #ifdef X printf("X, "); #ifdef Y printf("Y"); #else printf("NON-Y"); #endif #else printf("NON-X, "); #ifdef Y printf("Y"); #else printf("NON-Y"); #endif #endif printf("\n"); exit(0); } icmake-9.02.06/examples/7.00/index.im0000644000175000017500000000026713176557635015774 0ustar frankfrankvoid main(int argc, list argv) { list lst = strtok("aap noot mies", " "); int idx; for (idx = listlen(lst); idx--; ) printf(lst[idx][idx], "\n"); exit(0); } icmake-9.02.06/examples/7.00/define.im0000644000175000017500000000022213176557635016106 0ustar frankfrank#define SUBST "substituted" #define LINE "This is " ${SUBST} " as one line\n" void main(int argc, list argv) { printf(LINE); exit(0); } icmake-9.02.06/examples/7.00/substr.im0000644000175000017500000000070113176557635016200 0ustar frankfrankvoid main(int argc, list argv) { if (argc < 4) { printf("Argc = ", argc, ": provide string (arg1), offset (arg2) and count (arg3)\n"); exit(1); } printf(element(1, argv), ": from ", element(2, argv), " over ", element(3, argv), " chars: ", substr(element(1, argv), (int)element(2, argv), (int)element(3, argv)), "\n"); exit(0); } icmake-9.02.06/examples/7.00/getenv.im0000644000175000017500000000021513176557635016146 0ustar frankfrankvoid main(int argc, list argv) { list term = getenv("TERM"); printf(element(0, term), ": ", element(1, term), "\n"); exit(0); } icmake-9.02.06/examples/7.00/backtick.im0000644000175000017500000000013213176557635016427 0ustar frankfrankvoid main(int argc, list argv) { string cmd = "ls"; printf(`cmd`); exit(0); } icmake-9.02.06/examples/ftpxfer0000755000175000017500000001347713176557635015365 0ustar frankfrank#!/usr/bin/icmake -qi /*************************************************************************** This file shows an example of a shell around ftp. I use this program a lot in situations where I want to transfer a file from one unix host to another, and when I know beforehand what file from what directory I want to transfer. For the installation: - copy this file to your personal bin directory, under the name ftpxfer - make the file executable: chmod +x ftpxfer The program will prompt for the user name and password to use for the ftp transfer. If you often access one host with this program, and don't wont to type the user/password all the time, you can do the follwing for bash: > set FTPUSER my_login_name_on_that_host > export FTPUSER > set FTPASS my_password_on_that_host > export FTPASS For tcsh, try: > setenv FTPUSER my_login_name_on_that_host > setenv FTPASS my_password_on_that_host Net result: this program won't prompt you for the strings, but will retrieve them from the environment table. You can, of course, place these commands in your .login or .tcshrc file, to be executed automatically during the login procedure. But then it may be a good idea to make these files read/write only for you and for nobody else (e.g., by: chmod 644 .login). OB The actual ftp transfer occurs using an intermediate temporary file, TMPFILE in the below #define's. The user name and password _are_ stated in that file, but this should not be a security risk. First, the file is read/write for the user only, and for no-one else. Second, the file gets deleted as soon as it's no longer needed. If you consider this feature still a security hazard, take a valium and don't use this program. *****************************************************************************/ // here's a couple of defines, no need to change them.. #define VER "1.02" #define YEARS "1993" // the following define controls ftp's `verbatim' mode, set it to "-v" // if you want verbatim, or to "" if you don't #define VERBATIM "-v" list envp; // environment strings string tmpfile, // temp file for ftp use host, // host to transfer from/to dir, // foreign directory file, // local file direction; // "get" or "put" file? void inittmp () // purpose: initialize temp { // file if (exists (tmpfile)) // remove any old version exec ("rm", tmpfile); // if it exists exec ("touch", tmpfile); // make empty file exec ("chmod", "600", tmpfile); // make it r/w only for user } void process () // purpose: do the actual { // ftp transfer string foreignfile; // full name of foreign file inittmp (); // make new temp file if (dir) // if foreign dir specified: foreignfile = change_path (file, dir); // use that else if (get_path (file)) // if file spec has its own foreignfile = file; // directory: keep it else // otherwise: use current foreignfile = change_path (file, // directory as dest dir chdir (".")); string user; string password; if (list xuser = getenv ("FTPUSER") ) // get username from envp user = xuser[1]; else { // or prompt for it printf ("User name: "); user = gets (); } if (list xpassword = getenv ("FTPASS") ) // get passwd from envp password = xpassword[1]; else { // or prompt for it printf ("Password : "); password = gets (); } fprintf (tmpfile, // write ftp login procedure "open ", host, "\n", // to tmpfile, followed "user ", user, " ", password, "\n", // by transfer commands "binary\n", direction, " ", file, " ", foreignfile, "\n", "quit\n"); exec (P_NOCHECK, "ftp", VERBATIM, // do the ftp transfer "-n -i", "< ", tmpfile); exec (P_NOCHECK, "rm", tmpfile); // remove temp file } void usage () // purpose: print usage info { // and die printf ("\n" "ICCE Ftp-based File Transfer Shell V", VER, "\n" "Copyright (c) ICCE ", YEARS, ". All rights reserved.\n" "\n" "Usage: ftpxfer -p|-g host file [directory]\n" "where:\n" " -p : selects putting of file\n" " -g : selects getting of file\n" " host : host to put/get from/to\n" " file : file to transfer\n" " directory : optional directory at foreign host, if " "not given:\n" " directory in file argument is used, if not " "present:\n" " current directory is used for destination\n" "Ftpxfer will use the environment variables FTPUSER and FTPASS " "when available,\n" "or will prompt for the user and password.\n" "\n"); exit (1); } void main (int argc, list argv, list evp) // main function { envp = evp; // store environment echo (OFF); // no re-echoing of commands tmpfile = "/tmp/ftpxfer." // make temporary filename + (string) getpid (); if (element (1, argv) == "-p") // first argument: must direction = "put"; // be -p or -g else if (element (1, argv) == "-g") direction = "get"; else usage (); if (! (host = element (2, argv)) ) // second argument: must be usage (); // foreign host if (! (file = element (3, argv)) ) // third argument: must be usage (); // file to transfer if (direction == "put" && ! exists (file)) // if putting: file must { // exist printf ("File to put does not exist.\n"); exit (1); } dir = element (4, argv); // fourth element: may be // foreign directory process (); // hit it! exit (0); // exitstatus: success } icmake-9.02.06/examples/r0000755000175000017500000000633513176557635014143 0ustar frankfrank#!/usr/bin/icmake -t. /* This simple icmake script starts a given command in the current directory, and then recursively in all subdirectories. For the installation: see the sample script "tolower" (or, "tolower.im"). */ #define VER "1.04" int haswildcard (string s) // does s have wildcards { // in it? if (strfind(s, "?") > -1 || // if ? or * occurs: strfind(s, "*") > -1 // yes -- it has wildcards ) return (1); return (0); // otherwise, none } string makecmd (list cmd) // make one long cmd by { // expanding list elements string ret; // returned cmd int i, // outer/inner loop j, // counters expanded; // flag: expanded stuff? list aux; // expanded inner list expanded = listlen (cmd) <= 1; // expansion must occur when // arguments are in cmd ret = element (0, cmd); // add program name itself for (i = 1; i < listlen (cmd); i++) // for all other elements: if (aux = makelist (element (i, cmd))) // expand element, and add { expanded = 1; // argument expanded for (j = 0; j < listlen (aux); j++) // add expansion ret += " " + element (j, aux); } else if (! haswildcard (element (i, // when no expansion: add cmd))) // only if no wildcards in it ret += " " + element (i, cmd); if (expanded) // when args expanded: return (ret); // return the string return (""); // else, it's a non-valid cmd } void process (list cmd) { list dirs; // list of subdirs int i; // counter for subdirs or string // command name list cwd, // stored current working dir sys; // expanded command to run cwd = chdir ("."); // get cwd if (sys = makecmd (cmd)) // make cmd { printf ("==== r: directory ", cwd, // print this dir " ====\n"); system (P_NOCHECK, sys); // run the cmd } if (dirs = makelist (O_SUBDIR, "*")) // get list of subdirs { for (i = 0; i < listlen (dirs); i++) // for each one: { chdir (element (i, dirs)); // go there process (cmd); // recursively run cmd chdir (cwd); // and.. back again } } } void main (int argc, list argv) { echo (0); // suppress re-echoing if (argc == 1) // usage info if no { // cmdline arguments printf ("ICCE Recursive Command-expander Version ", VER, "\n" "Copyright (c) ICCE 1993,1994. All rights reserved.\n" "\n" "Usage: r program arguments\n" "Will run \"program arguments\" in this directory and" " recursively in the\n" "subdirectories.\n" "\n"); exit (1); } argv -= (list) element (0, argv); // remove makefile name process (argv); // and.. start at current // dir exit (0); // done. } icmake-9.02.06/examples/killprog0000755000175000017500000000247213176557635015523 0ustar frankfrank#!/usr/bin/icmake -qi /* Sample Icmake script. Kills programs; you can type 'killprog progname' instead of having to look up the program PID using 'ps' and then typing 'kill -1 '. For the installation: see the notes in the script file 'tolower'. */ #define VER "1.00" #define TMPFILE "/tmp/killprog.out" int kill (string prog) { int nkilled; list readstat; list psline; system ("ps -al > " + TMPFILE); while (readstat = fgets (TMPFILE, readstat)) { psline = strtok (element (0, readstat), " \n\t"); if (element (12, psline) == prog) { exec (P_NOCHECK, "kill", "-1", element (2, psline)); exec (P_NOCHECK, "kill", "-9", element (2, psline)); nkilled++; } } system ("rm " + TMPFILE); return (nkilled); } void main (int argc, list argv) { echo (0); if (argc != 2) { printf ("\n" "ICCE Program Slayer V", VER, "\n" "Copyright (c) ICCE, 1993. All rights reserved.\n" "\n" "Usage: killprog prog\n" "Will send a 'kill -1' signal to all programs matching " "'prog', followed\n" "by a 'kill -9'.\n" "\n"); exit (1); } printf ("Processes slayed: ", kill (element (1, argv)), "\n"); exit (0); } icmake-9.02.06/examples/am0000755000175000017500000001500513176557635014271 0ustar frankfrank#! /usr/bin/icmake -t. // This script implements a non-destructive rm (am: attic move) #define YEAR "1994--2016" #define VERSION "1.14.01" #define ATTIC_DIR "/.attic" // append after $HOME #define ATTIC_ZIP "attic.zip" // the zip-name int flags_done, extract, viewmode, debug; string home, attic, cwd, progname, recurs, forced, unzipflag; void kill(string s) { printf(s, "\n\n"); exit(1); } void preamble(list argv, list envp) { int index; cwd = chdir("."); // get cwd for (index = 0; home = element(index, envp); index += 2) { if (home == "HOME") // HOME found { // get it home = element(index + 1, envp); break; // and done } } if (!home) kill("$HOME not found"); progname = change_ext(element(0, argv), ""); attic = home + ATTIC_DIR; // set $HOME/.attic, change to } void check_attic() { if (!exists(attic)) // attic should exist { printf(attic, " does not exist. Create it [y/n] ? "); if (getch() != "y") // not a "y" ? kill("ok."); system("mkdir " + attic); // make the attic subdir exec("chmod", 700, attic); // private use } // else attic must be dir else if (!((int)element(0, stat(attic)) & S_IFDIR)) kill("'" + attic + "' is not a directory"); attic += "/" + ATTIC_ZIP; // append the zip-name chdir("/"); // go to the root } void set_flags(string arg) { int index; string flag; // process all arguments for (index = 1; flag = element(index, arg); index++) { if (flag == "r") // process encountered options recurs = "-r"; else if (flag == "d") debug++; else if (flag == "f") forced = "-f"; else if (flag == "x") extract++; else if (flag == "v") { extract++; viewmode++; unzipflag = "-l "; } else kill("Unrecognized flag '-" + flag + "': " + progname + "aborted"); } if (extract && unzipflag == "") unzipflag = "-u "; // use proper unzip flag } list options(int argc, list argv) { int index; list ret; string arg; for (index = 0; index < argc; index++) { arg = element(index, argv); // get next argument if (element(0, arg) == "-") // first element is a - ? set_flags(arg); // then set flags else ret += (list)arg; // or add to list to return } return (ret); // returned list } void usage() { printf ( "\n" "ICCE AM (Attic Move) non-destructive remove. Version " VERSION "\n" "Copyright (c) ICCE " YEAR ". All Rights Reserved\n" "\n" "AM by Frank B. Brokken\n" "\n" "Usage: ", progname, " [options] file(s)\n" "Where:\n" " options:\n" " -d: Debug mode: no execution but display of commands\n" " -f: Forced processing of indicated files\n" " -r: Recursive removal of directory contents\n" " -v: View current contents of the attic\n" " -x: Extract files from the attic to their original place\n" " (i.e., if you are permitted to do so...\n" "\n" " file(s): names of files and directories to move to/from the attic\n" "\n" " ", home, ATTIC_DIR, "/", ATTIC_ZIP, " is used to store the files.\n" "\n" ); exit (1); } string prefix_path(string file) { string el, ret; int index; if (element(0, file) != "/") // if file isn't an absolute path file = cwd + file; // then make an absolute path for (index = 1; el = element(index, file); index++) ret += el; // remove first char from abs path return (ret); // return modified string } void retrieve(string file) { string cmd; cmd = "unzip " // update only + unzipflag + attic; if (!viewmode) cmd += " " + prefix_path(file); // and the file (+ path prefix) if (debug) printf("( cd /; ", cmd, " )\n"); // debug: show command else system(cmd); // else exec cmd } void remove(string file) { string cmd; cmd = "zip -my " // remove, remove links as links + forced // maybe forced + " " + recurs // maybe recursive + " " + attic // target zip + " " + prefix_path(file); // and the file (+ path prefix) if (debug) printf("( cd /; ", cmd, " )\n"); // debug: show command else system(cmd); // else exec cmd } void one_file(string file) { if (extract) // either retrieve or remove retrieve(file); // the file else remove(file); } void process(int argc, list argv) { int index; for (index = 1; index < argc; index++) one_file(element(index, argv)); // process one file } int main(int argc, list argv, list envp) { echo (OFF); preamble(argv, envp); // set progname and attic dir. argv = options(argc, argv); // get the options argc = listlen(argv); // determine remaining arguments if (argc == 1 && !viewmode) // none left and no viewmode ? usage(); // give usage and exit 1 check_attic(); // check accessability of attic if (viewmode) // view contents retrieve(""); else // or process(argc, argv); // process remaining arguments return (0); // done } icmake-9.02.06/examples/tolower0000755000175000017500000000421613176557635015371 0ustar frankfrank#!/usr/bin/icmake -qi /* tolower: Icmake script to rename files to lower case. Use as follows. (1) Place this file in a given directory, e.g., $HOME/im. (2) To rename all *.C in a directory to lowercase, try this (assuming that the tcsh is used) icmake -q ~/im/tolower -- *.C (3) Alternatively, try the following tcsh alias (e.g., in your .tcshrc): alias tolower 'icmake -q ~/im/tolower -- \!*' (the quotes are needed here.) then do: tolower *.C (4) Or another: make a shell script 'tolower' in your $HOME/bin directory, containing: #!/bin/sh icmake -q $HOME/im/tolower -- $* Make the shell script executable, with "chmod +x tolower". (5) Yet another method, which is preferred, is the following: You can use this script as a literal executable, by renaming it to an extension-less file in your local bin directory: mv ~/bin/tolower Then, make it executable: chmod +x ~/bin/tolower Finally, add the following string as the first line to this file: #!/usr/local/bin/icmake -qi This line may actually be at the top of this file, check there. This will cause the command "tolower" to start Icmake, with "-qi tolower" as arguments. Make sure that the /usr/local/bin/icmake part of the text points to your icmake program; e.g., if you have icmake in /usr/bin, then that part should be /usr/bin/icmake. */ #define VERSION "1.01" void process (string file) { string lower; lower = strlwr (file); if (lower != file) if (exec (P_NOCHECK, "mv", file, lower)) printf ("tolower: can't rename ", file, " to ", lower, "\n"); } void main (int argc, list argv) { int i; echo (0); if (argc < 2) { printf ("\n" "ICCE Filecase Converter Version ", VERSION, "\n" "Copyright (c) ICCE 1993. All rights reserved.\n" "\n" "Usage: tolower file(s)\n" "Where: file(s) are the filenames to be renamed to their " "lower case names\n" "\n" ); exit (1); } for (i = 1; i < listlen (argv); i++) process (element (i, argv)); exit (0); } icmake-9.02.06/examples/bup0000755000175000017500000000401113176557635014455 0ustar frankfrank#!/usr/bin/icmake -qi #define ETCDIR "/usr/local/etc" #define VER "1.00" list volumes; // backup volumes void init () // definition of backup volumes { // always: dirs, descrip, etc volumes += (list) "dummy_1" + // bup 0: dummy (list) "dummy_2" + (list) "/" + // bup 1: whole disk (list) "whole UNIX disk" + (list) "/home/karel/dos" + // bup 2: DOS disk (list) "DOS partition" + (list) "/usr/local/bin /conf" + //bup 3: local stuff (list) "local UNIX stuff" + (list) "/home/karel" + // bup 4: user Karel (list) "user Karel, except for DOS" ; } void usage () { int i; printf ("\n" "ICCE Backup Runner V", VER, "\n" "Copyright (c) ICCE 1993. All rights reserved.\n" "\n" "Bup by Karel Kubat.\n" "\n" "Usage: bup volume-number\n" "Where:\n" " volume-number: number of volume to show/run\n" "\n" "Volumes may be:\n"); for (i = 2; i < listlen (volumes); i += 2) printf (i / 2, ": ", element (i + 1, volumes), " (", element (i, volumes), ")\n"); printf ("\n" "The actual backup is perfomed by the Icmake program `backup'.\n" "If the file ", ETCDIR, "/bup..exclude exists,\n" "then the files listed in this file are excluded from the backup.\n" "\n"); exit (1); } void main (int argc, list argv) // start of program { string excludefile, volstring; int volnum, showsize; init (); volstring = element (1, argv); volnum = (int) volstring * 2; if (volnum < 2 || volnum >= listlen (volumes)) usage (); excludefile = ETCDIR + "/" + "bup." + volstring + ".exclude"; if (exists (excludefile)) exec ("backup", "-v", "store", element (volnum, volumes), "--exclude-from", excludefile); else exec ("backup", "-v", "store", element (volnum, volumes)); exit (0); } icmake-9.02.06/examples/keep0000755000175000017500000000542113176557635014621 0ustar frankfrank#!/bin/sh ########################################################################### # Shell script to remove all but the arguments on the commandline, # assuming that you're removing stuff from the current dir. VER=1.03 PROG=`basename $0` # print info and die usage () { cat << ENDUSAGE ICCE Directory Cleaner $VER Copyright (c) K. Kubat (karel@icce.rug.nl) / ICCE 1995. All rights reserved. Another MegaHard Production! Usage: keep [-t] [-v] [-rf] file(s) where: -t : (optional) flag, tryout mode -- must be first argument -v : (optional) flag, increases verbosity -r : (optional) flag, specifying recursive removal of files -f : (optional) flag, specifying forced removal of files file(s) : files to keep, others are removed the files must be in the current directory ENDUSAGE exit 1 } # print error msg and die error () { echo $PROG: $* exit 1 } # verbose message chat () { if [ "$VERBOSE" != "" ] ; then echo keep: $@ fi } ############################################################################ # main starts here # assume options are off RECURSIVE="" FORCED="" TRYOUT=no VERBOSE="" # parse flags moreargs=yes while [ $moreargs = yes ] ; do case $1 in -t ) TRYOUT=yes chat "tryout mode" shift ;; -rf ) RECURSIVE=-r FORCED=-f chat "recursive and forced removal" shift ;; -fr ) RECURSIVE=-r FORCED=-f chat "recursive and forced removal" shift ;; -r ) RECURSIVE=-r chat "recursive removal" shift ;; -f ) FORCED=-f chat "forced removal" shift ;; -v ) VERBOSE=yes shift ;; -* ) error no such flag $1 defined, -r -f -fr -rf -v supported only ;; * ) moreargs=no ;; esac done # any arguments? if [ "$1" = "" ] ; then usage fi # build list of files] for f in $* ; do FILES=`echo $FILES $f | sed 's/\///'` done chat "all files or directories to keep: $FILES" # check that all files are real ones for f in $FILES ; do if [ ! -f $f -a ! -d $f ] ; then error specified file or directory $f not found, cannot keep it fi done # get a listing of cur dir LST=`ls -1` # if not recursive removal: keep only true files in the list if [ "$RECURSIVE" != "-r" ] ; then for f in $LST ; do if [ -f $f ] ; then NEWLIST=`echo $NEWLIST $f` fi done LST=$NEWLIST fi for f in $FILES ; do LST=`echo $LST | tr ' ' '\n' | grep -v "^$f$"` done chat "list of files to remove: $LST" if [ "$LST" = "" ] ; then error "no files to remove" fi if [ "$TRYOUT" = "yes" ] ; then echo 'Files that would be removed:' echo "$LST" else rm $RECURSIVE $FORCED `echo "$LST"` \ || error 'problem while removing files' fi exit 0 icmake-9.02.06/examples/nesteddirectives0000755000175000017500000000106013176557635017234 0ustar frankfrank#!/usr/bin/icmake -t. /* This simple icmake script illustrates the use of nested directives */ #ifdef HELLO this is not compiled #ifdef ALSO_NOT this is also not compiled #else but this isn't compiled either, since we're in the not-defined HELLO section #endif #define NESTED nested is not defined #include file is not included #else void fun() { printf("The function fun() is defined\n"); } #endif void main (int argc, list argv) { fun(); exit(0); } icmake-9.02.06/examples/initialization0000755000175000017500000000026413176557635016724 0ustar frankfrank#!/usr/bin/icmake -t. int main() { int one; // = 5; string a, b; a = "initialization"; b = "initialization"; if (a older b) printf(one, "\n"); } icmake-9.02.06/examples/ds0000755000175000017500000000732513176557635014310 0ustar frankfrank#!/usr/bin/icmake -t. #define VERSION "1.06.01" #define YEAR "1994--2016" int debug; string progname; string xdev; void kill(string s) { printf(s, "\n\n"); exit(1); } string backslash_wild(string spec) { string s; string ret; for (int index = 0; s = element(index, spec); index++) { if (s == "*" || s == "?") // wildcard specifiers ? ret += "\\"; // protect the wildcard spec. ret += s; } return ret; // return the protected string } void preamble(list argv) { progname = get_base(element(0, argv)); // determine progname without .bim xdev = "-xdev"; // no X-device find echo(OFF); // no display of the exec-ed cmnd } void option(string arg) { string optchar; // process all option characters for (int index = 1; optchar = arg[index]; ++index) { if (optchar == "x") // X-dev ok ? xdev == ""; // set appropriate flag else if (optchar == "d") // debug request debug++; // set flag else // kill DS if optchar not found kill("Unrecognized option: '-" + optchar); } } list options(int argc, list argv) { list new; for (int index = 0; index != argc; ++index) // all cmd line arguments { string arg = element(index, argv); // get next element if (element(0, arg) == "-") // found an option ? option(arg); // then process it else new += (list)arg; // else add to the returnlist } return new; // return argv-list without options } void usage() { printf ( "\n" "DS (Disk Search). Version " VERSION "\n" "Copyright (c) GPL " YEAR ". All Rights Reserved\n" "\n" "DS by Frank B. Brokken\n" "\n" "Usage: ", progname, " [options] [dir-spec] file\n" "Where:\n" " options:\n" " -d: Display rather than execute the search command\n" " -x: Allow cross-device searches\n" " dir-spec: specification of the directory where the search is to\n" " be started. By default: / (the root).\n" " file: name of file to search.\n" "\n" "For the 'file' argument quoted wildcards (e.g., ds '*.local') are ok.\n" "\n" ); exit(0); } void process(int argc, list argv) { string startdir = argc == 2 ? // a file given as argument "/" // start at the root : argv[1]; // otherwise start at specified dir // protect wildcards in the // filespecification with \-char string filespec = backslash_wild(element(argc - 1, argv)); string cmd = "find " + startdir + " " + xdev + " -name " + filespec + " 2>/dev/null"; if (!debug) system(P_NOCHECK, cmd); else printf(cmd, "\n"); } void main(int argc, list argv) { preamble(argv); // preamble: determine progname etc. argv = options(argc, argv); // process options argc = listlen(argv); if (argc == 1) // no arguments ? usage(); // give help process(argc, argv); // else process arguments } icmake-9.02.06/examples/idir0000755000175000017500000000343113176557635014623 0ustar frankfrank#!/usr/bin/icmake -qi /* Example of the Icmake 'stat()' function. This simple makefile prints something of a directory listing. For installation: see the sample file 'tolower'. */ int stringlength (string s) { int len; len = 0; while (element (len, s)) len++; return (len); } void showatt (string file, list statbuf) { int i, att; string size; printf (" "); att = (int) element (0, statbuf); if (att & S_IFDIR) printf ("d"); else printf ("-"); if (att & S_IFCHR) printf ("c"); else printf ("-"); if (att & S_IFREG) printf ("f"); else printf ("-"); if (att & S_IREAD) printf ("r"); else printf ("-"); if (att & S_IWRITE) printf ("w"); else printf ("-"); if (att & S_IEXEC) printf ("x"); else printf ("-"); size = element (1, statbuf); printf (" " , size, " "); for (i = stringlength (size); i < 10; i++) printf (" "); printf (file, "\n"); } void show (string filemask) { list statbuf, files; string file; int i; printf ("\n", filemask, ": "); if (! (files = makelist (O_ALL, filemask)) ) { printf ("not found\n"); return; } printf ("\n"); for (i = 0; i < listlen (files); i++) { file = element (i, files); if (! (statbuf = stat (P_NOCHECK, file))) printf (" can't stat ", file, "\n"); else showatt (file, statbuf); } } void main (int argc, list argv) { int i; if (argc == 1) show ("*"); else for (i = 1; i < listlen (argv); i++) show (element (i, argv)); exit (0); } icmake-9.02.06/exec/0000755000175000017500000000000013232314230013022 5ustar frankfrankicmake-9.02.06/exec/list/0000755000175000017500000000000013232314230013775 5ustar frankfrankicmake-9.02.06/exec/list/compare.c0000644000175000017500000000160613176557635015623 0ustar frankfrank#include "list.ih" void listCompare(ListVariable *lhs, ListVariable const *rhs) { int ret = 0; unsigned idx; unsigned size = l_size(lhs); if (size != l_size(rhs)) { listDestructor(lhs); intcons_int(lhs, (int)(size - l_size(rhs))); return; } for (idx = 0; idx != size; ++idx) { if ( (ret = strcmp(l_constElement(lhs)[idx], l_constElement(rhs)[idx])) != 0 ) break; } listDestructor(lhs); /* Can't use the return value as-is, since */ /* the non-16 bit return value may have its */ /* lower 16 bits set to zero (as happened */ /* on the powerpc */ intcons_int(lhs, ret < 0 ? -1 : ret > 0 ? 1 : 0); } icmake-9.02.06/exec/list/addcp.c0000644000175000017500000000021613176557635015244 0ustar frankfrank#include "list.ih" void list_add_charPtr(ListVariable *list, char const *txt) { l_incSize(list); l_addText(list, rss_strdup(txt)); } icmake-9.02.06/exec/list/destructor.c0000644000175000017500000000200613176557635016366 0ustar frankfrank/* #define msg A ListVariable has a ExprType type (e_list) TextData *data: a pointer to a allocated TextData, containing nShared: the share-count unsigned size: the number of strings, stored in the list char **element: a pointer to pointers to allocated NTBSs When the share count is 1 and the destructor is called, then size pointers at data->element are freed data->element is freed data is freed. */ /* #define msg */ #include "list.ih" void listDestructor(ListVariable const *var) { unsigned idx; if (var_decShared(var) == 0) { for (idx = l_size(var); idx--; ) /* free the NTBSs */ free(l_element((Variable *)var)[idx]); free(l_element((Variable *)var)); /* free the char ** array */ free(((Variable *)var)->data); /* free the data block */ } } icmake-9.02.06/exec/list/unionlist.c0000644000175000017500000000030613176557635016215 0ustar frankfrank#include "list.ih" void list_unionList(ListVariable *list, ListVariable const *src) { for (unsigned idx = l_size(src); idx--; ) list_unionStr(list, list_at(src, idx)); } icmake-9.02.06/exec/list/add.c0000644000175000017500000000115013176557635014717 0ustar frankfrank /* #define msg */ #include "list.ih" void list_add(ListVariable *dest, ListVariable const *rhs) { unsigned idx; unsigned nRhs = l_size(rhs); if (nRhs) /* something to add */ { ListVariable copy; listcopycons(©, dest); for (idx = 0; idx < nRhs; ++idx) { char const *cp = l_constElement(rhs)[idx]; if (list_contains(©, cp) == -1) list_add_charPtr(©, cp); } if (l_size(©) != l_size(dest)) list_assign(dest, ©); listDestructor(©); } } icmake-9.02.06/exec/list/lremove.c0000644000175000017500000000064613176557635015651 0ustar frankfrank#include "list.ih" unsigned l_remove(ListVariable *list, char const *txt) { unsigned idx = l_size(list); unsigned nRemoved = 0; while (idx--) { char **target = l_element(list) + idx; if (strcmp(txt, *target) == 0) { free(*target); *target = 0; /* set the free ntps pointer to 0 */ ++nRemoved; } } return nRemoved; } icmake-9.02.06/exec/list/laddtxt.c0000644000175000017500000000031613176557635015636 0ustar frankfrank#include "list.ih" void l_addText(ListVariable *list, char *txt) { List *p = l_listPtr(list); p->element = rss_realloc(p->element, p->size * sizeof(char **)); p->element[p->size - 1] = txt; } icmake-9.02.06/exec/list/lnew.c0000644000175000017500000000035613176557635015143 0ustar frankfrank#include "list.ih" TextData *l_new() /* initializes TextData, empty list */ { TextData *ret = rss_realloc(NULL, sizeof(TextData)); memset(ret, 0, sizeof(TextData)); ret->nShared = 1; return ret; } icmake-9.02.06/exec/list/list.ih0000644000175000017500000000160413176557635015324 0ustar frankfrank#include "list.h" #include #include #include "../var/var.h" #include "../virtual/virtual.h" #include "../int/int.h" TextData *l_new(void); void l_incSize(ListVariable *list); void l_addText(ListVariable *list, char *txt); unsigned l_remove(ListVariable *list, char const *txt); void l_cleanup(ListVariable *list, unsigned toRemove); inline List *l_listPtr(Variable *var) { return &var->data->list; } inline uint16_t *l_sizePtr(Variable *var) { return &l_listPtr(var)->size; } inline List const *l_listConstPtr(Variable const *var) { return &var->data->list; } inline uint16_t l_size(Variable const *var) { return l_listConstPtr(var)->size; } inline char **l_element(Variable *var) { return l_listPtr(var)->element; } inline char const **l_constElement(Variable const *var) { return (char const **)l_listConstPtr(var)->element; } icmake-9.02.06/exec/list/sub.c0000644000175000017500000000114713176557635014766 0ustar frankfrank#include "list.ih" void list_sub(ListVariable *dest, ListVariable const *rhs) { unsigned idx; unsigned nRhs = l_size(rhs); unsigned nRemoved = 0; if (nRhs) /* something to add */ { ListVariable copy; listcopycons(©, dest); for (idx = 0; idx != nRhs; ++idx) { char const *cp = l_constElement(rhs)[idx]; nRemoved += l_remove(©, cp); } if (nRemoved) { l_cleanup(©, nRemoved); list_assign(dest, ©); } listDestructor(©); } } icmake-9.02.06/exec/list/contains.c0000644000175000017500000000036513176557635016014 0ustar frankfrank#include "list.ih" int list_contains(ListVariable *lhs, char const *str) { for (int idx = 0, end = *l_sizePtr(lhs); idx != end; ++idx) { if (strcmp(str, l_element(lhs)[idx]) == 0) return idx; } return -1; } icmake-9.02.06/exec/list/lincsize.c0000644000175000017500000000012313176557635016006 0ustar frankfrank#include "list.ih" void l_incSize(ListVariable *list) { ++*l_sizePtr(list); } icmake-9.02.06/exec/list/conscharptrptr.c0000644000175000017500000000030113176557635017240 0ustar frankfrank#include "list.ih" void listcons_charPtrPtr(ListVariable *list, char **args) { list->type = e_list; list->data = l_new(); while (*args) list_add_charPtr(list, *args++); } icmake-9.02.06/exec/list/conssizecharptrptr.c0000644000175000017500000000033013176557635020135 0ustar frankfrank#include "list.ih" void listcons_size_charPtrPtr(ListVariable *list, unsigned argc, char **argv) { list->type = e_list; list->data = l_new(); for (; argc--; ) list_add_charPtr(list, *++argv); } icmake-9.02.06/exec/list/at.c0000644000175000017500000000017213176557635014576 0ustar frankfrank#include "list.ih" char const *list_at(ListVariable const *list, unsigned idx) { return l_constElement(list)[idx]; } icmake-9.02.06/exec/list/sort.c0000644000175000017500000000057313176557635015166 0ustar frankfrank/* This function sorts the list of variable {\em v}. The same variable, after sorting, is returned. */ #include "list.ih" static int compelement(void const *s1, void const *s2) { return strcmp(*(char const * const *)s1, *(char const * const *)s2); } void list_sort(ListVariable *list) { qsort(l_element(list), *l_sizePtr(list), sizeof(char *), compelement); } icmake-9.02.06/exec/list/listcleanup.cc0000644000175000017500000000224013176557635016656 0ustar frankfrank#include #include using namespace std; int main(size_t argc, char **argv) { istringstream in(argv[1]); size_t idx; size_t toRemove = 0; while (in >> idx) { ++toRemove; argv[idx] = 0; in.seekg(1, ios::cur); } for ( char **empty = argv, **end = empty + argc; empty != end; /* walk along all elements */ ++empty ) { if (*empty) /* next element if non-empty */ { cout << "In use: " << *empty << endl; continue; } char **used = empty + 1; /* beyond the empty one: find used */ for (; used != end && *used == 0; ++used) ; /* find the next one in use */ if (used == end) /* at the end */ break; *empty = *used; /* swap `used' and `empty' */ *used = 0; } argc -= toRemove; for (size_t idx = 0; idx < argc; ++idx) cout << idx << ": " << *argv++ << endl; return 0; } icmake-9.02.06/exec/list/copycons.c0000644000175000017500000000026213176557635016027 0ustar frankfrank/* #define msg */ #include "list.ih" void listcopycons(ListVariable *list, ListVariable const *other) { *list = *other; list->type = e_list; var_incShared(list); } icmake-9.02.06/exec/list/list.h0000644000175000017500000000514313176557635015155 0ustar frankfrank#ifndef _INCLUDED_ListH_ #define _INCLUDED_ListH_ #include "../../rss/rss.h" typedef Variable ListVariable; /* all constructors return ptr to a static ListVariable, with its share-count initialized to 1 A ListVariable has a ExprType type (e_list) TextData *data: a pointer to a allocated TextData, containing count: the share-count TextUnion ls.list: the information about the text fields, being: size: the number of strings, stored in the list char **element: a pointer to pointers to allocated NTBSs When the share count is 1 and the destructor is called, then ls.list.size pointers at ls.list.element are freed ls.list.element is freed data is freed. A ListVariable itself is normally reached via a pointer, which is not dynamically allocated and therefore not deleted (at program startup the required number of ListVariables are dynamically allocated, but they are not deallocated by List functions). all constructors return a pointer to a statically allocated data struct. In order to use the returned data it needs to be copied to a locally defined variable */ void listcons(ListVariable *list); void listcons_size_charPtrPtr(ListVariable *list, unsigned argc, char **argv); void listcons_charPtr(ListVariable *list, char const *argv); void listcons_charPtrPtr(ListVariable *list, char **args); void listcopycons(ListVariable *list, ListVariable const *other); void listDestructor(ListVariable const *var); void list_assign(ListVariable *lhs, ListVariable const *rhs); void list_add_charPtr(ListVariable *list, char const *txt); void list_add_grab_charPtr(ListVariable *list, char *txt); void list_add(ListVariable *lhs, ListVariable const *rhs); /* -1 if not found */ int list_contains(ListVariable *lhs, char const *str); /* int list_findListElement(ListVariable *lhs, ListVariable const *rhs); */ void list_unionStr(ListVariable *list, char const *txt); void list_unionList(ListVariable *list, ListVariable const *src); void list_sub(ListVariable *lhs, ListVariable const *rhs); int list_bool(ListVariable const *lhs); unsigned list_size(ListVariable const *list); char const *list_at(ListVariable const *list, unsigned idx); void list_sort(ListVariable *list); #endif icmake-9.02.06/exec/list/size.c0000644000175000017500000000013613176557635015144 0ustar frankfrank#include "list.ih" unsigned list_size(ListVariable const *list) { return l_size(list); } icmake-9.02.06/exec/list/cons.c0000644000175000017500000000015513176557635015135 0ustar frankfrank#include "list.ih" void listcons(ListVariable *list) { list->type = e_list; list->data = l_new(); } icmake-9.02.06/exec/list/frame0000644000175000017500000000010613176557635015040 0ustar frankfrank#include "list.ih" void l_ (ListVariable *list, ) { } icmake-9.02.06/exec/list/conscharptr.c0000644000175000017500000000024713176557635016523 0ustar frankfrank#include "list.ih" void listcons_charPtr(ListVariable *list, char const *arg) { list->type = e_list; list->data = l_new(); list_add_charPtr(list, arg); } icmake-9.02.06/exec/list/lcleanup.c0000644000175000017500000000222413176557635015775 0ustar frankfrank#include "list.ih" void l_cleanup(ListVariable *list, unsigned toRemove) { if (l_size(list) == toRemove) /* remove all ? */ { listDestructor(list); /* then wipe out the list */ listcons(list); /* and return a new, empty one */ return; } { /* walk along all elements */ char **empty = l_element(list); char **end = empty + l_size(list); for ( ; empty != end; ++empty) { char **used; if (*empty) /* next element if non-empty */ continue; used = empty + 1; /* beyond the empty one: find used */ for (; used != end && *used == 0; ++used) ; /* find the next one in use */ if (used == end) /* at the end */ break; *empty = *used; /* swap `used' and `empty' */ *used = 0; } } *l_sizePtr(list) -= toRemove; /* reduce the list's size */ } icmake-9.02.06/exec/list/addswallowcp.c0000644000175000017500000000020113176557635016647 0ustar frankfrank#include "list.ih" void list_add_grab_charPtr(ListVariable *list, char *txt) { l_incSize(list); l_addText(list, txt); } icmake-9.02.06/exec/list/unionstr.c0000644000175000017500000000025413176557635016054 0ustar frankfrank#include "list.ih" void list_unionStr(ListVariable *list, char const *str) { if (list_contains(list, str) == -1) list_add_charPtr(list, str); } icmake-9.02.06/exec/list/assign.c0000644000175000017500000000030013176557635015447 0ustar frankfrank#include "list.ih" void list_assign(ListVariable *lhs, ListVariable const *rhs) { if (lhs != rhs) { destructor(lhs); *lhs = *rhs; var_incShared(lhs); } } icmake-9.02.06/exec/list/bool.c0000644000175000017500000000012713176557635015125 0ustar frankfrank#include "list.ih" int list_bool(ListVariable const *lhs) { return l_size(lhs); } icmake-9.02.06/exec/virtual/0000755000175000017500000000000013232314230014510 5ustar frankfrankicmake-9.02.06/exec/virtual/compare.c0000644000175000017500000000020213176557635016325 0ustar frankfrank#include "virtual.ih" void virtual_compare(Variable *lhs, Variable const *rhs) { p_compare[var_typeValue(rhs)](lhs, rhs); } icmake-9.02.06/exec/virtual/subtract.c0000644000175000017500000000017213176557635016534 0ustar frankfrank#include "virtual.ih" void virtual_sub(Variable *lhs, Variable const *rhs) { p_sub[var_typeValue(rhs)](lhs, rhs); } icmake-9.02.06/exec/virtual/destructor.c0000644000175000017500000000025713176557635017107 0ustar frankfrank#include "virtual.ih" void destructor(Variable const *lhs) { register ExprType type = var_typeValue(lhs); if (type & e_typeMask) p_destructor[type](lhs); } icmake-9.02.06/exec/virtual/add.c0000644000175000017500000000017413176557635015437 0ustar frankfrank#include "virtual.ih" void virtual_add(Variable *lhs, Variable const *rhs) { p_add[var_typeValue(rhs)](lhs, rhs); } icmake-9.02.06/exec/virtual/logical.c0000644000175000017500000000015613176557635016321 0ustar frankfrank#include "virtual.ih" int virtual_bool(Variable const *lhs) { return p_bool[var_typeValue(lhs)](lhs); } icmake-9.02.06/exec/virtual/virtual.ih0000644000175000017500000000316313176557635016554 0ustar frankfrank#include "virtual.h" #include "../var/var.h" #include void intcons(Variable *var); void stringcons(Variable *var); void listcons(Variable *var); void int_assign(Variable *lhs, Variable const *rhs); void string_assign(Variable *lhs, Variable const *rhs); void list_assign(Variable *lhs, Variable const *rhs); void int_add(Variable *lhs, Variable const *rhs); void string_add(Variable *lhs, Variable const *rhs); void list_add(Variable *lhs, Variable const *rhs); void int_sub(Variable *lhs, Variable const *rhs); void stringSub(Variable *lhs, Variable const *rhs); void list_sub(Variable *lhs, Variable const *rhs); /* intCompare(void) is int_sub() */ void stringCompare(Variable *lhs, Variable const *rhs); void listCompare(Variable *lhs, Variable const *rhs); void intDestructor(Variable const *var); void stringDestructor(Variable const *var); void listDestructor(Variable const *var); int int_bool(Variable const *var); int string_bool(Variable const *var); int list_bool(Variable const *var); void intcopycons(Variable *var, Variable const *other); void stringcopycons(Variable *var, Variable const *other); void listcopycons(Variable *var, Variable const *other); extern void (*p_assign[])(Variable *lhs, Variable const *rhs); extern void (*p_add[])(Variable *lhs, Variable const *rhs); extern void (*p_sub[])(Variable *lhs, Variable const *rhs); extern void (*p_compare[])(Variable *lhs, Variable const *rhs); extern void (*p_constructor[])(Variable *var); extern void (*p_copycons[])(Variable *lhs, Variable const *other); extern void (*p_destructor[])(Variable const *var); extern int (*p_bool[])(Variable const *var); icmake-9.02.06/exec/virtual/data.c0000644000175000017500000000156413176557635015624 0ustar frankfrank#include "virtual.ih" void (*p_constructor[3])(Variable *var) = { intcons, stringcons, listcons, }; void (*p_copycons[3])(Variable *var, Variable const *other) = { intcopycons, stringcopycons, listcopycons, }; void (*p_destructor[3])(Variable const *var) = { intDestructor, stringDestructor, listDestructor, }; void (*p_assign[3])(Variable *lhs, Variable const *rhs) = { int_assign, string_assign, list_assign, }; int (*p_bool[3])(Variable const *var) = { int_bool, string_bool, list_bool, }; void (*p_add[3])(Variable *lhs, Variable const *rhs) = { int_add, string_add, list_add, }; void (*p_sub[3])(Variable *lhs, Variable const *rhs) = { int_sub, NULL, list_sub, }; void (*p_compare[3])(Variable *lhs, Variable const *rhs) = { int_sub, stringCompare, listCompare, }; icmake-9.02.06/exec/virtual/copycons.c0000644000175000017500000000020213176557635016534 0ustar frankfrank#include "virtual.ih" void copycons(Variable *var, Variable const *other) { p_copycons[var_typeValue(other)](var, other); } icmake-9.02.06/exec/virtual/virtual.h0000644000175000017500000000212413176557635016377 0ustar frankfrank#ifndef _INCLUDED_VIRTUAL_H_ #define _INCLUDED_VIRTUAL_H_ #include "../../rss/rss.h" /* all constructors return a pointer to a statically allocated data struct. In order to use the returned data it needs to be copied to a locally defined variable. The destructor expects a const *, which is used to allow passing of const and non-const objects. The destructor, as the object ceases to exist, casts away the const. */ void constructor(Variable *var, ExprType type); /* default constructors */ void copycons(Variable *var, Variable const *other); /* increments count */ void destructor(Variable const *var); /* decrements count */ /* assigns, updating count */ void virtual_assign(Variable *lhs, Variable const *rhs); int virtual_bool(Variable const *var); /* var to bool value */ void virtual_add(Variable *lhs, Variable const *rhs); void virtual_sub(Variable *lhs, Variable const *rhs); void virtual_compare(Variable *lhs, Variable const *rhs); #endif icmake-9.02.06/exec/virtual/cons.c0000644000175000017500000000035313176557635015650 0ustar frankfrank#include "virtual.ih" void constructor(Variable *var, ExprType type) { return p_constructor[ type & e_list ? 2 : type & e_str ? 1 : 0 ](var); } icmake-9.02.06/exec/virtual/assign.c0000644000175000017500000000020013176557635016161 0ustar frankfrank#include "virtual.ih" void virtual_assign(Variable *lhs, Variable const *rhs) { p_assign[var_typeValue(rhs)](lhs, rhs); } icmake-9.02.06/exec/usage.c0000644000175000017500000000073113176557635014324 0ustar frankfrank#include "icm-exec.ih" void usage(char const *argv0) { register char const *program = rss_programName(argv0); rss_copyright(program); printf ("This program is run as a child process of icmake.\n" "Usage: %s [-t] bimfile\n" "where: -t - option indicating that 'bimfile' must be\n" " removed on exit.\n" " bimfile - binary makefile to execute.\n\n" , program); exit(0); } icmake-9.02.06/exec/string/0000755000175000017500000000000013232314230014330 5ustar frankfrankicmake-9.02.06/exec/string/compare.c0000644000175000017500000000103113176557635016146 0ustar frankfrank#include "string.ih" void stringCompare(String *lhs, String const *rhs) { int ret = strcmp(string_charp(lhs), string_charp(rhs)); stringDestructor(lhs); /* Can't use the return value as-is, since */ /* the non-16 bit return value may have its */ /* lower 16 bits set to zero (as happened */ /* on the powerpc */ intcons_int(lhs, ret < 0 ? -1 : ret > 0 ? 1 : 0); } icmake-9.02.06/exec/string/destructor.c0000644000175000017500000000026713176557635016730 0ustar frankfrank#define msg #include "string.ih" void stringDestructor(Variable const *var) { if (var_decShared(var) == 0) { free(var->data->str); free(var->data); } } icmake-9.02.06/exec/string/string.h0000644000175000017500000000171613176557635016045 0ustar frankfrank#ifndef _INCLUDED_STRING_H_ #define _INCLUDED_STRING_H_ #include "../../rss/rss.h" typedef Variable String; /* all constructors return a pointer to a statically allocated data struct. In order to use the returned data it needs to be copied to a locally defined variable */ void stringcons(String *str); void stringcons_charPtr(String *str, char const *ntbs); void stringcons_swallowCharPtr(String *str, char *ntbs); void stringcopycons(String *str, String const *var); void stringDestructor(String const *var); void string_assign(String *lhs, String const *rhs); void string_add(String *lhs, String const *rhs); int string_bool(String const *lhs); /* returns 0 if empty */ char const *string_charp(String const *lhs); void string_reduce(String *str, unsigned length); /* reduce length */ void string_trimLeft(String *lhs, String const *str); void string_trimRight(String *lhs, String const *str); #endif icmake-9.02.06/exec/string/add.c0000644000175000017500000000033713176557635015260 0ustar frankfrank#include "string.ih" void string_add(String *lhs, String const *rhs) { char *catstr = rss_strjoin(string_charp(lhs), string_charp(rhs)); destructor(lhs); stringcons_charPtr(lhs, catstr); free(catstr); } icmake-9.02.06/exec/string/consswallowcharptr.c0000644000175000017500000000021013176557635020455 0ustar frankfrank#include "string.ih" void stringcons_swallowCharPtr(String *str, char *ntbs) { str->type = e_str; str->data = s_new(ntbs); } icmake-9.02.06/exec/string/charp.c0000644000175000017500000000013513176557635015621 0ustar frankfrank#include "string.ih" char const *string_charp(String const *lhs) { return s_str(lhs); } icmake-9.02.06/exec/string/reduce.c0000644000175000017500000000021713176557635015774 0ustar frankfrank#include "string.ih" void string_reduce(String *str, unsigned len) { if (len < strlen(str->data->str)) str->data->str[len] = 0; } icmake-9.02.06/exec/string/snew.c0000644000175000017500000000027313176557635015503 0ustar frankfrank /* #define msg */ #include "string.ih" TextData *s_new(char *cp) { TextData *ret = rss_realloc(NULL, sizeof(TextData)); ret->nShared = 1; ret->str = cp; return ret; } icmake-9.02.06/exec/string/trimright.c0000644000175000017500000000030113176557635016530 0ustar frankfrank/* #define msg */ #include "string.ih" void string_trimRight(String *lhs, String const *rhs) { char *trimmed = rss_trimRight(s_str(rhs)); stringcons_swallowCharPtr(lhs, trimmed); } icmake-9.02.06/exec/string/copycons.c0000644000175000017500000000022313176557635016357 0ustar frankfrank#include "string.ih" void stringcopycons(String *str, String const *other) { *str = *other; str->type = e_str; var_incShared(str); } icmake-9.02.06/exec/string/string.ih0000644000175000017500000000044113176557635016210 0ustar frankfrank#include "string.h" #include #include #include #include "../var/var.h" #include "../virtual/virtual.h" #include "../int/int.h" TextData *s_new(char *cp); /* cp must be free-able */ inline char *s_str(String const *arg) { return arg->data->str; } icmake-9.02.06/exec/string/trimleft.c0000644000175000017500000000021613176557635016352 0ustar frankfrank#include "string.ih" void string_trimLeft(String *lhs, String const *rhs) { stringcons_swallowCharPtr(lhs, rss_trimLeft(s_str(rhs))); } icmake-9.02.06/exec/string/cons.c0000644000175000017500000000016713176557635015473 0ustar frankfrank#include "string.ih" void stringcons(String *str) { str->type = e_str; str->data = s_new(rss_strdup("")); } icmake-9.02.06/exec/string/frame0000644000175000017500000000004213176557635015372 0ustar frankfrank#include "string.ih" void s_ { } icmake-9.02.06/exec/string/conscharptr.c0000644000175000017500000000022313176557635017050 0ustar frankfrank#include "string.ih" void stringcons_charPtr(String *str, char const *ntbs) { str->type = e_str; str->data = s_new(rss_strdup(ntbs)); } icmake-9.02.06/exec/string/assign.c0000644000175000017500000000027013176557635016010 0ustar frankfrank#include "string.ih" void string_assign(String *lhs, String const *rhs) { if (lhs != rhs) { destructor(lhs); *lhs = *rhs; var_incShared(lhs); } } icmake-9.02.06/exec/string/bool.c0000644000175000017500000000012513176557635015456 0ustar frankfrank#include "string.ih" int string_bool(String const *lhs) { return *s_str(lhs); } icmake-9.02.06/exec/stack/0000755000175000017500000000000013232314230014127 5ustar frankfrankicmake-9.02.06/exec/stack/popbp.c0000644000175000017500000000027413176557635015447 0ustar frankfrank#include "stack.ih" void stack_popBP() { while (gs_sp - 1 != gs_bp) stack_pop(); gs_bp = int_value(stack_top()); /* restore old gs_bp */ stack_pop(); } icmake-9.02.06/exec/stack/push.c0000644000175000017500000000053713176557635015310 0ustar frankfrank /* #define msg */ #include "stack.ih" #include "../int/int.h" #include "../string/string.h" static unsigned stackSize; void stack_push(Variable const *varEl) { if (gs_sp >= stackSize) { stackSize += 50; gs_stack = rss_realloc(gs_stack, stackSize * sizeof(Variable)); } copycons(gs_stack + gs_sp++, varEl); } icmake-9.02.06/exec/stack/pushbp.c0000644000175000017500000000024713176557635015630 0ustar frankfrank#include "stack.ih" void stack_pushBP() { Variable tmp; intcons_int(&tmp, (int)gs_bp); gs_bp = gs_sp; stack_push(&tmp); intDestructor(&tmp); } icmake-9.02.06/exec/stack/pop.c0000644000175000017500000000024313176557635015121 0ustar frankfrank#include "stack.ih" #include "../int/int.h" #include "../string/string.h" void stack_pop() { s_testUnderflow(); destructor(gs_stack + --gs_sp); } icmake-9.02.06/exec/stack/local.c0000644000175000017500000000016613176557635015421 0ustar frankfrank#include "stack.ih" Variable *stack_local(int index) { return gs_stack + (int)gs_bp + (int16_t)0xc000 - index; } icmake-9.02.06/exec/stack/data.c0000644000175000017500000000011713176557635015234 0ustar frankfrank#include "stack.ih" Variable *gs_stack; unsigned gs_sp; unsigned gs_bp; icmake-9.02.06/exec/stack/stack.h0000644000175000017500000000044713176557635015443 0ustar frankfrank#ifndef _INCLUDED_STACK_H_ #define _INCLUDED_STACK_H_ #include "../../rss/rss.h" void stack_push(Variable const *var); void stack_pushBP(void); void stack_pop(void); void stack_popBP(void); Variable *stack_top(void); Variable *stack_local(int index); #endif icmake-9.02.06/exec/stack/stack.ih0000644000175000017500000000034413176557635015610 0ustar frankfrank#include "stack.h" #include "../aux/aux.h" #include "../var/var.h" #include "../virtual/virtual.h" #include "../int/int.h" void s_testUnderflow(void); extern Variable *gs_stack; extern unsigned gs_sp; extern unsigned gs_bp; icmake-9.02.06/exec/stack/stestunderflow.c0000644000175000017500000000020413176557635017410 0ustar frankfrank#include "stack.ih" void s_testUnderflow() { if (gs_sp == 0) rss_fatal(0, 0, "stack underflow at %s", aux_offset()); } icmake-9.02.06/exec/stack/top.c0000644000175000017500000000014713176557635015130 0ustar frankfrank#include "stack.ih" Variable *stack_top() { s_testUnderflow(); return gs_stack + gs_sp - 1; } icmake-9.02.06/exec/icm_bootstrap0000755000175000017500000000026013176557635015644 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/${LIBDIR}/icm-exec build icm-exec aux var virtual int list string stack builtin opcodefun icmake-9.02.06/exec/icm-exec.ih0000644000175000017500000000045413176557635015072 0ustar frankfrank#include #include #include "../rss/rss.h" #include "aux/aux.h" #include "builtin/builtin.h" #include "int/int.h" #include "list/list.h" #include "opcodefun/opcodefun.h" #include "stack/stack.h" extern char **environ; void usage(char const *argv0); void cleanup(void); icmake-9.02.06/exec/bootstrap0000644000175000017500000000045213176557635015014 0ustar frankfrankecho Creating icm-exec gcc -O2 -g -Wall -DHAVE_GLOB -c *.c mkdir -p tmp/bin NR=0 for x in auks var virtual int list string stack opcodefun builtin do cd $x gcc -O2 -g -Wall -DHAVE_GLOB -c *.c || exit 1 cd .. done gcc -o tmp/bin/icm-exec$1 *.o */*.o ../rss/libicrss.a rm *.o */*.o icmake-9.02.06/exec/cleanup.c0000644000175000017500000000024713176557635014651 0ustar frankfrank/* This function is attached to the `at-exit' list by {\em main()}. */ #include "icm-exec.ih" void cleanup() { aux_unlinkBim(); opcodefun_close(); } icmake-9.02.06/exec/var/0000755000175000017500000000000013232314230013612 5ustar frankfrankicmake-9.02.06/exec/var/shared.c0000644000175000017500000000014013176557635015250 0ustar frankfrank#include "var.ih" uint16_t var_nShared(Variable const *var) { return var->data->nShared; } icmake-9.02.06/exec/var/decshared.c0000644000175000017500000000016213176557635015730 0ustar frankfrank#include "var.ih" uint16_t var_decShared(Variable const *var) { return --((Variable *)var)->data->nShared; } icmake-9.02.06/exec/var/var.h0000644000175000017500000000117013176557635014603 0ustar frankfrank#ifndef _INCLUDED_VariableH_ #define _INCLUDED_VariableH_ #include "../../rss/rss.h" inline ExprType var_type(Variable const *varp) { return varp->type & e_typeMask; } inline int var_typeValue(Variable const *varp) { return varp->type & e_list ? 2 : varp->type & e_str ? 1 : 0; } uint16_t var_nShared(Variable const *var); void var_incShared(Variable *var); /* returns count following the reduction */ /* (ignores the const */ uint16_t var_decShared(Variable const *var); #endif icmake-9.02.06/exec/var/incshared.c0000644000175000017500000000012313176557635015743 0ustar frankfrank#include "var.ih" void var_incShared(Variable *var) { ++var->data->nShared; } icmake-9.02.06/exec/var/var.ih0000644000175000017500000000002113176557635014746 0ustar frankfrank#include "var.h" icmake-9.02.06/exec/icmconf0000644000175000017500000000075313176557635014421 0ustar frankfrank#define USE_ECHO ON #define MAIN "main.c" #define REFRESH #define CLS #define COMPILER "gcc" #define COMPILER_OPTIONS "-Wall -Werror -O2 -fdiagnostics-color=never" #define SOURCES "*.c" #define LINKER_OPTIONS "-s" #define ADD_LIBRARIES "icrss" #define ADD_LIBRARY_PATHS "../../tmp" #define TMP_DIR "tmp" #define LIBRARY "modules" #define OBJ_EXT ".o" #define DEFCOM "program" icmake-9.02.06/exec/int/0000755000175000017500000000000013232314230013614 5ustar frankfrankicmake-9.02.06/exec/int/destructor.c0000644000175000017500000000007613176557635016212 0ustar frankfrank#include "int.h" void intDestructor(Variable const *var) {} icmake-9.02.06/exec/int/add.c0000644000175000017500000000020213176557635014533 0ustar frankfrank#include "int.ih" void int_add(Variable *lhs, Variable const *rhs) { int_assignInt(lhs, int_value(lhs) + int_value(rhs)); } icmake-9.02.06/exec/int/int.ih0000644000175000017500000000011713176557635014760 0ustar frankfrank#include "int.h" #include "../../rss/rss.h" #include "../virtual/virtual.h" icmake-9.02.06/exec/int/assignint.c0000644000175000017500000000014113176557635016004 0ustar frankfrank#include "int.h" void int_assignInt(IntVariable *lhs, int value) { lhs->intValue = value; } icmake-9.02.06/exec/int/sub.c0000644000175000017500000000020213176557635014574 0ustar frankfrank#include "int.ih" void int_sub(Variable *lhs, Variable const *rhs) { int_assignInt(lhs, int_value(lhs) - int_value(rhs)); } icmake-9.02.06/exec/int/int.h0000644000175000017500000000153313176557635014612 0ustar frankfrank#ifndef _INCLUDED_INT_H_ #define _INCLUDED_INT_H_ #include "../../rss/rss.h" typedef Variable IntVariable; /* all constructors return a pointer to a statically allocated data struct. In order to use the returned data it needs to be copied to a locally defined variable */ void intcons(IntVariable *var); void intcons_int(IntVariable *var, int value); void intcopycons(IntVariable *var, IntVariable const *other); void intDestructor(Variable const *lhs); void int_assign(Variable *lhs, Variable const *rhs); void int_add(Variable *lhs, Variable const *rhs); void int_sub(Variable *lhs, Variable const *rhs); /* same as intCompare */ int int_bool(IntVariable const *lhs); void int_assignInt(IntVariable *lhs, int value); int int_value(IntVariable const *lhs); /* return the stored int */ #endif icmake-9.02.06/exec/int/value.c0000644000175000017500000000012613176557635015124 0ustar frankfrank#include "int.h" int int_value(IntVariable const *lhs) { return lhs->intValue; } icmake-9.02.06/exec/int/copycons.c0000644000175000017500000000014613176557635015647 0ustar frankfrank#include "int.h" void intcopycons(IntVariable *var, IntVariable const *other) { *var = *other; } icmake-9.02.06/exec/int/consint.c0000644000175000017500000000022213176557635015462 0ustar frankfrank/*#define msg */ #include "int.ih" void intcons_int(IntVariable *intVar, int value) { intVar->type = e_int; intVar->intValue = value; } icmake-9.02.06/exec/int/cons.c0000644000175000017500000000014313176557635014751 0ustar frankfrank#include "int.h" void intcons(IntVariable *var) { var->type = e_int; var->intValue = 0; } icmake-9.02.06/exec/int/assign.c0000644000175000017500000000016213176557635015274 0ustar frankfrank#include "int.ih" void int_assign(Variable *lhs, Variable const *rhs) { destructor(lhs); *lhs = *rhs; } icmake-9.02.06/exec/int/bool.c0000644000175000017500000000012513176557635014742 0ustar frankfrank#include "int.h" int int_bool(IntVariable const *lhs) { return lhs->intValue; } icmake-9.02.06/exec/build0000755000175000017500000000003113176557635014072 0ustar frankfrank#!/bin/bash icmbuild $1 icmake-9.02.06/exec/aux/0000755000175000017500000000000013232314230013617 5ustar frankfrankicmake-9.02.06/exec/aux/offset.c0000644000175000017500000000013013176557635015274 0ustar frankfrank#include "aux.ih" char const *aux_offset() { return rss_hexString(ga_offset, 4); } icmake-9.02.06/exec/aux/aux.ih0000644000175000017500000000023313176557635014765 0ustar frankfrank#include "aux.h" #include #include #include "../../rss/rss.h" extern char *ga_bimname; extern unsigned ga_offset; icmake-9.02.06/exec/aux/data.c0000644000175000017500000000010513176557635014721 0ustar frankfrank#include "aux.ih" char *ga_bimname; unsigned ga_offset; icmake-9.02.06/exec/aux/set.c0000644000175000017500000000011513176557635014604 0ustar frankfrank#include "aux.ih" void aux_set(unsigned offset) { ga_offset = offset; } icmake-9.02.06/exec/aux/abnormal.c0000644000175000017500000000062513176557635015612 0ustar frankfrank/* This function issues an error with the string {\em ''Abnormal termination.''} as message. The {\em error()} function thereupon raises the {\em error\_occurred} flag. This function is attached to abnormal termination by the {\em signal()} function. */ #include "aux.ih" void aux_abnormal(int sig, int subcode) { rss_fatal(0, 0, "Abnormal termination."); } icmake-9.02.06/exec/aux/frame0000644000175000017500000000003713176557635014665 0ustar frankfrank#include "aux.ih" void a_ { } icmake-9.02.06/exec/aux/unlinkbim.c0000644000175000017500000000013413176557635016002 0ustar frankfrank#include "aux.ih" void aux_unlinkBim() { if (ga_bimname) unlink(ga_bimname); } icmake-9.02.06/exec/aux/aux.h0000644000175000017500000000051113176557635014613 0ustar frankfrank#ifndef INCLUDED_AUX_H_ #define INCLUDED_AUX_H_ #include void aux_abnormal(int sig, int subcode); void aux_cleanup(); char **aux_testRmBim(int *argcp, char **argv); void aux_unlinkBim(void); char const *aux_offset(); /* returns 4 char. hexstring of offset */ void aux_set(unsigned offset); #endif icmake-9.02.06/exec/aux/testrmbim.c0000644000175000017500000000053613176557635016026 0ustar frankfrank#include "aux.ih" char **aux_testRmBim(int *argcPtr, char **argv) { if (strcmp(argv[1], "-t") == 0) /* -t option found */ { argv[1] = argv[0]; /* remove the -t argument */ ++argv; --*argcPtr; ga_bimname = argv[1]; /* define temporary name */ } return argv; } icmake-9.02.06/exec/CLASSES0000644000175000017500000000110713176557635014072 0ustar frankfrank# This file contains the names of all subdirectories containing sources to # compile. Each directory should be specified on a line of its own. Initial # blanks are ok. Compilation is 1-level deep. # If a parser or scanner is used, (see icmconfig's USE_PARSER and USE_SCANNER # defines) then those directories are automatically included (although they # could be included here as well) # Lines starting with # or with // are ignored, as are empty lines. # sources in the current (i.e., this) directory are also compiled. opcodefun builtin stack list string int virtual var aux icmake-9.02.06/exec/builtin/0000755000175000017500000000000013232314230014470 5ustar frankfrankicmake-9.02.06/exec/builtin/ebformatter.c0000644000175000017500000000416013176557635017200 0ustar frankfrank#define msgx #include "builtin.ih" unsigned eb_formatter(void *dest, FormatDest startIdx) /* idx of 1st arg */ { unsigned endIdx = 1 + int_value(stack_top()); /* the idx beyond the idx of the last arg */ msg("last idx = %u", endIdx); int notUsed; char *fmt = eb_getArg(startIdx, ¬Used); /* get the fmt string */ char *end = eb_findPercent(fmt); /* 'end' at 0 or % */ unsigned ret; if (*end == 0) /* no % in the first str */ { ret = eb_noFormatting(dest, startIdx, endIdx); msg("processed from idx %u to idx %u", startIdx, endIdx); free(fmt); return ret; } ret = 1; char *begin = fmt; msg("Got a format string: `%s' startIdx = %u, endIdx = %u", fmt, startIdx,\ endIdx); errno = 0; /* make sure we're not bothered by a previous errno */ while (1) /* process the fmt string */ { (*gb_pDestWrite)(dest, begin, end); /* write begin .. end */ if (*end == 0) /* at end of string */ break; /* then done */ begin = end; /* begin -> % */ /* end -> % */ unsigned idx = eb_getNr(&end); /* idx: the idx of % */ if (errno == 0 && idx > 0 && idx < endIdx) /* if idx OK */ { ++ret; eb_writeArgument(dest, startIdx + idx); /* write arg. st + idx */ } else (*gb_pDestWrite)(dest, begin, end); /* or write the % as-is */ begin = end; /* ready for the next part */ end = eb_findPercent(begin); /* 'end' at 0 or % */ } free(fmt); return ret; } icmake-9.02.06/exec/builtin/ebgetnr.c0000644000175000017500000000027713176557635016321 0ustar frankfrank#include "builtin.ih" unsigned eb_getNr(char **ptr) /* *ptr points at % of % */ { return strtol(*ptr + 1, ptr, 10); /* return the position beyond */ } icmake-9.02.06/exec/builtin/bmakelist.c0000644000175000017500000000440613176557635016644 0ustar frankfrank/* This function converts the last pushed string into a listvariable holding expanded filenames. The {\em reg} register is set to hold the list. The returned list is alphabetically sorted. The stack is organized as follows: 1: without older/younger stack[-1] : op_hlt stack[-2] : filemask value stack[-3] : pattern 2: with older/younger stack[-1] : op_older / op_younger stack[-2] : filemask value stack[-3] : pattern stack[-4] : reference filename */ /* #define msg */ #include "builtin.ih" static int accept(char const *lhs, char const *rhs) { return 1; } void b_makeList() { msg("starting"); int opcode = int_value(stack_top()); // op_hlt/op_younger/op_older char const *name = string_charp(stack_top() - 2); // filemask string listcons(eb_releaseReg()); if (*name) /* if valid name.. */ { char dir[MAX_PATHLEN], /* filename, incl. path */ fname[MAX_PATHLEN], ext[MAX_PATHLEN], newname[MAX_PATHLEN]; msg("name is %s", name); unsigned attrib = int_value(stack_top() - 1); // attribute to match /* find a first name */ char *namefound = rss_findFirst (name, attrib); rss_splitPath(name, dir, fname, ext); char const *refName = opcode == op_hlt ? 0 : string_charp(stack_top() - 3); int (*include)(char const *lhs, char const *rhs) = opcode == op_hlt ? accept : opcode == op_younger ? rss_younger : rss_older; while (namefound) /* as long as that succeeds */ { /* make a new path */ rss_makePath (newname, dir, namefound, ""); if ((*include)(newname, refName)) /// add accepted entries list_add_charPtr(&gb_reg, newname); namefound = rss_findNext(); /* determine new name */ } list_sort(&gb_reg); } msg("ending"); } icmake-9.02.06/exec/builtin/ebupdatefgets.c0000644000175000017500000000071513176557635017512 0ustar frankfrank#include "builtin.ih" void eb_updateFgets(FILE *inf, char *dest) { char const *nl; char *last = dest + strlen(dest) - 1; if (*last != '\n') nl = ""; else { *last = 0; nl = "\n"; } list_add_grab_charPtr(&gb_reg, dest); list_add_charPtr(&gb_reg, nl); list_add_charPtr(&gb_reg, "OK"); char buffer[50]; sprintf (buffer, "%ld", (long)ftell(inf)); list_add_charPtr(&gb_reg, buffer); } icmake-9.02.06/exec/builtin/bchangeextension.c0000644000175000017500000000034613176557635020214 0ustar frankfrank#include "builtin.ih" void b_changeExtension() { char *cp = rss_changeExt(string_charp(stack_top()), string_charp(stack_top() - 1)); stringcons_charPtr(eb_releaseReg(), cp); free(cp); } icmake-9.02.06/exec/builtin/call.c0000644000175000017500000000023513176557635015600 0ustar frankfrank/* #define msg */ #include "builtin.ih" void builtin_call(unsigned funIdx) { msg("called for function 0x%x", funIdx); gb_pBuiltinFun[funIdx](); } icmake-9.02.06/exec/builtin/popreg.c0000644000175000017500000000015413176557635016161 0ustar frankfrank#include "builtin.ih" void builtin_popReg() { virtual_assign(&gb_reg, stack_top()); stack_pop(); } icmake-9.02.06/exec/builtin/bgets.c0000644000175000017500000000074213176557635015774 0ustar frankfrank/* This function reads in a string and returns it in the {\em reg} return register as an {\em e\_str} value. */ #include "builtin.ih" void b_gets() { int last; char *dest = eb_getLine(stdin); stringcons(eb_releaseReg()); if (!dest) return; last = strlen(dest) - 1; /* cut off final \n as per man-page */ if (dest[last] == '\n') dest[last] = 0; stringcons_charPtr(&gb_reg, dest); free(dest); } icmake-9.02.06/exec/builtin/ebtermch.c0000644000175000017500000000165413176557635016464 0ustar frankfrank/* Enter a single char without \n on systems supporting termios. If things fail, fall back to `eb_enterCh()' */ #include #include "builtin.ih" int eb_termCh(void) { struct termios saved; struct termios tattr; int key; if (tcgetattr(STDIN_FILENO, &saved)) { fprintf(stderr, "Single key input failed. Press `Enter' as well\n"); return eb_enterCh(); } tcgetattr(STDIN_FILENO, &tattr); /* can't assign saved to tattr */ tattr.c_lflag &= ~(ICANON | ECHO); tattr.c_cc[VMIN] = 1; tattr.c_cc[VTIME] = 0; if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tattr)) { fprintf(stderr, "Single key input failed. Press `Enter' as well\n"); return eb_enterCh(); } key = getchar(); if (key == '\n') putchar('\n'); else printf("%c\n", key); tcsetattr(STDIN_FILENO, TCSANOW, &saved); return key; } icmake-9.02.06/exec/builtin/bcmdhead.c0000644000175000017500000000102213176557635016407 0ustar frankfrank/* \funcref{fun\_cmd\_head}{void fun\_cmd\_head ()} {} {} {eb_setString()} {fun\_arg\_tail(), fun\_arg\_head(), fun\_cmd\_tail()} {funcmdte.c} { This function is called when an {\em op\_cmd\_head} opcode is read in the binary makefile. The {\em gb_cmdHead} variable is set to a duplicate of the string in the last pushed variable. The last pushed variable is then discarded. } */ #include "builtin.ih" void b_cmdHead() { gb_cmdHead = eb_setString(gb_cmdHead); } icmake-9.02.06/exec/builtin/bresize.c0000644000175000017500000000114013176557635016324 0ustar frankfrank/* */ #include "builtin.ih" void b_resize() { char const *str = string_charp(stack_top()); unsigned oldLen = strlen(str); unsigned newLen = int_value(stack_top() - 1); if ((int)newLen < 0) newLen = 0; char *newstr = rss_realloc(NULL, newLen + 1); /* room for new chars */ memset(newstr, ' ', newLen); /* initially blanks */ newstr[newLen] = 0; /* cp requested # chars */ memcpy(newstr, str, oldLen < newLen ? oldLen : newLen); stringcons_swallowCharPtr(eb_releaseReg(), newstr); } icmake-9.02.06/exec/builtin/bexec.c0000644000175000017500000000462713176557635015764 0ustar frankfrank/* This function is called when an {\em op\_builtin_exec} opcode is encountered in the binary makefile. At this point, the stack is expected to hold the following information: \begin{itemize} \item The last pushed value ({\em stack[sp]} holds the number of arguments to the original {\em b_exec()} statement. \item The value pushed before that ({\em stack [sp-1]}) holds the b_execution mode: 0 = checked, !0 = not checked. When the b_execution mode is checked, any exit status which is non-zero leads to an error. \item The value pushed before that ({\em stack [sp-2]}) holds the command to b_execute; a string. \item Other pushed values are the remaining arguments. \end{itemize} {\em fun\_builtin_exec()} initializes an array of command strings and retrieves arguments. When the length of the command list is about to exceed {\em MAX_CMDLEN} (see {\em icm.h}), the command is flushed by calling {\em eb_exeCmd()}. */ #include "builtin.ih" static char **initcmd(char **cmd) { register int i; if (cmd) { for (i = 0; cmd[i]; ++i) free(cmd[i]); free(cmd); } cmd = rss_realloc(NULL, 3 * sizeof(char *)); cmd[0] = rss_strdup(string_charp(stack_top() - 2)); if (strlen(gb_cmdHead) == 0) cmd[1] = NULL; else { cmd[1] = rss_strdup(gb_cmdHead); cmd[2] = NULL; } return cmd; } void b_exec () { int getnewarg = 1; char *nextarg = NULL; char **cmd = initcmd(NULL); unsigned nextarglen; unsigned cmdlen; unsigned i = 3; unsigned nargs = int_value(stack_top()); int mode = int_value(stack_top() - 1); while (i <= nargs) { int newbuiltin_element; if (getnewarg) nextarg = eb_getExecArg(i, &newbuiltin_element); else getnewarg = 1; nextarglen = strlen(nextarg); cmdlen = eb_getCmdLen(cmd); if (cmdlen + nextarglen + strlen(gb_cmdTail) >= MAX_CMDLEN) { cmd = eb_exeCmd (cmd, mode); cmd = initcmd (cmd); getnewarg = 0; } else { cmd = eb_addCmd (cmd, nextarg); i += newbuiltin_element; free(nextarg); } } cmd = eb_exeCmd (cmd, mode); for (i = 0; cmd[i]; ++i) free(cmd[i]); free(cmd); } icmake-9.02.06/exec/builtin/ebfgetsstatus.c0000644000175000017500000000026613176557635017554 0ustar frankfrank#include "builtin.ih" void eb_fgetsStatus(char const *status) { list_add_charPtr(&gb_reg, ""); list_add_charPtr(&gb_reg, ""); list_add_charPtr(&gb_reg, status); } icmake-9.02.06/exec/builtin/bexists.c0000644000175000017500000000052013176557635016343 0ustar frankfrank/* Function {\em fun\_builtin_exists()} checks if a file with the name of the last pushed string b_exists. If so, {\em reg.intValue} is set to 1. Else, the return register indicates 0. */ /*#define msg */ #include "builtin.ih" void b_exists() { intcons_int(eb_releaseReg(), rss_exists(string_charp(stack_top()))); } icmake-9.02.06/exec/builtin/ebstrlower.c0000644000175000017500000000022613176557635017055 0ustar frankfrank#include "builtin.ih" char *eb_strLower (char *s) { register char *cp; for (cp = s; *cp; ++cp) *cp = tolower(*cp); return s; } icmake-9.02.06/exec/builtin/bgetexecarg.c0000644000175000017500000000147113176557635017150 0ustar frankfrank/* This function performs a similar function as {\em eb_getArg()} but prefixes the retrieved argument with the string {\em gb_argHead} and postfixes the argument with the string {\em gb_argTail}. {\bf Note that} the return value always points to allocated memory which should be freed when no longer required. See further {\em eb_getArg()}. */ #include "builtin.ih" char *eb_getExecArg (unsigned n, int *flag) { register char *arg, *start, *ret; arg = eb_getArg(n, flag); if (strlen(gb_argHead)) { start = rss_strjoin(gb_argHead, arg); free(arg); } else start = arg; if (strlen(gb_argTail)) { ret = rss_strjoin(start, gb_argTail); free(start); } else ret = start; return ret; } icmake-9.02.06/exec/builtin/btrim.c0000644000175000017500000000030613176557635016001 0ustar frankfrank#include "builtin.ih" void b_trim() { String str; stringcons(&str); string_trimRight(&str, stack_top()); string_trimLeft(eb_releaseReg(), &str); stringDestructor(&str); } icmake-9.02.06/exec/builtin/bstrformat.c0000644000175000017500000000067313176557635017056 0ustar frankfrank/* Function {\em fun\_builtin_strFormat()} returns a formatted string using "%n" placeholders found in the first arg */ /* #define msg */ #include "builtin.ih" void b_strFormat(void) { char *ptr = rss_strdup(""); /* allocate empty string */ gb_pDestWrite = eb_stringWrite; /* write to a string */ eb_formatter(&ptr, TO_STRING); stringcons_charPtr(eb_releaseReg(), ptr); free(ptr); } icmake-9.02.06/exec/builtin/bstrlength.c0000644000175000017500000000030313176557635017035 0ustar frankfrank/* Function {\em fun\_strlen()} returns the length of a string */ #include "builtin.ih" void b_strLength() { intcons_int(eb_releaseReg(), (int)strlen(string_charp(stack_top()))); } icmake-9.02.06/exec/builtin/bputenv.c0000644000175000017500000000106613176557635016353 0ustar frankfrank/* This function expects a string to enter in the environment on top of the stack. Return register {\em reg} is set to type {\em e\_int}. The value of the return register is set to 0 if the setting was added to the environment. */ #include "builtin.ih" #ifdef M_UNIX /* sco unix 3.2.4.0 conflicting header files ... */ extern int putenv(const char *); #endif void b_putEnv() { intcons_int( eb_releaseReg(), putenv( rss_strdup( string_charp(stack_top()) ) ) ); } icmake-9.02.06/exec/builtin/bgetenv.c0000644000175000017500000000054413176557635016322 0ustar frankfrank/* */ #include "builtin.ih" void b_getEnv() { char *env = getenv(string_charp(stack_top())); listcons(eb_releaseReg()); if (!env) { list_add_charPtr(&gb_reg, "0"); list_add_charPtr(&gb_reg, ""); } else { list_add_charPtr(&gb_reg, "1"); list_add_charPtr(&gb_reg, env); } } icmake-9.02.06/exec/builtin/becho.c0000644000175000017500000000063213176557635015746 0ustar frankfrank/* \funcref{fun\_builtin_echo}{void fun\_builtin_echo ()} {} {} {} {} {funbuiltin_echo.c} { This function is b_executed when an {\em op\_builtin_echo} opcode is encountered. The global variable {\em b_echo} is set to the {\em intValue} value of the last pushed variable. } */ #include "builtin.ih" void b_echo() { gb_echo = int_value(stack_top()); } icmake-9.02.06/exec/builtin/ebgetarg.c0000644000175000017500000000366113176557635016453 0ustar frankfrank/* Function {\em eb_getArg()} can be called to retrieve arguments from the stack (e.g., the arguments of a {\em print()} statement) in string format. Parameter {\em n} specifies the argument to retrieve: 0 is the last pushed argument, 1 is the argument pushed before that, etc.. Parameter {\em increment} tells the caller whether to start retrieving a next argument or not. In the case of a list argument, {\em eb_getArg()} sets this flag to 0 while the list is not yet completely processed. When a list argument is processed or when the retrieved argument is not a list, the flag value is set to 1. The return value points to a string duplicate. The caller should free this memory when it is no longer needed. */ #include "builtin.ih" char *eb_getArg(unsigned idx, int *flag) { char convbuf [50]; register char *ret; Variable *base = stack_top() - idx; *flag = 1; /* assume that done with args */ if (var_type(base) & e_int) /* incase of an int.. */ { gb_listIndex = 0; sprintf (convbuf, "%d", int_value(base)); return (rss_strdup (convbuf)); } if (var_type(base) & e_str) /* incase of a string.. */ { gb_listIndex = 0; return rss_strdup(string_charp(base)); } /* incase of a list: */ if (!list_size(base)) { gb_listIndex = 0; ret = rss_strdup(""); } else { ret = rss_strdup(list_at(base, gb_listIndex)); ++gb_listIndex; if (gb_listIndex < list_size(base)) *flag = 0; /* if more b_elements, not done */ else /* with args.. */ gb_listIndex = 0; /* otherwise: returnflag = 1, */ } /* no next b_elements to get */ return (ret); } icmake-9.02.06/exec/builtin/bpath.c0000644000175000017500000000035613176557635015767 0ustar frankfrank/* The last pushed string is taken as a file name. The path is returned. */ #include "builtin.ih" void b_path() { stringcons_charPtr(eb_releaseReg(), rss_getPath(string_charp(stack_top()))); } icmake-9.02.06/exec/builtin/ebspawnvp.c0000644000175000017500000000144513176557635016676 0ustar frankfrank#include "builtin.ih" int eb_spawnvp(int mode, char const *prog, char const **av) { unsigned length = strlen(prog); /* determine length of required buffer */ char const **begin = av + 1; while (*begin) length += strlen(*begin++); /* add 1 for ASCIIZ + # elements in av */ char *buf = rss_realloc(NULL, length + 1 + begin - av); strcpy(buf, prog); /* copy the program */ while (*++av) /* plus all blank delimited extra args */ { strcat(buf, " "); strcat(buf, *av); } return system(buf); /* run the program */ } #ifdef DEBUG int main () { static char *args[] = { "ls", "*.c", "*.h", NULL }; eb_spawnvp(0, "ls", (char const **) args); } #endif icmake-9.02.06/exec/builtin/ebstringwrite.c0000644000175000017500000000055713176557635017564 0ustar frankfrank#include "builtin.ih" void eb_stringWrite(void *dest, char const *begin, char const *end) { char beyond = *end; /* save the char at end */ *(char *)end = 0; /* end the string to catenate */ *(char **)dest = rss_strcat(*(char **)dest, begin); *(char *)end = beyond; /* restore the char at end */ } icmake-9.02.06/exec/builtin/ebfilewrite.c0000644000175000017500000000021713176557635017166 0ustar frankfrank#include "builtin.ih" void eb_fileWrite(void *dest, char const *begin, char const *end) { fwrite(begin, 1, end - begin, (FILE *)dest); } icmake-9.02.06/exec/builtin/bsystem.c0000644000175000017500000000137613176557635016362 0ustar frankfrank/* This function expects a system string as last pushed {\em e\_str} value. The string is b_executed through a {\em system()} call (if this fails, an error is issued). */ #include "builtin.ih" void b_system() { int mode = int_value(stack_top()); /* get mode arg */ char const *cmd = string_charp(stack_top() - 1); /* get cmd string */ if (gb_echo) /* re-builtin_echo if requested */ puts(cmd); fflush(stdout); int ret = system(cmd); /* do system call */ if (ret && rss_checkMode(mode)) /* terminate upon failure? */ rss_fatal(0, 0, "system - failure of system call (status %d)", ret); intcons_int(eb_releaseReg(), ret); } icmake-9.02.06/exec/builtin/blistlen.c0000644000175000017500000000056613176557635016510 0ustar frankfrank/* This function determines the size of the last pushed list variable and sets {\em reg.intValue} to this size. */ #include "builtin.ih" void b_listlen() { Variable *base = stack_top(); intcons_int( eb_releaseReg(), var_type(base) == e_str ? (int)strlen(string_charp(base)) : (int)list_size(base) ); } icmake-9.02.06/exec/builtin/ebaddcmd.c0000644000175000017500000000141113176557635016405 0ustar frankfrank/* Function {\em eb_addCmd()} expects a pointer to an array of {\em char $*$}'s as first argument. This pointer may be {\em NULL}. The {\em argv}-like array is expanded to hold a reference to {\em string}. The reallocated array {\em cmd} is returned. The last field in the array is {\em NULL} to indicate the ending of the list. {\bf Note that} a reference to {\em string} itself is not added to the list: a duplicate is made. */ #include "builtin.ih" char **eb_addCmd(char **cmd, char *string) { register int size = 0; if (cmd) for (size = 0; cmd[size]; ++size) ; cmd = rss_realloc(cmd, (size + 2) * sizeof(char *)); cmd [size] = rss_strdup(string); cmd [size + 1] = NULL; return cmd; } icmake-9.02.06/exec/builtin/blistunion.c0000644000175000017500000000057013176557635017055 0ustar frankfrank#include "builtin.ih" /* Returns the set-union of the lhs list and the rhs list or string */ void b_listUnion() { Variable *source = stack_top() - 1; listcons(eb_releaseReg()); list_unionList(&gb_reg, stack_top()); if (var_type(source) == e_str) list_unionStr(&gb_reg, string_charp(source)); else list_unionList(&gb_reg, source); } icmake-9.02.06/exec/builtin/bbacktick.c0000644000175000017500000000200613176557635016600 0ustar frankfrank/* This function expects a string as last pushed {\em e\_str} value. The string is b_executed through a {\em system()} call (if this fails, an error is issued) and the standard output produced by the call is returned as a list, one b_element for each line. If the list contains zero b_elements the command has failed. A command not producing any output will at least result in a list having one (empty) string. */ #include "builtin.ih" void b_backtick() { char const *cmd = string_charp(stack_top()); /* get cmd string */ FILE *fpipe = popen(cmd, "r"); /* and open a pipe */ if (gb_echo) /* re-echo if requested */ printf("`%s`\n", cmd); listcons(eb_releaseReg()); if (!fpipe) /* command failed */ return; /* then empty list return */ char *line; while ((line = eb_getLine(fpipe))) list_add_grab_charPtr(&gb_reg, line); pclose(fpipe); } icmake-9.02.06/exec/builtin/bchdir.c0000644000175000017500000000341013176557635016116 0ustar frankfrank/* This function expects a string to {\em b_chDir} to as second-but-last argument on the stack. The last argument is the mode, {\em P\_CHECK} or {\em P\_NOCHECK}. If the directory name is a non-null string, then the current working directory is set to the indicated path. If the requested directory is an empty string, then a change-dir is performed to the startup directory. Modifier {\em P\_CHECK} causes this function to abort upon failure. Return register {\em reg} is set to type {\em e\_str}. The value of the return register is set to the obtained working directory. This may not be the requested directory if the {\em b_chDir} fails. */ /* #define msg */ #include "builtin.ih" static char dirsep[2] = {DIRSEP}; void b_chDir() { /* copy the destination */ register char *dir = rss_strdup(string_charp(stack_top() - 1)); register int mode = int_value(stack_top()); /* mode of operation */ char newdir[MAX_PATHLEN]; if (!*dir) /* destination is an empty string: */ { free(dir); dir = rss_strdup(gb_orgDir); /* change to the startup dir */ } if (chdir(dir) && rss_checkMode(mode)) /* cd to the directory */ rss_fatal(0, 0, "builtin_chDir - can't change dir to %s", dir); free(dir); /* at the new destination: obtain */ if (getcwd(newdir, MAX_PATHLEN) == NULL) rss_fatal(0, 0, "getcwd($s) fails"); /* its absolute pathname */ if (newdir[strlen(newdir) - 1] != DIRSEP) /* and append a DIRSEP */ strcat(newdir, dirsep); stringcons_charPtr(eb_releaseReg(), newdir); /* return reg */ } icmake-9.02.06/exec/builtin/ebwriteargument.c0000644000175000017500000000111613176557635020070 0ustar frankfrank#define msgx #include "builtin.ih" static char separator[] = {' ', 0}; void eb_writeArgument(void *dest, unsigned idx) { int stop; do { char *string = eb_getArg(idx, &stop); msg("argument = `%s', length = %u", string, strlen(string)); (*gb_pDestWrite)(dest, string, string + strlen(string)); /* write a separator between */ if (!stop && *string) /* list b_elements */ (*gb_pDestWrite)(dest, separator, separator + 1); free(string); } while (!stop); } icmake-9.02.06/exec/builtin/bstrchr.c0000644000175000017500000000064013176557635016334 0ustar frankfrank/* Function fun_builtin_strChr()} returns the first index in a string haystack where a character in the b_subString needle was found. If not found, -1 is returned. */ #include "builtin.ih" void b_strChr() { char const *haystack = string_charp(stack_top()); char const *ret = strpbrk(haystack, string_charp(stack_top() - 1)); intcons_int(eb_releaseReg(), ret ? ret - haystack : -1); } icmake-9.02.06/exec/builtin/bdotextension.c0000644000175000017500000000023013176557635017545 0ustar frankfrank#include "builtin.ih" void b_dotExtension() { stringcons_charPtr( eb_releaseReg(), rss_getDext(string_charp(stack_top())) ); } icmake-9.02.06/exec/builtin/bextension.c0000644000175000017500000000037013176557635017043 0ustar frankfrank/* The last pushed string is taken as a file name. The extension is returned. */ #include "builtin.ih" void b_extension() { stringcons_charPtr(eb_releaseReg(), rss_getExt(string_charp(stack_top()))); } icmake-9.02.06/exec/builtin/bstrelement.c0000644000175000017500000000130513176557635017210 0ustar frankfrank/* This function is called when an {\em op\_str\_el} opcode is enountered. The last pushed value is interpreted as a string, the one but last pushed value as an index. The return register {\em reg} is set to an {\em e\_str} variable: the character from the string at index {\em index}, terminated by $\backslash$0. If index is smaller than 0 or larger than the size of the string, {\em reg} holds a null-character. */ #include "builtin.ih" static char buf[2]; void b_strElement() { unsigned idx = int_value(stack_top()); char const *str = string_charp(stack_top() - 1); buf[0] = idx >= strlen(str) ? 0 : str[idx]; stringcons_charPtr(eb_releaseReg(), buf);; } icmake-9.02.06/exec/builtin/belement.c0000644000175000017500000000122613176557635016461 0ustar frankfrank/* This function is called when an {\em op\_builtin_element} opcode is enountered. The last pushed value is interpreted as a list, the one but last pushed value as an index. The return register {\em reg} is set to a string variable, holding a duplicate of the listbuiltin_element {\em index}. If index is larger than the size of the b_element, {\em reg} holds a null-string. */ #include "builtin.ih" void b_element() { unsigned idx = int_value(stack_top()); stringcons_charPtr( eb_releaseReg(), idx < list_size(stack_top() - 1) ? list_at(stack_top() - 1, idx) : "" ); } icmake-9.02.06/exec/builtin/bstat.c0000644000175000017500000000411313176557635016001 0ustar frankfrank/* This function expects a filename as last pushed {\em e\_str} value. The file attributes are retrieved by a {\em stat ()} call and the return register is set to the type {\em e\_list}. This list returns the following information: \begin{itemize} \item The first b_element represents the file attributes. \item The second b_element represents the file size. \end{itemize} */ #include "builtin.ih" void b_stat() { struct stat statbuf; /* file stat buffer */ int fileatt = 0; /* file attributes */ int mode = int_value(stack_top()); /* get mode arg */ char const *fname = string_charp(stack_top() - 1); /* get file name */ if (stat(fname, &statbuf)) /* do stat call */ { /* failure to stat? */ if (rss_checkMode (mode)) /* if mode indicates abort..*/ rss_fatal(0, 0, "stat - unable to stat file %s", fname); statbuf.st_size = -1; } /* empty list */ else { if (statbuf.st_mode & S_IREAD) /* set file attribute int */ fileatt |= IS_IREAD; if (statbuf.st_mode & S_IWRITE) fileatt |= IS_IWRITE; if (statbuf.st_mode & S_IEXEC) fileatt |= IS_IEXEC; if (statbuf.st_mode & S_IFDIR) fileatt |= IS_IFDIR; if (statbuf.st_mode & S_IFCHR) fileatt |= IS_IFCHR; if (statbuf.st_mode & S_IFREG) fileatt |= IS_IFREG; } listcons(eb_releaseReg()); /* return result as list */ char buf[80]; /* conversion buf */ sprintf(buf, "%u", fileatt); /* file attr --> string */ list_add_charPtr(&gb_reg, buf); /* = b_element #0 */ sprintf(buf, "%ld", /* file size --> string */ (long)statbuf.st_size); /* = b_element #1 */ list_add_charPtr(&gb_reg, buf); } icmake-9.02.06/exec/builtin/btrimright.c0000644000175000017500000000014213176557635017035 0ustar frankfrank#include "builtin.ih" void b_trimRight() { string_trimRight(eb_releaseReg(), stack_top()); } icmake-9.02.06/exec/builtin/bsubstring.c0000644000175000017500000000157413176557635017056 0ustar frankfrank/* */ #include "builtin.ih" void b_subString() { char const *str = string_charp(stack_top()); unsigned strLen = strlen(str); int firstIdx = int_value(stack_top() - 1); if (firstIdx < 0) // use 0 for negative offsets firstIdx = 0; int nChars = int_value(stack_top() - 2); if (nChars < 0) // use 0 for negative # of chars nChars = 0; if (firstIdx >= strLen) // 1st idx points beyond stringcons_charPtr(eb_releaseReg(), ""); // string contents: return // empty string else { stringcons_charPtr(eb_releaseReg(), str + firstIdx); /* intbal copy */ string_reduce(&gb_reg, nChars); /* reduce the strlen if necessary */ } } icmake-9.02.06/exec/builtin/ebsetstring.c0000644000175000017500000000065313176557635017222 0ustar frankfrank/* This function is called from {\em fun\_arg\_head()}, {\em fun\_cmd\_head()}, etc., to set the appropriate strings to a duplicate of the last pushed string. The argument {\em s} is freed if necessary. It should be the same pointer variable which is assigned the return value. */ #include "builtin.ih" char *eb_setString (char *s) { free(s); return s = rss_strdup(string_charp(stack_top())); } icmake-9.02.06/exec/builtin/bcmdtail.c0000644000175000017500000000100013176557635016433 0ustar frankfrank/* \funcref{fun\_cmd\_tail}{void fun\_cmd\_tail ()} {} {} {eb_setString()} {fun\_arg\_tail(), fun\_arg\_head()} {funcmdte.c} { This function is called when an {\em op\_cmd\_tail} opcode is read in the binary makefile. The {\em gb_cmdTail} variable is set to a duplicate of the string in the last pushed variable. The last pushed variable is then discarded. } */ #include "builtin.ih" void b_cmdTail() { gb_cmdTail = eb_setString(gb_cmdTail); } icmake-9.02.06/exec/builtin/barghead.c0000644000175000017500000000100213176557635016413 0ustar frankfrank/* \funcref{fun\_arg\_head}{void fun\_arg\_head ()} {} {} {eb_setString()} {fun\_arg\_tail(), fun\_cmd\_tail()} {funarghe.c} { This function is called when an {\em op\_arg\_head} opcode is read in the binary makefile. The {\em gb_argHead} variable is set to a duplicate of the string in the last pushed variable. The last pushed variable is then discarded. } */ #include "builtin.ih" void b_argHead () { gb_argHead = eb_setString (gb_argHead); } icmake-9.02.06/exec/builtin/ebnoformatting.c0000644000175000017500000000045313176557635017705 0ustar frankfrank#define msgx #include "builtin.ih" unsigned eb_noFormatting(void *dest, unsigned start, unsigned lastIdx) { gb_listIndex = 0; for (unsigned idx = start; idx != lastIdx; ++idx) { msg("write arg %u", idx); eb_writeArgument(dest, idx); } return lastIdx - start; } icmake-9.02.06/exec/builtin/bchangepath.c0000644000175000017500000000072713176557635017137 0ustar frankfrank/* The last pushed string is taken as a file name. The pathname is converted to the one but last pushed string. A new {\em e\_str} variable is created holding the new string and is returned via {\em gb_reg}. */ #include "builtin.ih" void b_changePath() { char *cp = rss_changePath(string_charp(stack_top()), string_charp(stack_top() - 1)); stringcons_charPtr(eb_releaseReg(), cp); free(cp); } icmake-9.02.06/exec/builtin/ebgetpid.c0000644000175000017500000000015513176557635016451 0ustar frankfrank#include "builtin.ih" void b_getPid() { gb_reg.type = e_int; gb_reg.intValue = (int16_t)getpid(); } icmake-9.02.06/exec/builtin/bargtail.c0000644000175000017500000000100013176557635016441 0ustar frankfrank/* \funcref{fun\_arg\_tail}{void fun\_arg\_tail ()} {} {} {eb_setString()} {fun\_arg\_tail(), fun\_cmd\_tail()} {funargte.c} { This function is called when an {\em op\_arg\_tail} opcode is read in the binary makefile. The {\em gb_argTail} variable is set to a duplicate of the string in the last pushed variable. The last pushed variable is then discarded. } */ #include "builtin.ih" void b_argTail() { gb_argTail = eb_setString(gb_argTail); } icmake-9.02.06/exec/builtin/bfprintf.c0000644000175000017500000000116413176557635016501 0ustar frankfrank/* This function prints the arguments to a {\em fprint()} statement, pushed onto the stack previously. The number of arguments to print is the last pushed value. The arguments are: the number of arguments (a hidden parameter), a filename, and then the remaining arguments to print. */ #include "builtin.ih" void b_fprintf() { char const *filename = string_charp(stack_top() - 1); FILE *outf; if (! (outf = fopen(filename, "a")) ) rss_fatal(0, 0, "cannot append to \"%s\"", filename); intcons_int(eb_releaseReg(), eb_formattedFprintf(outf, TO_FILE)); fclose(outf); } icmake-9.02.06/exec/builtin/bstrlower.c0000644000175000017500000000040513176557635016707 0ustar frankfrank/* Function {\em fun\_strlwr()} returns lower-case transformed string } */ #include "builtin.ih" void b_strLower() { char *cp = eb_strLower(rss_strdup(string_charp(stack_top()))); stringcons_charPtr(eb_releaseReg(), cp); free(cp); } icmake-9.02.06/exec/builtin/builtin.c0000644000175000017500000000045013176557635016332 0ustar frankfrank#include "builtin.ih" void builtin() { if (!getcwd(gb_orgDir, MAX_PATHLEN)) rss_fatal(0, 0, "getcwd($s) fails"); /* its absolute pathname */ gb_argHead = rss_strdup(""); gb_argTail = rss_strdup(""); gb_cmdHead = rss_strdup(""); gb_cmdTail = rss_strdup(""); } icmake-9.02.06/exec/builtin/basciistring.c0000644000175000017500000000104213176557635017343 0ustar frankfrank/* This function is called when a call to the built-in function {\em ascii} is to be processed. This function represents the opcode {\em op\_ascii\_int}: a string is converted to an int. If the last pushed value is a string, then the return register is set to the integer (ASCII number) representation of the first character in the string. */ #include "builtin.ih" static char buf[2]; void b_asciiString () { buf[0] = int_value(stack_top()); stringcons_charPtr(eb_releaseReg(), buf); } icmake-9.02.06/exec/builtin/ebenterch.c0000644000175000017500000000041313176557635016622 0ustar frankfrank#include "builtin.ih" /* enter the first of a series of characters, terminated by \n. The first char may be a \n */ int eb_enterCh() { int ch = getchar(); if (ch != '\n') { while (getchar() != '\n') ; } return ch; } icmake-9.02.06/exec/builtin/ebexecmd.c0000644000175000017500000000306113176557635016441 0ustar frankfrank/* This function is called from {\em fun\_builtin_exec()} to b_execute a command. The command is held in the {\em argv}-like array {\em cmd}. The same array is returned, since {\em eb_exeCmd()} may have to resize it to add a command tail. The return register is set to the exit status of the program. The maker aborts when: \begin{itemize} \item the indicated program cannot not be b_executed, \item the indicated program can be b_executed but returns a non-zero exit status while the b_execution mode allows checking. \end{itemize} {\bf Note that} the strings pointed to by the {\em cmd} array are not freed. */ #include "builtin.ih" char **eb_exeCmd(char **cmd, int mode) { register int i, ret; /* exit status */ if (strlen(gb_cmdTail)) /* add cmd tail */ cmd = eb_addCmd(cmd, gb_cmdTail); if (gb_echo) /* re-builtin_echo if requested */ { for (i = 0; cmd [i]; ++i) printf("%s ", cmd[i]); putchar('\n'); } fflush(stdout); /* try to b_execute */ ret = eb_spawnvp(WAIT, cmd [0], (char const **)cmd); /* if non-zero return and */ if (ret && rss_checkMode(mode)) /* if checking requested.. */ rss_fatal(0, 0, "builtin_execute - program indicates failure (status %d)", ret); intcons_int(eb_releaseReg(), ret); /* return exit status */ return cmd; } icmake-9.02.06/exec/builtin/data.c0000644000175000017500000000374713176557635015611 0ustar frankfrank#include "builtin.ih" char gb_orgDir[MAX_PATHLEN]; Variable gb_reg; int gb_echo = 1; unsigned gb_listIndex; /* eb_getArg.c, noformatting.c */ char *gb_argHead; char *gb_argTail; char *gb_cmdHead; char *gb_cmdTail; /* when the next initialization changes, verify that this is in line with changes in rss/types.ih */ void (*gb_pBuiltinFun[])(void) = { /* 0 */ b_argHead, b_argTail, b_asciiInt, b_asciiString, /* 4 */ b_backtick, b_changeBase, b_changeExtension, b_changePath, /* 8 */ b_chDir, b_cmdHead, b_cmdTail, b_echo, /* c */ b_element, b_backtick, b_exec, /* dummy for compiler-used */ b_exec, /* b_execute */ /* 10 */ b_exists, b_fgets, b_fprintf, b_getBase, /* 14 */ b_dotExtension, b_extension, b_path, b_getCh, /* 18 */ b_getEnv, b_getPid, b_gets, b_listlen, /* 1c */ b_makeList, b_printf, b_putEnv, b_stat, /* 20 */ b_strElement, b_strFind, b_strFormat, b_strLength, /* 24 */ b_strLower, b_resize, b_strtok, b_strUpper, /* 28 */ b_subString, b_system, b_trim, b_trimLeft, /* 2c */ b_trimRight, /* placeholders for functions that can be */ /* added later without having to change the */ /* binary code */ b_strChr, b_listFind, b_listUnion, /* 30 */ b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, b_empty, /* hlt is non-existent.. */ /* f_hlt used to mark non-existing functions */ }; void (*gb_pDestWrite)(void *dest, char const *begin, char const *end); icmake-9.02.06/exec/builtin/basciiint.c0000644000175000017500000000054513176557635016636 0ustar frankfrank/* This function is called when a call to the built-in function {\em ascii} is to be processed. The function represents the opcode {\em op\_ascii\_int}. The last pushed {\em e\_int} is converted to a string. */ #include "builtin.ih" void b_asciiInt() { intcons_int(eb_releaseReg(), *string_charp(stack_top())); } icmake-9.02.06/exec/builtin/blistfind.c0000644000175000017500000000056513176557635016651 0ustar frankfrank/* This function returns the first index of an element in the lhs list which is equal to either the rhs string -1 is returned if such an element was not found. */ #include "builtin.ih" void b_listFind(void) { Variable *target = stack_top() - 1; intcons_int( eb_releaseReg(), (int)list_contains(stack_top(), string_charp(target)) ); } icmake-9.02.06/exec/builtin/btrimleft.c0000644000175000017500000000014013176557635016650 0ustar frankfrank#include "builtin.ih" void b_trimLeft() { string_trimLeft(eb_releaseReg(), stack_top()); } icmake-9.02.06/exec/builtin/bstrtok.c0000644000175000017500000000213313176557635016354 0ustar frankfrank/* This function is b_executed upon an opcode {\em op_strtok}. The last pushed string is converted to a list, by splitting it according to the separators which are found in the one-but-last pushed string. When the separator-string is empty, then the string to split is split into separate characters. */ #include "builtin.ih" static char buf[2]; void b_strtok() { char const *str = string_charp(stack_top()); char const *sep = string_charp(stack_top() - 1); listcons(eb_releaseReg()); if (*str) { char *string = rss_strdup(str); char *cp; if (*sep) { if ((cp = strtok(string, sep))) { do { list_add_charPtr(&gb_reg, cp); cp = strtok(NULL, sep); } while (cp); } } else { cp = string; while (*cp) { buf[0] = *cp++; list_add_charPtr(&gb_reg, buf); } } free(string); } } icmake-9.02.06/exec/builtin/regptr.c0000644000175000017500000000012013176557635016161 0ustar frankfrank#include "builtin.ih" Variable const *builtin_regPtr() { return &gb_reg; } icmake-9.02.06/exec/builtin/bgetbase.c0000644000175000017500000000037613176557635016447 0ustar frankfrank/* The last pushed string is taken as a file name. The base name is returned. */ #include "builtin.ih" void b_getBase () { stringcons_charPtr( eb_releaseReg(), rss_getBase(string_charp(stack_top())) ); } icmake-9.02.06/exec/builtin/bfgets.c0000644000175000017500000000347113176557635016144 0ustar frankfrank/* This function reads in a string from a file and returns it in the {\em gb_reg} return register as an {\em e\_str} value. The arguments on the stack are: the filename and an {\em int offset}, where the read operation should start. The return value is a list, holding as the first list the just read line, as the second element the final \n (if available), as its third element the string OK, or FAIL, and as its fourth b_element the (long) offset value from where the next string must be read. This long value is stored as binary value using the host byte order. On EOF an empty list is returned. */ #include "builtin.ih" void b_fgets() { char const *filename = string_charp(stack_top()); Variable *list = stack_top() - 1; FILE *inf; listcons(eb_releaseReg()); char const *status; /* input not OK */ if (list_size(list) >= 4 && strcmp(status = list_at(list, 2), "OK") != 0) { eb_fgetsStatus(status); return; } long offset = list_size(list) == 0 ? 0 : strtol(list_at(list, 3), 0, 10); if ( (inf = fopen(filename, "r")) && (fseek(inf, offset, SEEK_SET) == 0) /* locate the read-pos. */ ) { char *dest = eb_getLine(inf); if (dest) /* anything read? */ eb_updateFgets(inf, dest); else if (!feof(inf)) /* no, and not EOF: fail */ eb_fgetsStatus("FAIL"); fclose (inf); return; /* empty list at EOF */ } eb_fgetsStatus("FAIL"); } icmake-9.02.06/exec/builtin/bgetch.c0000644000175000017500000000045413176557635016124 0ustar frankfrank/* This function reads in one key and returns it in the {\em reg} return register as an {\em e\_str} value. */ #include "builtin.ih" #include "../string/string.h" static char buf[2]; void b_getCh() { buf[0] = eb_termCh(); stringcons_charPtr(eb_releaseReg(), buf); } icmake-9.02.06/exec/builtin/ebgetcmdlen.c0000644000175000017500000000113413176557635017135 0ustar frankfrank/* \funcref{eb_getCmdLen}{int eb_getCmdLen (\params)} { {char} {**cmd} {{\em argv}-like array} } {length of command line corresponding to {\em cmd}} {} {eb_addCmd()} {getcmdle.c} { The length of the command, as represented by {\em cmd}, is returned. See {\em eb_addCmd()} for a description of the {\em cmd} array. } */ #include "builtin.ih" int eb_getCmdLen (cmd) char **cmd; { register int i, len; len = 0; for (i = 0; cmd [i]; i++) { len += strlen (cmd [i]); len++; } return (len); } icmake-9.02.06/exec/builtin/ebreleasereg.c0000644000175000017500000000014213176557635017307 0ustar frankfrank#include "builtin.ih" Variable *eb_releaseReg() { destructor(&gb_reg); return &gb_reg; } icmake-9.02.06/exec/builtin/builtin.ih0000644000175000017500000000721313176557635016514 0ustar frankfrank#include "builtin.h" #include #include #include #include #include #include #include #include #include "../var/var.h" #include "../stack/stack.h" #include "../list/list.h" #include "../string/string.h" #include "../virtual/virtual.h" #include "../int/int.h" typedef enum { TO_STRING = 1, TO_STDOUT = 1, TO_FILE = 2 } FormatDest; extern Variable gb_reg; extern char gb_orgDir[]; extern char *gb_argHead; extern char *gb_argTail; extern char *gb_cmdHead; extern char *gb_cmdTail; extern int gb_echo; extern unsigned gb_listIndex; extern void (*gb_pBuiltinFun[])(void); extern void (*gb_pDestWrite)(void *dest, char const *begin, char const *end); /* From push_reg(): This function is called when the return register is to be pushed. The return register is used to return information from built-in functions. {\bf Note that} the {\em count} field of the return register is {\bf not} incremented when the register is pushed. The associated memory is assigned by internal functions and may be freed by subsequent {\em pop}-instructions. Therefore, the builtin functions do not have to free the reg's memory when assigning a value to reg. */ char **eb_addCmd(char **, char *); char **eb_exeCmd(char **, int); char *eb_findPercent(char *begin); char *eb_getArg(unsigned argIdx, int *listDone); /* listDone = 1 when all list elements have been retrieved */ char *eb_getExecArg(unsigned, int *); char *eb_getLine(FILE *file); char *eb_setString(char *); char *eb_strLower(char *str); char *eb_strUpper(char *str); int eb_enterCh(void); int eb_getCmdLen(char **); int eb_spawnvp(int mode, char const *prog, char const **argv); int eb_termCh(void); unsigned eb_formattedFprintf(FILE *dest, FormatDest formatDest); unsigned eb_formatter(void *dest, FormatDest formatDest); unsigned eb_getNr(char **ptr); unsigned eb_noFormatting(void *dest, unsigned start, unsigned lastIdx); void eb_fgetsStatus(char const *status); void eb_fileWrite(void *dest, char const *begin, char const *end); void eb_stringWrite(void *dest, char const *begin, char const *end); void eb_updateFgets(FILE *inf, char *dest); void eb_writeArgument(void *dest, unsigned idx); Variable *eb_releaseReg(void); /* remaining b_ named functions are builtin functions that can be used by icmake scripts */ void b_resize(void); void b_empty(void); void b_argHead(void); void b_argTail(void); void b_asciiInt(void); void b_asciiString(void); void b_backtick(void); void b_stat(void); void b_putEnv(void); void b_chDir(void); void b_getEnv(void); void b_cmdHead(void); void b_cmdTail(void); void b_changeBase(void); void b_changeExtension(void); void b_changePath(void); void b_strtok(void); void b_fgets(void); void b_fprintf(void); void b_getBase(void); void b_getCh(void); void b_getPid(void); void b_gets(void); void b_dotExtension(void); void b_extension(void); void b_path(void); void b_echo(void); void b_element(void); void b_exec(void); void b_exists(void); void b_makeList(void); void b_printf(void); void b_listlen(void); void b_strElement(void); void b_strFind(void); void b_strFormat(void); void b_strLength(void); void b_strLower(void); void b_strUpper(void); void b_subString(void); void b_system(void); void b_trim(void); void b_trimLeft(void); void b_trimRight(void); void b_strChr(void); void b_listFind(void); void b_listUnion(void); icmake-9.02.06/exec/builtin/ebformattedfprintf.c0000644000175000017500000000044513176557635020555 0ustar frankfrank#define msgx #include "builtin.ih" unsigned eb_formattedFprintf(FILE *out, FormatDest formatDest) { gb_pDestWrite = eb_fileWrite; /* write to file or string: here: to file */ return eb_formatter(out, formatDest); } icmake-9.02.06/exec/builtin/frame0000644000175000017500000000004513176557635015535 0ustar frankfrank#include "builtin.ih" void b_() { } icmake-9.02.06/exec/builtin/bstrupper.c0000644000175000017500000000040513176557635016712 0ustar frankfrank/* Function {\em fun\_strupr()} returns lower-case transformed string } */ #include "builtin.ih" void b_strUpper() { char *cp = eb_strUpper(rss_strdup(string_charp(stack_top()))); stringcons_charPtr(eb_releaseReg(), cp); free(cp); } icmake-9.02.06/exec/builtin/ebfindpercent.c0000644000175000017500000000156013176557635017477 0ustar frankfrank#include "builtin.ih" char *eb_findPercent(char *ptr) { while (1) /* search the string */ { ptr += strcspn(ptr, "\\%"); /* ptr -> \, % or \0 */ switch (*ptr) { case 0: /* at end of string */ return ptr; case '\\': /* at a backslash */ if (*++ptr) /* skip the next char */ ++ptr; break; default: /* at % */ if (isdigit(ptr[1])) /* if at % */ return ptr; /* return ptr -> % */ ++ptr; /* or skip % and continue */ break; } } } icmake-9.02.06/exec/builtin/builtin.h0000644000175000017500000000043113176557635016336 0ustar frankfrank#ifndef _INCLUDED_BUILTIN_H_ #define _INCLUDED_BUILTIN_H_ #include "../../rss/rss.h" void builtin(void); /* prepare initial data, call only once */ void builtin_call(unsigned funIdx); void builtin_popReg(void); Variable const *builtin_regPtr(); #endif icmake-9.02.06/exec/builtin/ebstrupper.c0000644000175000017500000000022513176557635017057 0ustar frankfrank#include "builtin.ih" char *eb_strUpper(char *s) { register char *cp; for (cp = s; *cp; ++cp) *cp = toupper(*cp); return s; } icmake-9.02.06/exec/builtin/ebgetline.c0000644000175000017500000000215513176557635016626 0ustar frankfrank#include "builtin.ih" #define bufsize (200) #define buflast (bufsize - 1) #define lastch (bufsize - 2) char *eb_getLine(FILE *file) { char *dest = rss_strdup(""); char buffer[bufsize]; while (1) { buffer[lastch] = 0; /* overwritten by \n or the */ /* last char read of a line */ /* otherwise, the end of the*/ /* line is earlier */ if (!fgets(buffer, buflast, file)) /* reading fails */ break; dest = rss_strcat(dest, buffer); /* append the buffer */ /* EOLN encountered */ if (buffer[lastch] == '\n' || !buffer[lastch]) break; /* end of line at then end */ /* or earlier */ } if (*dest) /* line read */ return dest; free(dest); return NULL; } icmake-9.02.06/exec/builtin/bstrfind.c0000644000175000017500000000062513176557635016503 0ustar frankfrank/* Function {\em fun\_builtin_strFind()} returns the first index in a string haystack where a b_subString needle was found. If not found, -1 is returned. */ #include "builtin.ih" void b_strFind() { char const *haystack = string_charp(stack_top()); char const *ret = strstr(haystack, string_charp(stack_top() - 1)); intcons_int(eb_releaseReg(), ret ? ret - haystack : -1); } icmake-9.02.06/exec/builtin/bempty.c0000644000175000017500000000002713176557635016164 0ustar frankfrankvoid b_empty (void) {} icmake-9.02.06/exec/builtin/bprintf.c0000644000175000017500000000050413176557635016330 0ustar frankfrank/* This function prints the arguments to a {\em printf()} statement, pushed onto the stack previously. The number of arguments to printf is the last pushed value. */ /* #define msg */ #include "builtin.ih" void b_printf(void) { intcons_int(eb_releaseReg(), eb_formattedFprintf(stdout, TO_STDOUT)); } icmake-9.02.06/exec/builtin/bchangebase.c0000644000175000017500000000037713176557635017116 0ustar frankfrank#include "builtin.ih" void b_changeBase() { char *cp = rss_changeBase( string_charp(stack_top()), string_charp(stack_top() - 1) ); stringcons_charPtr(eb_releaseReg(), cp); free(cp); } icmake-9.02.06/exec/main.c0000644000175000017500000000271313176557635014146 0ustar frankfrank/* The {\em main()} function opens the binary makefile, reads the offsets of the variables and strings sections, calls {\em getvar()} to retrieve the variables, pushes {\em argc}, {\em argv} and {\em envp} onto the {\em icmake} stack and then calls {\em process()} to execute the makefile. The exit value of {\em main()} is held in the global variable {\em retval} (see also {\em fun\_ret()}). Function {\em cleanup()} is attached to the `at-exit' list for DOS systems. This is necessary so that the startup working directory is restored. For UNIX systems, no {\em atexit()} list is created. */ #define msg /* */ #include "icm-exec.ih" int main(int argc, char **argv) { if (argc == 1) usage(argv[0]); argv = aux_testRmBim(&argc, argv); builtin(); /* prepare builtin data */ opcodefun_setInfile(argv[1]); atexit(cleanup); signal(SIGINT, (void (*)(int))aux_abnormal); opcodefun_setGlobalVariables(); // third main arg: environ ListVariable list; listcons_charPtrPtr(&list, environ); stack_push(&list); listDestructor(&list); // second main arg: argv listcons_size_charPtrPtr(&list, argc, argv); stack_push(&list); listDestructor(&list); // first main arg: argc IntVariable nArgs; intcons_int(&nArgs, argc - 1); stack_push(&nArgs); intDestructor(&nArgs); return opcodefun_process(); } icmake-9.02.06/exec/opcodefun/0000755000175000017500000000000013232314230015004 5ustar frankfrankicmake-9.02.06/exec/opcodefun/opushstrconst.c0000644000175000017500000000165013176557635020141 0ustar frankfrank/* This function is called when a string constant is to be pushed onto the stack. The offset of the string to be pushed, relative to the strings section of the binary makefile, is expected to follow the opcode. This relative offset is an {\em uint16_t} variable. A variable of type {\em e\_str} and with field {\em valuestr} set to a duplicate of the string constant is pushed. */ /* #define msg */ #include "opcodefun.ih" void o_push_strconst() { register char *str = rss_getString(go_infile, go_header->offset[0], (unsigned)rss_getInt16(go_infile)); if (str == (char *)-1) rss_fatal(0, 0, "cannot get string, opcode at %s", aux_offset()); /* str is allocated by getstring() */ String tmp; stringcons_charPtr(&tmp, str); stack_push(&tmp); stringDestructor(&tmp); free(str); } icmake-9.02.06/exec/opcodefun/opushreg.c0000644000175000017500000000131213176557635017032 0ustar frankfrank/* This function is called when the return register is to be pushed. The return register is used to return information from built-in functions. {\bf Note that} the {\em count} field of the return register is {\bf not} incremented when the register is pushed. The associated memory is assigned by internal functions and may be freed by subsequent {\em pop}-instructions. Therefore, also the builtin functions do not have to free the reg's memory when assigning a value to reg. */ #include "opcodefun.ih" void o_push_reg() { stack_push(builtin_regPtr()); /* do not de-allocate, since it merely */ /* transfers its memory to its dest. */ } icmake-9.02.06/exec/opcodefun/osm.c0000644000175000017500000000100013176557635015766 0ustar frankfrank/* \funcref{fun\_sm}{void fun\_sm ()} {} {} {push(),virtual_compare(), stack_pop()} {} {funsm.c} { Function {\em fun\_sm()} is called when opcode {\em op\_sm} is read. This function pops two variables, calls {\em compare()} to compare the values, and pushes the result of the comparison. The two compared variables are discarded. } */ #include "opcodefun.ih" void o_sm () { o_neq(); int_assignInt(stack_top(), int_value(stack_top()) < 0); } icmake-9.02.06/exec/opcodefun/opush1.c0000644000175000017500000000102013176557635016411 0ustar frankfrank/* This function serves the evaluation of logical expressions. It is executed when an {\em op\_push\_1\_jmp\_end} opcode is found in the binary makefile. A variable of type {\em e\_int} is pushed, while its {\em intValue} field is set 1. After this, the next opcode (which is by definition {\em op\_push\_0}) is skipped. */ #include "opcodefun.ih" void o_push_1_jmp_end() { IntVariable tmp; intcons_int(&tmp, 1); stack_push(&tmp); intDestructor(&tmp); rss_getOpcode(go_infile); } icmake-9.02.06/exec/opcodefun/oitoa.c0000644000175000017500000000106213176557635016313 0ustar frankfrank/* This funtion converts the integer variable which was last pushed to a string variable. The {\em type} field of the last used stack position (this is {\em stack[sp]}) is set to {\em e\_str} and the {\em value.str} field is assigned to hold the string representation of the {\em intValue} field. */ #include "opcodefun.ih" void o_itoa() { char buffer[100]; sprintf(buffer, "%d", int_value(stack_top())); Variable tmp; stringcons_charPtr(&tmp, buffer); virtual_assign(stack_top(), &tmp); stringDestructor(&tmp); } icmake-9.02.06/exec/opcodefun/opcodefun.ih0000644000175000017500000000256013176557635017344 0ustar frankfrank#include "opcodefun.h" #include #include #include "../aux/aux.h" #include "../var/var.h" #include "../stack/stack.h" #include "../virtual/virtual.h" #include "../int/int.h" #include "../list/list.h" #include "../string/string.h" #include "../builtin/builtin.h" extern int go_retVal; extern FILE *go_infile; extern BinHeader *go_header; extern Variable *go_globalVar; extern void (*go_pRssFun[])(void); Variable *o_getDest(void); int o_isTrue(void); void o_call(void); void o_exit(void); void o_ret(void); void o_popReg(void); void o_push_imm(void); void o_callRss(void); void o_push_strconst(void); void o_pushVar(void); void o_popVar(void); void o_frame(void); void o_asp(void); void o_add(void); void o_shl(void); void o_shr(void); void o_empty(void); void o_jmp(void); void o_jmpTrue(void); void o_push_reg(void); void o_older(void); void o_younger(void); void o_atoi(void); void o_atol(void); void o_band (void); void o_bnot(void); void o_bor(void); void o_dec(void); void o_div(void); void o_eq(void); void o_gr(void); void o_greq(void); void o_inc(void); void o_itoa(void); void o_jmpFalse(void); void o_mod(void); void o_mul(void); void o_neq(void); void o_push_0(void); void o_push_1_jmp_end(void); void o_sm(void); void o_smeq(void); void o_sub(void); void o_umin(void); void o_xor(void); void o_copyVar(void); icmake-9.02.06/exec/opcodefun/ogetdest.c0000644000175000017500000000071513176557635017022 0ustar frankfrank/* This function is called when an opcode is read which is followed by a variable number (e.g., {\em op\_push\_var}). The index is read and a pointer to a {\em VAR\_} structure is returned; either in the variables section or in the stack (relative to {\em bp}). */ /*#define msg */ #include "opcodefun.ih" Variable *o_getDest() { int index = rss_getInt16(go_infile); return index >= 0 ? go_globalVar + index : stack_local(index); } icmake-9.02.06/exec/opcodefun/close.c0000644000175000017500000000011313176557635016301 0ustar frankfrank#include "opcodefun.ih" void opcodefun_close() { fclose(go_infile); } icmake-9.02.06/exec/opcodefun/omod.c0000644000175000017500000000122713176557635016141 0ustar frankfrank/* This function pops two variables and pushes the modulo value of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. It is assumed that the left argument of the modision was pushed first; therefore, the right argument is popped first. A division by zero leads to an error. */ #include "opcodefun.ih" void o_mod () { int value = int_value(stack_top()); if (!value) rss_fatal(0, 0, "division by zero at %s", aux_offset()); stack_pop(); value = int_value(stack_top()) % value; int_assignInt(stack_top(), value); /* update the stack_top()'s value */ } icmake-9.02.06/exec/opcodefun/obnot.c0000644000175000017500000000052213176557635016321 0ustar frankfrank/* \funcref{fun\_bnot}{void fun\_bnot ()} {} {} {} {} {funbnot.c} { Function {\em fun\_bnot()} bitwise-not's the last pushed variable. This variable is assumed to be of type {\em e\_int}. } */ #include "opcodefun.ih" void o_bnot () { int_assignInt(stack_top(), ~int_value(stack_top())); } icmake-9.02.06/exec/opcodefun/oxor.c0000644000175000017500000000075213176557635016174 0ustar frankfrank/* \funcref{fun\_xor}{void fun\_xor ()} {} {} {stack_pop(), stack_push()} {} {funxor.c} { This function pops two variables and pushes the bitwise xor-ed result of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. } */ #include "opcodefun.ih" void o_xor () { int rvalue = int_value(stack_top()); stack_pop(); int_assignInt(stack_top(), int_value(stack_top()) ^ rvalue); } icmake-9.02.06/exec/opcodefun/ojmptrue.c0000644000175000017500000000126313176557635017050 0ustar frankfrank/* \funcref{fun\_jmp\_true}{void fun\_jmp\_true ()} {} {} {rss_getInt16(), o_isTrue()} {fun\_jmp\_false(), fun\_jmp()} {funjmpt.c} { This function is executed when an {\em op\_jmp\_true} opcode is read in the binary makefile. Following the opcode, an {\em int16_t} offset is expected. The result of a previous expression is popped and if this yields non-zero, a jump is made relative to the current offset by repositioning the file pointer. } */ #include "opcodefun.ih" void o_jmpTrue () { register int16_t offs = rss_getInt16 (go_infile); if (o_isTrue()) fseek(go_infile, (int32_t) offs, SEEK_CUR); } icmake-9.02.06/exec/opcodefun/opush0.c0000644000175000017500000000061213176557635016416 0ustar frankfrank/* This function serves the evaluation of logical expressions. It is executed when an {\em op\_push\_0} opcode is found in the binary makefile. A variable of type {\em e\_int} is pushed, while its {\em intValue} field is set to zero. */ #include "opcodefun.ih" void o_push_0() { IntVariable tmp; intcons_int(&tmp, 0); stack_push(&tmp); intDestructor(&tmp); } icmake-9.02.06/exec/opcodefun/opushvar.c0000644000175000017500000000105613176557635017052 0ustar frankfrank/* This function is executed when an {\em op\_push\_var} opcode is read in the binary makefile. Follwing the opcode a variable index is expected. This variable is pushed onto the stack. */ /*#define msg */ #include "opcodefun.ih" void o_pushVar() { stack_push(o_getDest()); /* A global var's address is returned, */ /* Since it's a var, */ /* getDest()'s return variable shouldn't be */ /* destroyed */ } icmake-9.02.06/exec/opcodefun/oasp.c0000644000175000017500000000123113176557635016140 0ustar frankfrank/* \funcref{fun\_asp} {void fun\_asp ()} {} {} {rss_getOpcode(), stack_pop(), discard()} {} {funasp.c} { This function is executed when an {\em op\_asp} opcode is read from the binary makefile. Following the opcode, an {\em UNS8} argument is expected which specifies the number of stack positions to discard. Function {\em fun\_asp()} repetitively calls {\em stack_pop()} and {\em discard()} to throw away the stack variables. } */ #include "opcodefun.ih" void o_asp () { register unsigned idx = (unsigned)rss_getOpcode(go_infile); for ( ; idx--; ) stack_pop(); } icmake-9.02.06/exec/opcodefun/oumin.c0000644000175000017500000000052413176557635016331 0ustar frankfrank/* \funcref{fun\_umin}{void fun\_umin ()} {} {} {} {} {funumin.c} { Function {\em fun\_umin()} reverses the sign of the last pushed variable. This variable is assumed to be of type {\em e\_int}. } */ #include "opcodefun.ih" void o_umin() { stack_top()->intValue = -stack_top()->intValue; } icmake-9.02.06/exec/opcodefun/oinc.c0000644000175000017500000000066713176557635016142 0ustar frankfrank/* \funcref{fun\_inc}{void fun\_inc ()} {} {} {} {fun\_dec()} {funinc.c} { This function decrements the {\em intValue} field of a variable. The The number of the variable (a 16-bits unsigned number) is assumed to follow the {\em op\_dec} opcode. } */ #include "opcodefun.ih" void o_inc () { register Variable *dest = o_getDest(); int_assignInt(dest, int_value(dest) + 1); } icmake-9.02.06/exec/opcodefun/oatol.c0000644000175000017500000000073113176557635016320 0ustar frankfrank/* This function converts the last pushed variable, which is assumed to hold a string, to a list of one element. The string variable is discarded after use. The formed list, containing one element, is copied onto the stack to the former position of the string variable. */ #include "opcodefun.ih" void o_atol() { Variable tmp; listcons_charPtr(&tmp, string_charp(stack_top())); virtual_assign(stack_top(), &tmp); listDestructor(&tmp); } icmake-9.02.06/exec/opcodefun/omul.c0000644000175000017500000000115313176557635016155 0ustar frankfrank/* \funcref{fun\_mul}{void fun\_mul ()} {} {} {stack_pop(), stack_push()} {} {funmul.c} { This function pops two variables and pushes the product of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. } */ #include "opcodefun.ih" void o_mul() { int value = int_value(stack_top()); stack_pop(); /* remove rhs */ value *= int_value(stack_top()); /* multiply with lhs */ int_assignInt(stack_top(), value); /* update the stack_top()'s value */ } icmake-9.02.06/exec/opcodefun/oatoi.c0000644000175000017500000000110513176557635016311 0ustar frankfrank/* This funtion converts the string variable which was last pushed to an integer variable. The {\em type} field of the last used stack position (this is {\em stack[sp]}) is set to {\em e\_int} and the {\em intValue} field is assigned to hold the integer representation of the {\em value.str} field. The string variable which occupied the stack is discarded. */ #include "opcodefun.ih" void o_atoi() { IntVariable value; intcons_int(&value, atoi(string_charp(stack_top()))); virtual_assign(stack_top(), &value); intDestructor(&value); } icmake-9.02.06/exec/opcodefun/oshr.c0000644000175000017500000000121713176557635016155 0ustar frankfrank/* \funcref{fun\_shr}{void fun\_shr ()} {} {} {stack_pop(), stack_push(), rss_fatal()} {} {funshr.c} { This function pops two variables and pushes the shift-right result of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. It is assumed that the left argument of the expression was pushed first; therefore, the right argument is popped first. } */ #include "opcodefun.ih" void o_shr () { int rvalue = int_value(stack_top()); stack_pop(); int_assignInt(stack_top(), int_value(stack_top()) >> rvalue); } icmake-9.02.06/exec/opcodefun/ocall.c0000644000175000017500000000117513176557635016277 0ustar frankfrank/* This function is executed whan an {\em op\_call} opcode is read. Following the opcode a 16-bits unsigned value is expected, stating the offset of the function to call. The offset of the next instruction is pushed as an {\em e\_int} variable. Then the file pointer associated with the binary makefile is set to the offset of the called function. */ #include "opcodefun.ih" void o_call() { uint16_t offs = rss_getInt16(go_infile); Variable ra; intcons_int(&ra, ftell(go_infile)); stack_push(&ra); stack_pushBP(); fseek(go_infile, (int32_t)offs, SEEK_SET); } icmake-9.02.06/exec/opcodefun/oexit.c0000644000175000017500000000033013176557635016325 0ustar frankfrank/* This function places the {\em int} value of the return register {\em reg} into the global variable {\em retval}. */ #include "opcodefun.ih" void o_exit() { go_retVal = int_value(builtin_regPtr()); } icmake-9.02.06/exec/opcodefun/obor.c0000644000175000017500000000075113176557635016145 0ustar frankfrank/* \funcref{fun\_bor}{void fun\_bor ()} {} {} {stack_pop(), stack_push()} {} {funbor.c} { This function pops two variables and pushes the bitwise or-ed result of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. } */ #include "opcodefun.ih" void o_bor () { int rvalue = int_value(stack_top()); stack_pop(); int_assignInt(stack_top(), int_value(stack_top()) | rvalue); } icmake-9.02.06/exec/opcodefun/oyounger.c0000644000175000017500000000127213176557635017052 0ustar frankfrank/* This function is executed when an {\em op\_younger} opcode is found in the binary makefile. Two variables are popped and their {\em valuestr} fields are used as file names to compare two files. The result of the comparison is pushed as an {\em e\_int} variable. Note that the right operand of the {\em younger} operator is popped first since the left operand is expected to be pushed first. */ #include "opcodefun.ih" void o_younger () { int ret; Variable rval; copycons(&rval, stack_top()); stack_pop(); ret = rss_younger(string_charp(stack_top()), string_charp(&rval)); stringDestructor(stack_top()); intcons_int(stack_top(), ret); } icmake-9.02.06/exec/opcodefun/odiv.c0000644000175000017500000000122113176557635016136 0ustar frankfrank/* This function pops two variables and pushes the quotient of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. It is assumed that the left argument of the division was pushed first; therefore, the right argument is popped first. A division by zero leads to an rss_fatal. */ #include "opcodefun.ih" void o_div() { int value = int_value(stack_top()); if (!value) rss_fatal(0, 0, "division by zero at %s", aux_offset()); stack_pop(); value = int_value(stack_top()) / value; int_assignInt(stack_top(), value); /* update the stack_top()'s value */ } icmake-9.02.06/exec/opcodefun/oistrue.c0000644000175000017500000000101313176557635016666 0ustar frankfrank/* This function pops the last pushed variable and determines if that variable should yield true. If the variable is of type {\em e\_int}, then the integer representation is returned. If the variable is of type {\em e\_str}, then the first character in the string (this may be a zero-byte) is returned. If the variable is of type {\em e\_list}, the list size is returned. */ #include "opcodefun.ih" int o_isTrue() { int ret = virtual_bool(stack_top()); stack_pop(); return ret; } icmake-9.02.06/exec/opcodefun/ocallrss.c0000644000175000017500000000157313176557635017031 0ustar frankfrank/* This function is executed when an {\em op\_call\_rss} opcode is encountered in the binary makefile. Following this opcode a function index is expected (an {\em char} value), indicating the function number to call (see the enumeration type {\em FUNNR\_} in the file {\em icrss.h}). If the index indicates a non-existing function, i.e., when the index exceeds or equals {\em f\_hlt}, an error occurs. Else, the indicated built in function is called (see the {\em builtinfun} array of function pointers, files {\em opcodefun.ih} and {\em data.c}). */ /* #define msg */ #include "opcodefun.ih" void o_callRss() { unsigned funIdx = (unsigned)rss_getOpcode(go_infile); if (funIdx >= f_hlt) rss_fatal(0, 0, "unknown rss function call at %s", aux_offset()); msg("calling builtin function 0x%x", funIdx); builtin_call(funIdx); } icmake-9.02.06/exec/opcodefun/ojmp.c0000644000175000017500000000105513176557635016147 0ustar frankfrank/* \funcref{fun\_jmp}{void fun\_jmp ()} {} {} {rss_getInt16()} {fun\_jmp\_true(), fun\_jmp\_false()} {funjmp.c} { This function is executed when an {\em op\_jmp} opcode is read in the binary makefile. Following the opcode, an {\em int16_t} offset is expected. An unconditional jump is made relative to the current offset by repositioning the file pointer. } */ #include "opcodefun.ih" void o_jmp () { int16_t offs = rss_getInt16(go_infile); fseek(go_infile, (int32_t) offs, SEEK_CUR); } icmake-9.02.06/exec/opcodefun/data.c0000644000175000017500000000616113176557635016116 0ustar frankfrank#include "opcodefun.ih" char *go_cmdtail; char *go_cmdHead; char *go_cmdtail; Variable *go_globalVar; int go_retVal; FILE *go_infile; BinHeader *go_header; void (*go_pRssFun[])(void) = { o_jmp, /* op_jmp, 00 */ o_jmpFalse, /* op_jmp_false, 01 */ o_jmpTrue, /* op_jmp_true, 02 */ o_push_1_jmp_end, /* op_push_1_jmp_end, 03 */ o_push_0, /* op_push_0, 04 */ o_push_imm, /* op_push_imm, 05 */ o_push_strconst, /* op_push_strconst, 06 */ o_pushVar, /* op_push_var, 07 */ o_push_reg, /* op_push_reg, 08 */ o_popVar, /* op_pop_var, 09 */ o_umin, /* op_umin, 0a */ o_atoi, /* op_atoi, 0b */ o_itoa, /* op_itoa, 0c */ o_atol, /* op_atol, 0d */ o_mul, /* op_mul, 0e */ o_div, /* op_div, 0f */ o_mod, /* op_mod, 10 */ o_add, /* op_add, 11 */ o_sub, /* op_sub, 12 */ o_eq, /* op_eq, 13 */ o_neq, /* op_neq, 14 */ o_sm, /* op_sm, 15 */ o_gr, /* op_gr, 16 */ o_younger, /* op_younger, 17 */ o_older, /* op_older, 18 */ o_smeq, /* op_smeq, 19 */ o_greq, /* op_greq, 1a */ o_callRss, /* op_call_rss, 1b */ o_asp, /* op_asp, 1c */ o_exit, /* op_exit, 1d */ o_copyVar, /* op_copy_var, 1e */ o_inc, /* op_inc, 1f */ o_dec, /* op_dec, 20 */ o_call, /* op_call, 21 */ o_frame, /* op_frame, 22 */ o_ret, /* op_ret, 23 */ o_popReg, /* op_pop_reg, 24 */ o_band, /* op_band, 25 */ o_bor, /* op_bor, 26 */ o_bnot, /* op_bnot, 27 */ o_xor, /* op_xor, 28 */ o_shl, /* op_shl, 29 */ o_shr, /* op_shr, 2a */ /* o_hlt does not exist, op_hlt is a dummy... */ }; icmake-9.02.06/exec/opcodefun/ogreq.c0000644000175000017500000000101513176557635016313 0ustar frankfrank/* \funcref{fun\_greq}{void fun\_greq ()} {} {} {push(),virtual_compare(), stack_pop()} {} {fungreq.c} { Function {\em fun\_greq()} is called when opcode {\em op\_greq} is read. This function pops two variables, calls {\em compare()} to compare the values, and pushes the result of the comparison. The two compared variables are discarded. } */ #include "opcodefun.ih" void o_greq () { o_neq(); int_assignInt(stack_top(), int_value(stack_top()) >= 0); } icmake-9.02.06/exec/opcodefun/oolder.c0000644000175000017500000000126513176557635016471 0ustar frankfrank/* This function is executed when an {\em op\_older} opcode is found in the binary makefile. Two variables are popped and their {\em valuestr} fields are used as file names to compare two files. The result of the comparison is pushed as an {\em e\_int} variable. Note that the right operand of the {\em older} operator is popped first since the left operand is expected to be pushed first. */ #include "opcodefun.ih" void o_older() { int ret; Variable rval; copycons(&rval, stack_top()); stack_pop(); ret = rss_older(string_charp(stack_top()), string_charp(&rval)); stringDestructor(stack_top()); intcons_int(stack_top(), ret); } icmake-9.02.06/exec/opcodefun/opopvar.c0000644000175000017500000000146513176557635016675 0ustar frankfrank/* This function is called when an {\em op\_pop\_var} is encountered in the binary makefile. Following the opcode a variable index is expected. The logic of the function is as follows: \begin{itemize} \item The original contents of the variable are released if necessary by calling {\em discard()}. \item The last used stack element is copied into the variable. \item The stack pointer is decremented to reflect the shrinking of the stack. \end{itemize} Note that the memory associated with the stack variable remains unchanged. */ #include "opcodefun.ih" void o_popVar() { virtual_assign(o_getDest(), stack_top()); /* increments the reference count */ stack_pop(); /* and resets it to its former value */ } icmake-9.02.06/exec/opcodefun/oband.c0000644000175000017500000000075613176557635016274 0ustar frankfrank/* \funcref{fun\_band}{void fun\_band ()} {} {} {stack_pop(), stack_push()} {} {funband.c} { This function pops two variables and pushes the bitwise and-ed result of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. } */ #include "opcodefun.ih" void o_band () { int rvalue = int_value(stack_top()); stack_pop(); int_assignInt(stack_top(), int_value(stack_top()) & rvalue); } icmake-9.02.06/exec/opcodefun/setglobalvariables.c0000644000175000017500000000165013176557635021050 0ustar frankfrank/* #define msg */ #include "opcodefun.ih" void opcodefun_setGlobalVariables() { unsigned nvars = rss_getVar(&go_globalVar, go_infile, go_header); msg("N global vars: %u", nvars); /* return array of global vars */ if (nvars == (int16_t)-1) rss_fatal(0, 0, "invalid bim-file, cannot read variable section"); /* global string/list variables haven't been initialized by */ /* the compiler, so that's icm-exec's job */ for (Variable *var = go_globalVar, *end = var + nvars; var != end; ++var) { switch (var_type(var)) { case e_str: stringcons(var); break; case e_list: listcons(var); break; default: // not handled break; } } fseek(go_infile, go_header->offset[3], SEEK_SET); } icmake-9.02.06/exec/opcodefun/oret.c0000644000175000017500000000124613176557635016155 0ustar frankfrank/* \funcref{fun\_ret}{void fun\_ret ()} {} {} {stack_pop(), discard()} {fun\_call()} {funret.c} { This code terminates a called function. The assembler opcodes {\em mov sp, bp ; pop bp} are simulated by popping and discarding until {\em sp} equals {\em bp} and subsequently popping {\em bp}. After this, the return address is popped and the file pointer associated with the input file is set to this address. } */ #include "opcodefun.ih" void o_ret () { stack_popBP(); { int32_t ra = (int32_t)int_value(stack_top()); stack_pop(); fseek (go_infile, ra, SEEK_SET); } } icmake-9.02.06/exec/opcodefun/ocopyvar.c0000644000175000017500000000106313176557635017043 0ustar frankfrank/* This function is called when an {\em op\_copy\_var} opcode is encountered in the makefile. Following this opcode, a variable index is expected. The index may point to a global variable, to a function parameter or to a local variable. The function serves multiple assignments. The last pushed variable is copied onto the indicated variable. For {\em e\_str} and {\em e\_list} variables, this may involve the sharing of occupied memory. */ #include "opcodefun.ih" void o_copyVar () { virtual_assign(o_getDest(), stack_top()); } icmake-9.02.06/exec/opcodefun/process.c0000644000175000017500000000170513176557635016662 0ustar frankfrank/* Function {\em process()} is the main loop of the execution of the binary makefile. It is called from {\em main()} when the variables are read and when the offsets of the variable section and of the strings section are known. An opcode is retrieved from the binary makefile and appropriate action is taken until an {\em op\_ret} opcode is encountered. */ /* #define msg */ #include "opcodefun.ih" int opcodefun_process() { register Opcode opcode; do { aux_set(ftell(go_infile)); opcode = rss_getOpcode(go_infile); msg("opcode: 0x%x at %s", opcode, aux_offset()); if (opcode >= op_hlt || opcode == (Opcode)-1) { fprintf(stderr, "bad opcode at %s ", aux_offset()); rss_fatal(0, 0, "(opcode %s)", rss_hexString(opcode, 2)); } go_pRssFun[opcode](); } while (opcode != op_exit); return go_retVal; } icmake-9.02.06/exec/opcodefun/oframe.c0000644000175000017500000000205513176557635016454 0ustar frankfrank/* This function is executed when an {\em op\_frame} opcode is encountered. Following this opcode, the number of local variables is expected. When room for local variables should be made, a series of variable types is expected. The function imitates the assembler opcodes {\em push bp; mov bp, sp} by pushing an {\em e\_int} variable with the value of {\em bp} as {\em intValue} field. If local variables should be created, then {\em newvar()} is called to create a variable (the variable type is read from the binary makefile) and {\em push()} is called to make room for the variable. */ /* #define msg */ #include "opcodefun.ih" void o_frame() { unsigned nlocals = rss_getOpcode(go_infile); unsigned idx; for (idx = 0; idx != nlocals; ++idx) { Variable frame; constructor(&frame, (ExprType)rss_getOpcode(go_infile)); stack_push(&frame); /* push a local variable on the stack */ destructor(&frame); } } icmake-9.02.06/exec/opcodefun/oshl.c0000644000175000017500000000122013176557635016141 0ustar frankfrank/* \funcref{fun\_shl}{void fun\_shl ()} {} {} {stack_pop(), stack_push(), rss_fatal()} {} {funshl.c} { This function pops two variables and pushes the shift-left result of the {\em intValue} fields of these variables. The resulting pushed variable is of type {\em e\_int}. It is assumed that the left argument of the expression was pushed first; therefore, the right argument is popped first. } */ #include "opcodefun.ih" void o_shl () { int rvalue = int_value(stack_top()); stack_pop(); int_assignInt(stack_top(), int_value(stack_top()) << rvalue); } icmake-9.02.06/exec/opcodefun/osmeq.c0000644000175000017500000000101513176557635016322 0ustar frankfrank/* \funcref{fun\_smeq}{void fun\_smeq ()} {} {} {push(),virtual_compare(), stack_pop()} {} {funsmeq.c} { Function {\em fun\_smeq()} is called when opcode {\em op\_smeq} is read. This function pops two variables, calls {\em compare()} to compare the values, and pushes the result of the comparison. The two compared variables are discarded. } */ #include "opcodefun.ih" void o_smeq () { o_neq(); int_assignInt(stack_top(), int_value(stack_top()) <= 0); } icmake-9.02.06/exec/opcodefun/setinfile.c0000644000175000017500000000035313176557635017164 0ustar frankfrank#include "opcodefun.ih" void opcodefun_setInfile(char const *arg) { if (!(go_infile = fopen(arg, "r"))) rss_fatal(0, 0, "cannot read bimfile '%s'", arg); go_header = rss_readHeader(go_infile, (unsigned)version[0]); } icmake-9.02.06/exec/opcodefun/osub.c0000644000175000017500000000133013176557635016146 0ustar frankfrank/* Function {\em fun\_sub()} processes opcode {\em op\_sub}. Two variables are popped and subtracted. Depending on their type, two integer values are subtracted or a difference between two lists is computed. The result of the subtraction is stored in a temporary variable, which is then pushed. The two popped variables are discarded after use. */ #include "opcodefun.ih" void o_sub() { Variable rval; copycons(&rval, stack_top()); /* make a copy */ stack_pop(); /* remove the r-operand */ virtual_sub(stack_top(), &rval); /* subtract the rval to the top */ destructor(&rval); /* remove the local var */ } icmake-9.02.06/exec/opcodefun/frame0000644000175000017500000000004513176557635016051 0ustar frankfrank#include "opcodefun.ih" void o_ { } icmake-9.02.06/exec/opcodefun/opopreg.c0000644000175000017500000000032513176557635016654 0ustar frankfrank/* The last pushed value is popped into the return register. This action is usually taken when a function is about to return a value. */ #include "opcodefun.ih" void o_popReg() { builtin_popReg(); } icmake-9.02.06/exec/opcodefun/oneq.c0000644000175000017500000000066313176557635016150 0ustar frankfrank/* Function {\em fun\_neq()} is called when opcode {\em op\_neq} is read. This function pops two variables, calls {\em compare()} to compare the values, and pushes the result of the comparison. The two compared variables are discarded. */ #include "opcodefun.ih" void o_neq() { Variable rval; copycons(&rval, stack_top()); stack_pop(); virtual_compare(stack_top(), &rval); destructor(&rval); } icmake-9.02.06/exec/opcodefun/odec.c0000644000175000017500000000066713176557635016124 0ustar frankfrank/* \funcref{fun\_dec}{void fun\_dec ()} {} {} {} {fun\_inc()} {fundec.c} { This function decrements the {\em intValue} field of a variable. The The number of the variable (a 16-bits unsigned number) is assumed to follow the {\em op\_dec} opcode. } */ #include "opcodefun.ih" void o_dec () { register Variable *dest = o_getDest(); int_assignInt(dest, int_value(dest) - 1); } icmake-9.02.06/exec/opcodefun/opushimm.c0000644000175000017500000000070013176557635017037 0ustar frankfrank/* This function is called when an immediate value is to be pushed. The value (type {\em int16_t}) is expected to follow the opcode. A variable of type {\em e\_int}, with its {\em intValue} field set to the value retrieved from the binary makefile, is pushed. */ #include "opcodefun.ih" void o_push_imm() { IntVariable tmp; intcons_int(&tmp, rss_getInt16(go_infile)); stack_push(&tmp); intDestructor(&tmp); } icmake-9.02.06/exec/opcodefun/ojmpfalse.c0000644000175000017500000000126213176557635017162 0ustar frankfrank/* \funcref{fun\_jmp\_false}{void fun\_jmp\_false ()} {} {} {rss_getInt16(), o_isTrue()} {fun\_jmp\_true(), fun\_jmp()} {funjmpf.c} { This function is executed when an {\em op\_jmp\_false} opcode is read in the binary makefile. Following the opcode, an {\em int16_t} offset is expected. The result of a previous expression is popped and if this yields zero, a jump is made relative to the current offset by repositioning the file pointer. } */ #include "opcodefun.ih" void o_jmpFalse() { register int16_t offs = rss_getInt16(go_infile); if (!o_isTrue()) fseek (go_infile, (int32_t) offs, SEEK_CUR); } icmake-9.02.06/exec/opcodefun/oeq.c0000644000175000017500000000126413176557635015770 0ustar frankfrank/* \funcref{fun\_eq}{void fun\_eq ()} {} {} {push(),virtual_compare(), stack_pop()} {} {funeq.c} { Function {\em fun\_eq()} is called when opcode {\em op\_eq} is read. This function pops two variables, calls {\em compare()} to compare the values, and pushes the result of the comparison. The two compared variables are discarded. The result of the comparison is logically {\em not}-ted when two integers are beging compared, since {\em compare()} subtracts two integer values as result. } */ #include "opcodefun.ih" void o_eq () { o_neq(); int_assignInt(stack_top(), !int_value(stack_top())); } icmake-9.02.06/exec/opcodefun/oadd.c0000644000175000017500000000130613176557635016110 0ustar frankfrank/* Function {\em fun\_add()} processes opcode {\em op\_add}. Two variables are popped and added. Depending on their type, two integer values are added, two strings are concatenated, or two lists are merged. The result of the addition is stored in a temporary variable, which is then pushed. The two popped variables are discarded after use. */ #include "opcodefun.ih" void o_add() { Variable rval; copycons(&rval, stack_top()); /* make a copy */ stack_pop(); /* remove the r-operand */ virtual_add(stack_top(), &rval); /* add the rval to the top */ destructor(&rval); /* remove the local var */ } icmake-9.02.06/exec/opcodefun/opcodefun.h0000644000175000017500000000036613176557635017175 0ustar frankfrank#ifndef _INCLUDED_OPCODEFUN_H_ #define _INCLUDED_OPCODEFUN_H_ #include "../../rss/rss.h" int opcodefun_process(void); void opcodefun_setGlobalVariables(); void opcodefun_setInfile(char const *arg); void opcodefun_close(); #endif icmake-9.02.06/exec/opcodefun/ogr.c0000644000175000017500000000100013176557635015757 0ustar frankfrank/* \funcref{fun\_gr}{void fun\_gr ()} {} {} {push(),virtual_compare(), stack_pop()} {} {fungr.c} { Function {\em fun\_gr()} is called when opcode {\em op\_gr} is read. This function pops two variables, calls {\em compare()} to compare the values, and pushes the result of the comparison. The two compared variables are discarded. } */ #include "opcodefun.ih" void o_gr () { o_neq(); int_assignInt(stack_top(), int_value(stack_top()) > 0); } icmake-9.02.06/icmake/0000755000175000017500000000000013232311417013333 5ustar frankfrankicmake-9.02.06/icmake/execute.c0000644000175000017500000000127413176557635015172 0ustar frankfrank#define msg #include "icmake.ih" void execute(char **argv) { if (!(flags & f_doExec)) /* no exec is requested: leave */ return; if (execArgIdx == 0) /* icm-exec only receives arguemtns if */ *argv = 0; /* execArgIdx refers to the first one */ *--argv = bimFile; /* set the bim-file to use */ if (flags & f_rmBim) { *--argv = "-t"; /* set -t flag for icm-exec */ flags &= ~f_rmBim; /* icmake itself doesn't remove bim */ } *--argv = icm_exec; /* icm-exec is called */ execvp(*argv, (char *const *)argv); rss_spawnErr(icm_exec); } icmake-9.02.06/icmake/about.c0000644000175000017500000000261113176557635014636 0ustar frankfrank/* A B O U T . C */ #include "icmake.ih" void about(char const *program) { rss_copyright(program); printf("%s%s", "ICMAKE consists of a set of five programs. Together, they can\n" "be used for managing program development comparable to, e.g.,\n" "the UNIX make facility, or as a SHELL-script language.\n" "\n" "Icmake was developed using the C programming language by " "Karel Kubat\n" "and Frank Brokken.\n" "\n" "ICMAKE is available for several UNIX-platforms.\n" "\n", "ICMAKE's home page is:\n" " http://fbb-git.github.io/icmake/\n" "Also, ICMAKE is included in the Debian Linux distribution\n" "\n" "Questions, remarks, etc. about ICMAKE can be sent to:\n" "\n" " Frank B. Brokken,\n" "phone: (+31) 50 363 9281\n" "e-mail: f.b.brokken@rug.nl\n" "surface mail: Center of Information Technology, " "University of Groningen\n" " P.O. Box 11044, 9700 CA Groningen, " "the Netherlands" "\n"); exit(0); } icmake-9.02.06/icmake/inspectflags.c0000644000175000017500000000103213176557635016202 0ustar frankfrank#define msgx #include "icmake.ih" void inspectFlags(char const *program, char **argv) { if (flags & f_showFlags) showFlags(argv); if (flags & f_about) /* -a specified: about info */ about(program); int test = flags & f_commandMask; /* select all command-flags */ if ((test & (test - 1))) /* not a power of 2 -> multiple options */ rss_fatal(0, 0, "multiple action-options are not supported"); if (flags == 0 || flags == f_force) noOptions(argv); } icmake-9.02.06/icmake/icmdep.c0000644000175000017500000000023113176557635014761 0ustar frankfrank#define msg #include "icmake.ih" void icmDep(char **argv) { *argv = icm_pre; execvp(*argv, (char *const *)argv); rss_spawnErr(icm_pre); } icmake-9.02.06/icmake/preprocess.c0000644000175000017500000000105313176557635015710 0ustar frankfrank#define msg #include "icmake.ih" void preProcess() { if (!(flags & f_doPreProcess)) /* no preprocessing requested: leave */ return; int ret = spawnlp(WAIT, icm_pp, icm_pp, imFile, pimFile, NULL); if (ret) { flags |= f_rmPim; /* remove the pim file if preprocessing failed */ if (ret == -1) /* return valu -1 means: icm-pp wasn't */ rss_spawnErr(icm_pp); /* run */ exit(1); } } icmake-9.02.06/icmake/usage.c0000644000175000017500000000737113176557635014640 0ustar frankfrank#include "icmake.ih" void usage(char const *program) { rss_copyright(program); printf ( "%s%s%s%s%s%s%s%s%s%s%s", "Usage: ", program, " [options] source [dest] [-- [args]]\n" "where:\n" " options: optional arguments:\n" " --about (-a) : information about ", program, "\n" " --compile (-c) : the destination file is compiled (even if " "it's\n" " up-to-date)\n" " --directory (-T) : the directory name following -T is used " "for icmake's\n" " temporary files. By default /tmp is used or the " "HOME\n" " directory if /tmp is not writable. When used, -T is\n" " usually specified as icmake's first option\n" " --execute (-e) : execute the .bim file, which is provided " "as `source'\n" " (remaining arguments are passed as-is to the .bim\n" " file)\n" " --force (-f) : the icmake source file is recompiled " "(even if the\n" " .bim file is up-to-date) either when no other " "options\n" " are specified, or when specified in combination " "with options\n" " --source and --tmpbin\n" " --help (-h) : provide this help and end ", program, "\n" " --icm-dep (-d) : call icm-dep, passing it any remaining " "arguments\n" " --preprocess (-p): only the preprocessor is activated\n" " --source (-i) : the first argument is the icmake source " "file to\n" " process (default extension: .im), the default\n" " .bim-filename is used and the .bim file is kept;\n" " remaining arguments are passed to icm-exec\n" " --summary (-F) : show filenames, flags, and actions to " "perform\n" " --tmpbin (-t) : the filename following -t is the name of " "the compiled\n" " .bim-file (removed on exit). The first argument is " "the\n" " icmake source file to process (using default " "extension\n" " .im). Remaining arguments are passed as-is to " "icm-exec\n" " -v : display ", program, "'s version number and end ", program, "\n" "\n" " source: icmake source file to process (default extension: .im,\n" " with -b the default extension is .bim)\n" " dest: generated binary icmake file (default: source.bim)\n" " (ignored with -t and -b)\n" " -- : separator separating icmake's arguments from icm-exec's\n" " arguments\n" " args: arguments passed to icm-exec\n" "\n" ); exit(0); } icmake-9.02.06/icmake/compile.c0000644000175000017500000000062313176557635015155 0ustar frankfrank#define msg #include "icmake.ih" void compile() { if (!(flags & f_doCompile)) /* no compilation requested: leave */ return; int ret = spawnlp(WAIT, icm_comp, icm_comp, pimFile, bimFile, NULL); if (flags & f_rmPim) unlink(pimFile); if (ret) { flags |= f_rmBim; if (ret == -1) rss_spawnErr(icm_comp); exit(1); } } icmake-9.02.06/icmake/opttmpbim.c0000644000175000017500000000122013176557635015532 0ustar frankfrank#define msgx #include "icmake.ih" void optTmpBim(char **argv) { flags |= f_tmpBim | f_doPreProcess | f_doCompile | f_doExec | f_rmPim | f_rmBim; bimFile = rss_trimLeft(optarg); if (strcmp(bimFile, ".") == 0) // replace . by bimFile = rss_strjoin(tmpDir, ".bim"); // /tmpDir/`pid`.bim msg("optarg = `%s', bimfile = `%s'", optarg, bimFile); if (argv[optind] == NULL) rss_fatal(0, 0, "icmake-script filename missing after `-t bimFile'"); imFile = accessFile(argv[optind], "im"); pimFile = rss_strjoin(tmpDir, ".pim"); execArgIdx = optind + 1; } icmake-9.02.06/icmake/optcompile.c0000644000175000017500000000042113176557635015674 0ustar frankfrank#define msg #include "icmake.ih" void optCompile(char **argv) { flags |= f_doPreProcess | f_rmPim | f_doCompile | f_compile; imFile = accessFile(optarg, "im"); pimFile = rss_strjoin(tmpDir, ".pim"); bimFile = useFile(argv[optind], optarg, "bim"); } icmake-9.02.06/icmake/options.c0000644000175000017500000000463113176557635015223 0ustar frankfrank#define msg #include "icmake.ih" static struct option longOpts[] = { {"about", no_argument, NULL, 'a'}, {"compile", required_argument, NULL, 'c'}, {"execute", required_argument, NULL, 'e'}, {"icm-dep", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {"preprocess", required_argument, NULL, 'p'}, {"source", required_argument, NULL, 'i'}, {"summary", no_argument, NULL, 'F'}, {"version", no_argument, NULL, 'v'}, {NULL} }; /* process all std options or perform -h and -a actions see README.options for an overview of actions */ void options(int argc, char **argv) { char const *program = rss_programName(argv[0]); if (argc == 1) usage(program); execArgIdx = dashesIndex(argv, argv + argc); /* beyond -- */ setTmpDir(); int ready = 0; while (!ready) { int c = getopt_long(argc, argv, "ac:de:fFhi:p:qt:T:v", longOpts, NULL); switch (c) { case 'a': flags |= f_about; break; case 'c': optCompile(argv); break; case 'd': flags |= f_doIcmDep; return; case 'e': optExecute(); ready = 1; break; case 'h': usage(program); case 'f': flags |= f_force; break; case 'F': flags |= f_showFlags; break; case 'i': optIm(argv); ready = 1; break; case 'T': optTmpDir(); break; case 't': optTmpBim(argv); ready = 1; break; case 'p': optPreProcess(argv); break; case 'q': /* ignored, but kept to prevent breaking existing scripts */ break; case 'v': printf("%s V%s\n", program, version); exit(0); case -1: ready = 1; break; case '?': rss_fatal(0, 0, "option -%c not supported", optopt); } /* switch */ } /* while */ inspectFlags(program, argv); } icmake-9.02.06/icmake/nooptions.c0000644000175000017500000000100713176557635015552 0ustar frankfrank/* #define msg */ #include "icmake.ih" void noOptions(char **argv) { msg("starting"); flags |= f_doPreProcess | f_rmPim | f_doCompile | f_doExec; if (optind == execArgIdx) rss_fatal(0, 0, "first argument must be icmake-script"); imFile = accessFile(argv[optind], "im"); pimFile = rss_changeExt(imFile, "pim"); bimFile = execArgIdx > optind + 1 ? rss_strdup(argv[optind + 1]) : rss_changeExt(imFile, "bim"); testCompile(); } icmake-9.02.06/icmake/spawnlp.c0000644000175000017500000000100513176557635015204 0ustar frankfrank#include "icmake.ih" int spawnlp(int mode, char const *prog, char const *av0, ...) { va_list marker; register char *nextarg; char buf[MAX_PATHLEN * 4]; strcpy(buf, prog); va_start(marker, av0); nextarg = va_arg (marker, char*); while (nextarg) { strcat(buf, " "); strcat(buf, nextarg); nextarg = va_arg(marker, char*); } return system(buf); } #ifdef DEBUG int main () { _spawnlp (0, "ls", "ls", "*.c", "*.h", NULL); return (0); } #endif icmake-9.02.06/icmake/settmpdir.c0000644000175000017500000000136513176557635015544 0ustar frankfrank#include "icmake.ih" void setTmpDir() { struct stat buf; char pidStr[20]; snprintf(pidStr, 20, "%u", getpid()); tmpDir = rss_strcat( rss_strjoin( stat("/tmp", &buf) == 0 /* /tmp exists */ && S_ISDIR(buf.st_mode) /* and it's a directory */ && (buf.st_mode & S_IRWXO) == S_IRWXO /* and rwx mode */ ? "/tmp" : getenv("HOME"), "/" /* trailing / */ ), pidStr /* pid as initial filename */ ); } icmake-9.02.06/icmake/README.options0000644000175000017500000000541613176557635015740 0ustar frankfranka: optarg i: optidx v: argv e: execArgIdx ------------------------------------------------------------------------------------------- test- exec- compile preProc. rmPim comp. rmBim execute ArgIdx imfile pimfile bimfile -------------------------------------------------------------------------------------- -c - 1 1 1 0 0 - a[.im] a.pim v[1] || a.bim -------------------------------------------------------------------------------------- -e - 0 0 0 0 1 i - - a[.bim] -------------------------------------------------------------------------------------- -i 0 0 0 0 0 1 i - - a.bim 1 1 1 1 0 1 i a[.im] a.pim a.bim -------------------------------------------------------------------------------------- -p - 1 0 0 0 0 - a[.im] v[i] - || a.pim -------------------------------------------------------------------------------------- -t 0 0 0 0 0 1 i+1 v[i][.im] - a[.bim] 1 1 1 1 0 1 i v[i][.im] a.pim a[.bim] -------------------------------------------------------------------------------------- none 0 0 0 0 0 1 - v[i][.im] - v[i+1][.bim] || v[i].bim 1 1 1 1 0 1 - v[i][.im] v[i].pim v[i+1][.bim] || v[i].bim (if i + 1 == e then v[i].bim is used) -------------------------------------------------------------------------------------- test- exec- compile preProc. rmPim comp. rmBim execute ArgIdx imfile pimfile bimfile -------------------------------------------------------------------------------------- icmake-9.02.06/icmake/usefile.c0000644000175000017500000000037313176557635015163 0ustar frankfrank#define msg #include "icmake.ih" char *useFile(char const *firstChoice, char const *fallback, char const *ext) { return firstChoice != NULL ? rss_strdup(firstChoice) : rss_changeExt(fallback, ext); } icmake-9.02.06/icmake/icm_bootstrap0000755000175000017500000000041413176557635016152 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/${BINDIR}/icmake echo -n . try ${CC} ${CFLAGS} -o ../tmp/${BINDIR}/icmake *.c ../tmp/libicrss.a \ ${LDFLAGS} echo . icmake-9.02.06/icmake/optexecute.c0000644000175000017500000000033313176557635015710 0ustar frankfrank#define msgx #include "icmake.ih" void optExecute() { flags |= f_icmexec | f_doExec; bimFile = accessFile(optarg, "bim"); msg("optarg: %s, bimFile: %s", optarg, bimFile); execArgIdx = optind; } icmake-9.02.06/icmake/accessfile.c0000644000175000017500000000122113176557635015621 0ustar frankfrank/* return allocated string containing either `file' or `file.ext' If file exists, file is returned; otherwise if file.ext exists it is returned, otherwise an error is written and execution stops. */ #include "icmake.ih" char *accessFile(char const *file, char const *ext) { char *ret; if (access(file, R_OK) == 0) /* File exists as-is ? */ return rss_strdup(file); /* return it */ ret = rss_changeExt(file, ext); /* file.ext */ if (access(ret, R_OK) != 0) /* File.ext doesn't exist */ rss_fatal(0, 0, "can't read `%s' or `%s'", file, ret); return ret; } icmake-9.02.06/icmake/opttmpdir.c0000644000175000017500000000052113176557635015544 0ustar frankfrank#define msgx #include "icmake.ih" void optTmpDir() { free(tmpDir); tmpDir = rss_strdup(optarg); if (tmpDir[strlen(tmpDir) - 1] != '/') /* tmpDir must end in / */ tmpDir = rss_strcat(tmpDir, "/"); char pidStr[20]; snprintf(pidStr, 20, "%u", getpid()); tmpDir = rss_strcat(tmpDir, pidStr); } icmake-9.02.06/icmake/optpreprocess.c0000644000175000017500000000032413176557635016433 0ustar frankfrank#define msg #include "icmake.ih" void optPreProcess(char **argv) { flags |= f_preProcess | f_doPreProcess; imFile = accessFile(optarg, "im"); pimFile = useFile(argv[optind], imFile, "pim"); } icmake-9.02.06/icmake/icmake.ih0000644000175000017500000000535713176557635015145 0ustar frankfrank#include "../rss/rss.h" #include #include #include #include #include #include #include #include #include "../tmp/INSTALL.im" #ifdef SUN #include #endif typedef enum { f_preProcess = (1 << 0), /* command-line action options */ f_compile = (1 << 1), f_icmexec = (1 << 2), f_im = (1 << 3), f_tmpBim = (1 << 4), /* selects all command-line actions */ f_commandMask = ((1 << 6) - 1), f_about = (1 << 6), /* command-line info requests */ f_help = (1 << 7), f_rmBim = (1 << 8), /* removal flags */ f_rmPim = (1 << 9), f_doPreProcess = (1 << 10), /* action flags */ f_doCompile = (1 << 11), f_doExec = (1 << 12), f_doIcmDep = (1 << 13), f_force = (1 << 14), f_showFlags = (1 << 15) } FLAGS_; extern char icm_pre[]; extern char icm_comp[]; extern char icm_exec[]; extern char icm_pp[]; extern char *tmpDir; extern char *imFile; extern char *pimFile; extern char *bimFile; extern FILE *fdest; extern FLAGS_ flags; extern unsigned execArgIdx; void noOptions(char **argv); unsigned dashesIndex(char **begin, char **end); void optCompile(char **argv); void optExecute(); void optIm(char **argv); void optPreProcess(char **argv); void optTmpBim(char **argv); void optTmpDir(void); void options(int argc, char **argv); void cleanup(void); /* cleanup temp. info */ void usage(char const *progname); void about(char const *program); /* about icmake */ void execute(char **argv); void preProcess(void); void compile(void); void icmDep(char **argv); char *accessFile(char const *file, char const *ext); /* returns copy of file or file.ext, or error if neither exists */ /* if existing, use firstChoice, else use fallback, using the specified extension */ char *useFile(char const *firstChoice, char const *fallback, char const *ext); void testCompile(void); int spawnlp(int mode, char const *prog, char const *av0, ...); void inspectFlags(char const *program, char **argv); void setTmpDir(void); void showFlags(char **argv); // int optChars(char const *program, char const *options, char **argv); //void stdFiles(char **argv); /* also calls testCompile */ //void optDashSeparator(char **argv); icmake-9.02.06/icmake/data.c0000644000175000017500000000044413176557635014437 0ustar frankfrank#include "icmake.ih" char icm_pre[] = LIBDIR "/icm-dep"; char icm_comp[] = LIBDIR "/icm-comp"; char icm_exec[] = LIBDIR "/icm-exec"; char icm_pp[] = LIBDIR "/icm-pp"; char *tmpDir; char *imFile; char *pimFile; char *bimFile; FILE *fdest; FLAGS_ flags; unsigned execArgIdx; icmake-9.02.06/icmake/optim.c0000644000175000017500000000056013176557635014655 0ustar frankfrank#define msg #include "icmake.ih" void optIm(char **argv) { flags |= f_im | f_doPreProcess | f_rmPim | f_doCompile | f_doExec; imFile = accessFile(optarg, "im"); pimFile = rss_strjoin(tmpDir, "pim"); bimFile = rss_changeExt(imFile, "bim"); testCompile(); /* may wipe f_doPreProcess | f_rmPim | f_doCompile */ execArgIdx = optind; } icmake-9.02.06/icmake/cleanup.c0000644000175000017500000000026713176557635015160 0ustar frankfrank#include "icmake.ih" void cleanup() { fflush(stdout); fflush(stderr); if (flags & f_rmPim) unlink(pimFile); if (flags & f_rmBim) unlink(bimFile); } icmake-9.02.06/icmake/testcompile.c0000644000175000017500000000226213176557635016056 0ustar frankfrank#define msg #include "icmake.ih" void testCompile() { char buffer[MAX_PATHLEN]; BinHeader hdr; /* forced compilation or no bimfile yet */ /* then compilation is required */ if (flags & f_force || !rss_exists(bimFile)) return; if (!(fdest = fopen(bimFile, "rb"))) /* bimfile exists: open it */ rss_fatal(0, 0, "Can't read `%s'", bimFile); if (rss_younger(imFile, bimFile)) /* old bim-file: compilation needed */ return; /* also check files used for .bim */ hdr = *rss_readHeader(fdest, (unsigned)version[0]); fseek(fdest, hdr.offset[2], SEEK_SET); /* go to filenames area */ while (fgets(buffer, MAX_PATHLEN, fdest)) /* read the next filename */ { buffer[strlen(buffer) - 1] = 0; /* remove \n */ if (rss_younger(buffer, bimFile)) /* a source name is younger */ return; /* so recompilation needed */ } /* no compilation needed */ flags &= ~(f_doPreProcess | f_rmPim | f_doCompile | f_rmBim); } icmake-9.02.06/icmake/icmconf0000644000175000017500000000073313176557635014724 0ustar frankfrank#define USE_ECHO ON #define MAIN "main.c" #define COMPILER "gcc" #define COMPILER_OPTIONS "-Wall -O2 -fdiagnostics-color=never" #define SOURCES "*.c" #define LINKER_OPTIONS "-s" #define ADD_LIBRARIES "icrss" #define ADD_LIBRARY_PATHS "../../tmp" #define REFRESH #define CLS #define TMP_DIR "tmp" #define LIBRARY "modules" #define OBJ_EXT ".o" #define DEFCOM "program" icmake-9.02.06/icmake/dashesindex.c0000644000175000017500000000035513176557635016026 0ustar frankfrank#include "icmake.ih" unsigned dashesIndex(char **begin, char **end) { char **start = begin; for (; begin != end; ++begin) { if (strcmp(*begin, "--") == 0) return 1 + begin - start; } return 0; } icmake-9.02.06/icmake/build0000755000175000017500000000003113176557635014377 0ustar frankfrank#!/bin/bash icmbuild $1 icmake-9.02.06/icmake/showflags.c0000644000175000017500000000163113176557635015522 0ustar frankfrank#include "icmake.ih" void showFlags(char **argv) { printf( "first icm-exec Arg Idx = %u: %s\n" "flags: 0x%x\n" "do preprocess: %d\n" "do compile: %d\n" "do exec: %d\n" "remove pim: %d\n" "remove bim: %d\n" "force compile: %d\n" "imfile: %s\n" "pimfile: %s\n" "bimfile: %s\n" "tmp. prefix: %s\n", execArgIdx, argv[execArgIdx], flags, (flags & f_doPreProcess) != 0, (flags & f_doCompile) != 0, (flags & f_doExec) != 0, (flags & f_rmPim) != 0, (flags & f_rmBim) != 0, (flags & f_force) != 0, imFile ? imFile : "--", pimFile ? pimFile : "--", bimFile ? bimFile : "--", tmpDir ); } icmake-9.02.06/icmake/setlinks0000755000175000017500000000020513176557635015137 0ustar frankfrank#!/bin/bash cd tmp/bin || exit 1 for x in icm-exec icm-comp icm-pp icmun do ln -s ../../../$x/tmp/bin/binary $x || exit 1 done icmake-9.02.06/icmake/main.c0000644000175000017500000000111613176557635014447 0ustar frankfrank /* #define msg */ #include "icmake.ih" /* icmake source(txt) dest(bin) */ int main(int argc, char **argv) { options(argc, argv); if (flags & f_doIcmDep) icmDep(argv + optind - 1); atexit(cleanup); if (flags & f_icmexec) /* direct execute the bim-file */ execute(argv + execArgIdx); /* ends icmake */ preProcess(); compile(); /* f_compile ends icmake */ execute(argv + execArgIdx); /* ends icmake */ } icmake-9.02.06/icm_bootstrap0000755000175000017500000000266313176557635014731 0ustar frankfrank#!/bin/bash if [ "$#" == "0" ] ; then echo " Usage: icm_bootstrap Parser and scanner files generated by bison and flex must already be available (which is true for the standard distribution) Before calling this script icm_prepare must have been called. " exit 0 fi if [ ! -e tmp/INSTALL.sh ] ; then echo tmp/INSTALL.sh does not exist. Try running the icm_prepare script exit 1 fi . bootstrap/functions . tmp/INSTALL.sh # build icmake and its support programs for target in rss icmake un pp comp exec dep icmbuild do cd $target ./icm_bootstrap cd .. done echo ./scripts to ./tmp cp scripts/icmbuild.in scripts/icmstart.in tmp/ echo skeleton files to tmp/${SKELDIR} try cp -r usr/share/icmake/* tmp/${SKELDIR} echo configuration files to tmp/${CONFDIR} try cp -r etc/icmake/* tmp/${CONFDIR} cd doc echo man-pages to tmp/${MANDIR}/man1 and .../man7 for x in *.1 ; do gzip -9cn $x > ../tmp/${MANDIR}/man1/$x.gz || exit 1 done for x in *.7 ; do gzip -9cn $x > ../tmp/${MANDIR}/man7/$x.gz || exit 1 done echo documentation to tmp/${DOCDIR} and tmp/${DOCDOCDIR} for x in icmake.doc icmake.ps README.icmbuild ; do gzip -9cn $x > ../tmp/${DOCDOCDIR}/$x.gz || exit 1 done cd .. gzip -9cn changelog > tmp/${DOCDIR}/changelog.gz || exit 1 try cp -r examples tmp/${DOCDOCDIR} echo ./etc files to tmp/etc/ try cp -r etc tmp/ echo Done. icmake-9.02.06/icmbuild/0000755000175000017500000000000013232311417013672 5ustar frankfrankicmake-9.02.06/icmbuild/usage.c0000644000175000017500000000502313176557635015167 0ustar frankfrank#include "icmbuild.ih" int usage() { rss_copyright("icmbuild"); printf("Usage: icmbuild [-h] [-c] args\n" " -h - Disply this help-information (ends " "`icmbuild')\n" " (this help is also shown if the file " "`icmconf',\n" " required by `icmbuild', does not exist in the " "current\n" " working directory)\n" " -c - Do 'tput clear' (clear screen) just before\n" " processing 'args'\n" "\n" " args - select from:\n" " clean - clean up remnants of previous activities\n" "\n" "(library construction:)\n" " library - build a static library (using icmconf's" " defines\n" " `TMP_DIR' and `LIBRARY')\n" " optionally (when `SHARED' is defined in " "`icmconf')\n" " `icmbuild' also build a shared library\n" " strip-shared - strip a shared library (requires `SHARED' " "in\n" " `icmconf')\n" " install static - install the static library in " "directory \n" " (may start with ~)\n" " install shared - install the shared library in " "directory \n" " (may start with ~)\n" "\n" "(program construction)\n" " program - build a program (using icmconf's " "define `TMP_DIR')\n" " program strip - build stripped TMP_DIR/bin/binary\n" " install program path - install the binary program at " "`path'\n" " (provide the full path-name (may start " "with ~)\n" ); return 0; } icmake-9.02.06/icmbuild/icm_bootstrap0000755000175000017500000000042013176557635016506 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/${BINDIR}/icmbuild echo -n . try ${CC} ${CFLAGS} -o ../tmp/${BINDIR}/icmbuild *.c ../tmp/libicrss.a \ ${LDFLAGS} echo . icmake-9.02.06/icmbuild/icmbuild.ih0000644000175000017500000000046613176557635016037 0ustar frankfrank#include "../rss/rss.h" #include #include #include "../tmp/INSTALL.im" // #include // #include // #include // #include // #include // #include // // // #ifdef SUN // #include // #endif int usage(); icmake-9.02.06/icmbuild/icmconf0000644000175000017500000000074313176557635015264 0ustar frankfrank#define USE_ECHO ON #define MAIN "main.c" #define COMPILER "gcc" #define COMPILER_OPTIONS "-Wall -O2 -fdiagnostics-color=never" #define SOURCES "*.c" #define LINKER_OPTIONS "-s" #define ADD_LIBRARIES "icrss" #define ADD_LIBRARY_PATHS "../../tmp" #define REFRESH #define CLS #define TMP_DIR "tmp" #define LIBRARY "modules" #define OBJ_EXT ".o" #define DEFCOM "program" icmake-9.02.06/icmbuild/build0000755000175000017500000000003113176557635014736 0ustar frankfrank#!/bin/bash icmbuild $1 icmake-9.02.06/icmbuild/main.c0000644000175000017500000000120513176557635015005 0ustar frankfrank/* #define msg */ #include "icmbuild.ih" int main(int argc, char **argv) { if (!rss_exists("icmconf") || (argc > 1 && strcmp(argv[1], "-h") == 0)) return usage(); char *arg[argc + 3]; // args to call icmake on // LIBDIR/icmbuild arg[0] = "icmake"; arg[1] = "-t."; arg[2] = rss_strcat(rss_strdup(LIBDIR), "/icmbuild"); for (int argvIdx = 1, end = argc + 1; argvIdx != end; ++argvIdx) arg[argvIdx + 2] = argv[argvIdx]; execvp(arg[0], arg); // run the icmbuild script rss_spawnErr("icmbuild"); // does exit(1) } icmake-9.02.06/icm-comp/0000755000175000017500000000000012766231720013617 5ustar frankfrankicmake-9.02.06/icm-exec/0000755000175000017500000000000012766231720013605 5ustar frankfrankicmake-9.02.06/icm_github0000755000175000017500000000124613176557635014172 0ustar frankfrank#!/bin/bash echo -n "This script is for internal use only. Are you sure you want to run it [y/n] ?" read yesno [ "$yesno" == "y" ] || exit 0 . icm_prepare / cp doc/*.1 tmp/${MANDIR}/man1 cp doc/*.7 tmp/${MANDIR}/man7 cp changelog ../../wip/changelog.txt sed ' s/VERSION=\(.*\)/SUBST\(_CurVers_\)\(\1\)/ s/YEARS=\(.*\)/SUBST\(_CurYrs_\)\(\1\)/ ' VERSION > release.yo cp release.yo required ../../wip/ cd doc/manpage ln -sf ../../release.yo . for yo in ic*yo do yodl2html --no-warnings $yo done cd .. mkdir -p ../../../wip/manpages cp -r manpage/*.html ../../../wip/manpages rm -f manpage/{*.html,release.yo} cd .. rm -r tmp release.yo icmake-9.02.06/icm_install0000755000175000017500000000325613176557635014361 0ustar frankfrank#!/bin/bash usage() { echo " Usage: $0 [strip] all|progs|scripts|man|skel|doc|etc|docdoc [installdir] " exit 1 } [ -e tmp/ROOT ] || usage . scripts/conversions echo ROOT DIRECTORY: ${ROOT} if [ "$1" == "strip" ] ; then STRIP=strip shift fi if [ "$2" != "" ] ; then INSTALLDIR=$2 else INSTALLDIR=${ROOT} fi try() { # echo $* $* || exit 1 } progs() { if [ "$STRIP" == "strip" ] ; then try strip tmp/${BINDIR}/icmake tmp/${BINDIR}/icmbuild \ tmp/${LIBDIR}/* fi try mkdir -p $INSTALLDIR/${BINDIR} $INSTALLDIR/${LIBDIR} try cp tmp/${BINDIR}/icmake tmp/${BINDIR}/icmbuild \ $INSTALLDIR/${BINDIR} if [ -e $INSTALLDIR/${LIBDIR}/icm-exec ] ; then try rm $INSTALLDIR/${LIBDIR}/icm-exec fi try cp -r tmp/${LIBDIR}/* $INSTALLDIR/${LIBDIR} } scripts() { try mkdir -p $INSTALLDIR/${BINDIR} $INSTALLDIR/${LIBDIR} # script install-dest. try scripts/convert icmbuild $INSTALLDIR/$LIBDIR try scripts/convert icmstart $INSTALLDIR/$BINDIR try chmod +x $INSTALLDIR/$BINDIR/icmstart } into() { try mkdir -p $INSTALLDIR/$1 try cp -r tmp/$1/* $INSTALLDIR/$1 } case $1 in (all) progs scripts into ${MANDIR} into ${SKELDIR} into ${DOCDIR} into ${DOCDOCDIR} into ${CONFDIR} ;; (progs) progs ;; (scripts) scripts ;; (man) into ${MANDIR} ;; (skel) into ${SKELDIR} ;; (doc) into ${DOCDIR} ;; (etc) into ${CONFDIR} ;; (docdoc) into ${DOCDOCDIR} ;; (*) usage ;; esac icmake-9.02.06/icm-pp/0000755000175000017500000000000012766231720013300 5ustar frankfrankicmake-9.02.06/icm_prepare0000755000175000017500000000301313176557635014340 0ustar frankfrank#!/bin/bash if [ "$#" == "0" ] ; then echo " Usage: icm_prepare rootdir In standard situations specify / as rootdir. The physical installation dir is specified when calling icm_install, but rootdir specified here is hard-coded in icmake's programs, so eventually the icmake files should be available under rootdir. " exit 0 fi try() { # echo $* $* || exit 1 } echo Creating the intermediate destination directory ./tmp echo and removing any old files try rm -rf tmp icmake/tmp icmun/tmp/ icm-*/tmp try find -name '*.o' -exec rm -f '{}' \; try mkdir -p tmp echo Writing tmp/ROOT ROOT=`echo $1 | sed 's_/$__'` echo "ROOT=${ROOT}/" > tmp/ROOT . scripts/conversions echo " #define BINDIR \"${BINDIR}\" #define SKELDIR \"${SKELDIR}\" #define MANDIR \"${MANDIR}\" #define LIBDIR \"${LIBDIR}\" #define CONFDIR \"${CONFDIR}\" #define DOCDIR \"${DOCDIR}\" #define DOCDOCDIR \"${DOCDOCDIR}\" #define VERSION \"${VERSION}\" #define YEARS \"${YEARS}\" " > tmp/INSTALL.im echo " BINDIR=\"${BINDIR}\" SKELDIR=\"${SKELDIR}\" MANDIR=\"${MANDIR}\" LIBDIR=\"${LIBDIR}\" CONFDIR=\"${CONFDIR}\" DOCDIR=\"${DOCDIR}\" DOCDOCDIR=\"${DOCDOCDIR}\" VERSION=\"${VERSION}\" YEARS=\"${YEARS}\" " > tmp/INSTALL.sh echo Creating remaining intermediate destination directories try mkdir -p tmp/${BINDIR} tmp/${LIBDIR} tmp/${SKELDIR} \ tmp/${CONFDIR} tmp/${MANDIR}/man1 tmp/${MANDIR}/man7 \ tmp/${DOCDIR} tmp/${DOCDOCDIR} icmake-9.02.06/icmun/0000755000175000017500000000000012766231720013226 5ustar frankfrankicmake-9.02.06/INSTALL0000644000175000017500000001525713176557635013172 0ustar frankfrankINSTALLING ICMAKE ================= Version 9.02.00 (and beyond). 1. Unpack the archive: ====================== The installation files for Icmake comes as an archive, e.g., "icmake_9.02.00.tar.gz". These archives unpack to several directories and files. The archive unpacks to a directory icmake-9.02.00 below the current directory. The version number in this directory may change to newer release versions. So, if you unpack icmake_9.02.00.tar.gz (or later versions) in the directory /usr/local/src, a directory /usr/local/src/icmake/icmake-9.02.00 is created, as well as other subdirectories below /usr/local/src/icmake/icmake-9.02.00 To unpack the archives, create an appropriate directory (e.g., `/usr/local/src/icmake' E.g, tar xvzf icmake_9.02.00.tar.gz The extraction of files from the archive should yield a lot of C source files in various directories. Icmake's default distribution does not contain makefiles for the Unix-utility `make' anymore. 2. Compile the programs ======================= Change to the directory into which the sources were unpacked. E.g., do cd icmake-9.02.00 This directory should contain this file (i.e., INSTALL). Icmake uses several support programs, which do not have to be stored in the PATH diretories. Before starting the compilation, make sure their locations are in accordance with your local requirements: - Inspect (and optionally modify) the path-settings in INSTALL.im. In particular check: #define BINDIR "usr/bin" #define SKELDIR "usr/share/icmake" #define MANDIR "usr/share/man" #define LIBDIR "usr/lib/icmake" #define CONFDIR "etc/icmake" #define DOCDIR "usr/share/doc/icmake" #define DOCDOCDIR "usr/share/doc/icmake-doc" These locations are all are relative to a specifiable base-directory. Meaning: BINDIR the binary programs and scripts SKELDIR the icmstart-script skeleton files MANDIR the base directory of man-pages (under MANDIR/man1 and MANDIR/man2) LIBDIR icmake's support programs CONFDIR the system-wide configuration files (AUTHOR, VERSION, icmstart.rc) DOCDIR various doc-files (e.g., changelog) DOCDOCDIR more extensive documentation (icmake.ps, examples) - Inspect (and optionally modify) the availability of the program mentioned in ./def/programs (they should be available on any Unix(like) systems). - Prepare for the program construction by running the shell-script `icm_prepare' as follows: ./icm_prepare / (this assumes that you want to prepend all base locations mentioned in INSTALL.im with /; other base locations are also possible, e.g., ./icm_prepare /tmp prepares for installation of all files in the specified locations, all below /tmp. - Next run the shell-script `icm_bootstrap' as follows: ./icm_bootstrap x This constructs the icmake files under the ./tmp directory, preparing for an installation under the directory specified at ./icm_prepare. It puts all icmake related files in tmp/$BINDIR, tmp/$SKELDIR, tmp/$MANDIR, tmp/$LIBDIR, tmp/$CONFDIR, tmp/$DOCDIR, tmp/$DOCDOCDIR NOTE: There have been reports about failing compilations of the file ./icm-comp/lexer.c. This is usually caused by incompatibilities between the existing lexer.c file and the lex(1) run-time library. These problems are commonly solved after running in the directory ./icm-comp the command ./updatescanner 3. Install the files ==================== You probably must do this as `root': ./icm_install [strip] all This installs all files under the root directory (which was initially specied when calling icm_bootstrap) When providing the strip arguments binaries will be stripped. Note that by default unstripped binaries will be installed. Separate parts may be installed as well. E.g., ./icm_install [strip] progs / - installs all executables ./icm_install scripts / - installs the icmstart/icmbuild scripts ./icm_install man / - installs the man-pages ./icm_install skel / - installs the skeletons ./icm_install etc / - installs the default icmstart.rc related files ./icm_install doc / - installs the docs ./icm_install docdoc / - installs the extended docs and examples 4. Clean up the garbage ======================= rm -rf tmp 5. Predefined symbols ===================== Icmake does not require special modifications. However, you may wish to take a look at the file icm-pp/loadsymbols.c. In this file the function 'loadSymbols()' of the preprocessor icm-pp is found. The preloaded symbols of Icmake are defined in this function. If you plan to use these predefined symbols in your Icmake scripts, make sure that the conditional code in the file pp/loadsym.c recognizes your platform. If you are unsure whether this code recognizes your compiler, build Icmake as distributed and try out the sample icmake file examples/defines.im (i.e., say: "icmake examples/defines"). If the output of the makefile is not satisfatory, modify pp/loadsym.c. E.g., if your MegaC compiler defines the symbol MEGA_C, you might want to add the following lines to pp/loadsym.c: #ifdef MEGA_C preload("MEGA_C", "1"); #else preload("MEGA_C", "0"); #endif Currently the following symbols are predefined: -------------------------------------------------------------- symbol 1 when defined on the platform ... otherwise 0 -------------------------------------------------------------- unix Unix, usually with GNU's gcc compiler UNIX same linux '386 or '486 running Linux (usually with gcc) LINUX same M_SYSV, M_UNIX '386 or '486 running SCO/Unix (usually with Microsoft C) _POSIX_SOURCE Unix with Posix compliant compiler __hpux HP-UX, with the native HP compiler -------------------------------------------------------------- If you want to modify something here which hasn't been done before, please email me about it, and I'll include it in the standard distribution. icmake-9.02.06/INSTALL.im0000644000175000017500000000216013176557635013563 0ustar frankfrank/* The locations of the binaries, the man pages and the documentation ================================================================== The settings in this file are according to the Debian File Standard Change them according to your tastes if you think they should be different. All locations are relative to a specifiable base-directory. BINDIR the binary programs and scripts SKELDIR the icmstart-script skeleton files MANDIR the base directory of man-pages (under MANDIR/man1 and MANDIR/man2) LIBDIR icmake's support programs CONFDIR the system-wide configuration files (AUTHOR, VERSION, icmstart.rc) DOCDIR various doc-files (e.g., changelog) DOCDOCDIR more extensive documentation (icmake.ps, examples) */ #define BINDIR "usr/bin" #define SKELDIR "usr/share/icmake" #define MANDIR "usr/share/man" #define LIBDIR "usr/lib/icmake" #define CONFDIR "etc/icmake" #define DOCDIR "usr/share/doc/icmake" #define DOCDOCDIR "usr/share/doc/icmake-doc" icmake-9.02.06/iuo/0000755000175000017500000000000013176557635012723 5ustar frankfrankicmake-9.02.06/iuo/install0000755000175000017500000000052213176557635014316 0ustar frankfrank#!/bin/bash cd /usr/bin if [ -f icmake ] ; then mv icmake icmake.org ln -sf /home/frank/git/icmake/src/icmake/icmake/tmp/bin/binary icmake fi cd /usr/lib/icmake for x in icm-pp icm-comp icm-exec do if [ -f $x ] ; then mv $x $x.org ln -sf /home/frank/git/icmake/src/icmake/$x/tmp/bin/binary $x fi done icmake-9.02.06/iuo/uninstall0000755000175000017500000000033713176557635014665 0ustar frankfrank#!/bin/bash cd /usr/bin if [ -h icmake ] ; then rm icmake mv icmake.org icmake fi cd /usr/lib/icmake for x in icm-pp icm-comp icm-exec do if [ -h $x ] ; then rm $x mv $x.org $x fi done icmake-9.02.06/iuo/bootstrapinstall0000755000175000017500000000046713176557635016264 0ustar frankfrank#!/bin/bash cd /usr/bin if [ -f icmake ] ; then mv icmake icmake.org ln -sf /home/frank/src/icmake/tmp/usr/bin/icmake . fi cd /usr/lib/icmake for x in icm-pp icm-comp icm-exec do if [ -f $x ] ; then mv $x $x.org ln -sf /home/frank/src/icmake/tmp/usr/lib/icmake/$x . fi done icmake-9.02.06/legacy/0000755000175000017500000000000013176557635013373 5ustar frankfrankicmake-9.02.06/legacy/mail.frank0000644000175000017500000000236213176557635015343 0ustar frankfrankMichael Meskes Von: Frank B. Brokken [frank@suffix.icce.rug.nl] Gesendet: Dienstag, 18. November 1997 16:44 An: meskes@topsystem.de Betreff: Re: icmake copyright Dear Michael Meskes, you wrote: > Hi, > > in your copyright you say: whatever... but in our website www.icce.rug.nl/docs/software.html, we explicitly state that ALL software that we make publicly available is distributed according to the GPL, whatever the docs (still) tell you. So don't worry. It's ony a bit inconvenient that the copyright-information that is distributed with (some) of our software is still a bit incongruent with the GPL. But again: ignore that, and consider all our software free. If you have a patch and want it to be part of icmake of whatever software we distribute, go ahead! Which doesn't mean that we're not interested in receiving information about that patch :-) But I guess that goes without saying. Have a nice day, -- | ---|--- -----+--0--+----- | | Frank (al sinds enige jaren uitgedost (untranslatable)) E-mail: frank@icce.rug.nl or f.b.brokken@icce.rug.nl Fax: (+31) 50 363 6686: office hrs, (+31) 50 403 2341 otherwise. Phone: (+31) 50 363 3688: office hrs, (+31) 50 403 2223 otherwise. icmake-9.02.06/legacy/lsm.org/0000755000175000017500000000000013176557635014754 5ustar frankfrankicmake-9.02.06/legacy/lsm.org/icmakebin.lsm0000644000175000017500000000315513176557635017417 0ustar frankfrankBegin2 Title = Icmake - an Intelligent C-like Maker Version = 6.20 Desc1 = Icmake is yet another maker -- but this time, one that uses Desc2 = a C-like syntaxis. The Icmake scripts should feel `natural' to Desc3 = all C programmers. Icmake is furthermore a powerful shell script Desc4 = language: it can be used for program maintenance as well as for Desc5 = system administrative tasks. Author = Frank B. Brokken and Karel Kubat AuthorEmail = frank@icce.rug.nl and karel@icce.rug.nl Maintainer = Frank B. Brokken and Karel Kubat MaintEmail = frank@icce.rug.nl and karel@icce.rug.nl Site1 = ftp.icce.rug.nl Path1 = pub/unix File1 = icmake-6.20.bin.tgz FileSize1 = xxx Site2 = tsx-11.mit.edu Path2 = pub/linux/binaries/usr.bin File2 = icmake-6.20.bin.tgz FileSize2 = xxx Site3 = sunsite.unc.edu Path3 = pub/Linux/devel/make File3 = icmake-6.20.bin.tgz FileSize3 = xxx Required1 = libc.4.6.27 is expected with the linux-executables. CopyPolicy1 = The Icmake package may be freely distributed, provided that CopyPolicy2 = no changes are made to the software or documentation. Keywords = icmake make C Comment1 = The package contains the following documentation: Comment2 = icmake.doc and INSTALLBIN - installation guide. READ ! Comment3 = doc/icmake.ps - 300dpi LaserJet documentation, gs-printable Comment4 = doc/icmake.1 - simple man page RelFiles1 = icmake-6.20.tgz: Sources found at the sites. Entered = 10MAY1995 EnteredBy = Frank Brokken CheckedEmail = frank@icce.rug.nl End icmake-9.02.06/legacy/lsm.org/icmake.lsm0000644000175000017500000000346613176557635016733 0ustar frankfrankBegin2 Title = Icmake - an Intelligent C-like Maker Version = 6.20 Desc1 = Icmake is yet another maker -- but this time, one that uses Desc2 = a C-like syntaxis. The Icmake scripts should feel `natural' to Desc3 = all C programmers. Icmake is furthermore a powerful shell script Desc4 = language: it can be used for program maintenance as well as for Desc5 = system administrative tasks. Author = Frank B. Brokken and Karel Kubat AuthorEmail = frank@icce.rug.nl and karel@icce.rug.nl Maintainer = Frank B. Brokken and Karel Kubat MaintEmail = frank@icce.rug.nl and karel@icce.rug.nl Site1 = ftp.icce.rug.nl Path1 = pub/unix File1 = icmake-6.20.tgz FileSize1 = xxx Site2 = tsx-11.mit.edu Path2 = pub/linux/sources/usr.bin File2 = icmake-6.20.tgz FileSize2 = xxx Site3 = sunsite.unc.edu Path3 = pub/Linux/devel/make File3 = icmake-6.20.tgz FileSize3 = xxx Required1 = No special hardware or software is required, except for Required2 = a C compiler. GNU's gcc 2.6.2. will do nicely. Furthermore, Required3 = libc.4.6.27 is expected with the linux-executables. CopyPolicy1 = The Icmake package may be freely distributed, provided that CopyPolicy2 = no changes are made to the software or documentation. Keywords = icmake make C Comment1 = The package contains the following documentation: Comment2 = icmake.doc and INSTALL - installation guide Comment3 = doc/icmake.ps - 300dpi LaserJet documentation, gs-printable Comment4 = doc/icmake.1 - simple man page RelFiles1 = icmake.doc, icmake-6.20.bin.tgz (containing binaries): Found RelFiles2 = at the sites. Read icmake.doc before installing Entered = 10MAY1995 EnteredBy = Frank Brokken CheckedEmail = frank@icce.rug.nl End icmake-9.02.06/legacy/dos-msc.im0000644000175000017500000001531013176557635015267 0ustar frankfrank// These two defines are the C compiler and the flags. -c is needed to // ensure compilation-only; -O is selected to turn debugging off. #define CC "cl" #define CFLAGS "-c -W3 -O -AS" // The following two macros are the library manager. That program // is started as "AR ARFLAGS library-name object-files". #define AR "lib" // A remove program.. #define RM "del" // The destination directory to copy executables to, and your install // program ("cp" for a poor man's solution). #define BINDIR "c:\\sys\\ec" #define CP "copy" // You've edited enough now. Try making it. #define LIB_ICRSS "icrss.lib" #define LIB_ICMAKE "icmake.lib" #define LIB_ICMPP "icmpp.lib" #define LIB_ICMCOMP "icmcomp.lib" #define LIB_ICMEXEC "icmexec.lib" #define LIB_ICMUN "icmun.lib" #define ZIP "icmake.zip" list loadass (string dir, string lib) { int i; string ofile; list ofiles; chdir (dir); printf ("Checking asm/*.obj files against library ", lib, "\n"); ofiles = makelist ("asm\\*.obj"); // list of obj files for (i = 0; i < sizeof (ofiles); i++) { ofile = element (i, ofiles); if (ofile older lib) { ofiles -= (list) ofile; i--; } } chdir (".."); return (ofiles); } void makelib (string dir, string lib, string mainobj, list extraobj) { list cfiles, ofiles; string ofile, cfile; int i; chdir (dir); mainobj = rss_changeExt (mainobj, ".obj"); printf ("Checking .c files against library ", lib, "\n"); cfiles = makelist ("*.c"); for (i = 0; i < sizeof (cfiles); i++) { cfile = element (i, cfiles); ofile = rss_changeExt (cfile, ".obj"); if (cfile older lib || (exists (ofile) && ofile younger cfile) ) { cfiles -= (list) cfile; i--; } } if (cfiles) execute (CC, CFLAGS, "", cfiles, "", ""); printf ("Checking .obj files against library ", lib, "\n"); ofiles = makelist ("*.obj") - (list) mainobj; if (ofiles) { execute (AR, lib, "-+", ofiles, "", ";"); for (i = 0; i < sizeof (ofiles); i++) system (RM + " " + element (i, ofiles)); } if (extraobj) execute (AR, lib, "-+", extraobj, "", ";"); system (RM + " " + rss_changeExt(lib, "bak")); chdir (".."); } void makelibs () { printf ("\nLoading Assembler modules in RSS Library\n"); printf ("\nMaking Run Time Support System library\n"); makelib ("rss", LIB_ICRSS, "", loadass ("rss", LIB_ICRSS)); printf ("\nMaking lib for shell program icmake\n"); makelib ("make", LIB_ICMAKE, "icmake", (list)""); printf ("\nMaking lib for preprocessor icm-pp\n"); makelib ("pp", LIB_ICMPP, "icm-pp", (list)""); printf ("\nMaking lib for compiler icm-comp\n"); makelib ("comp", LIB_ICMCOMP, "icm-comp", (list)""); printf ("\nMaking lib for executor icm-exec\n"); makelib ("exec", LIB_ICMEXEC, "icm-exec", (list)""); printf ("\nMaking lib for unassembler icmun\n"); makelib ("un", LIB_ICMUN, "icmun", (list)""); } void makeprog (string dir, string lib, string prog) { string exepacked_prog, rsslib; rsslib = "..\\rss\\icrss.lib"; exepacked_prog = "..\\bindos\\" + prog; chdir (dir); printf ("Checking prog ", exepacked_prog, " against libs ", lib, " and ", rsslib, "\n"); if (lib younger exepacked_prog || rsslib younger exepacked_prog) { exec (CC, rss_changeExt (prog, ".obj"), lib, rsslib); exec ("exepack", prog, exepacked_prog); system("del " + prog); } chdir (".."); } void makeprogs () { makelibs (); printf ("\nMaking shell program icmake\n"); makeprog ("make", LIB_ICMAKE, "icmake.exe"); printf ("\nMaking preprocessor program icm-pp\n"); makeprog ("pp", LIB_ICMPP, "icm-pp.exe"); printf ("\nMaking compiler program icm-comp\n"); makeprog ("comp", LIB_ICMCOMP, "icm-comp.exe"); printf ("\nMaking executor program icm-exec\n"); makeprog ("exec", LIB_ICMEXEC, "icm-exec.exe"); printf ("\nMaking unassembler program icmun\n"); makeprog ("un", LIB_ICMUN, "icmun.exe"); } void inst (string prog) { string dest; chdir ("bindos"); dest = BINDIR + "\\" + prog; if (prog newer dest) system (CP + " " + prog + " " + BINDIR); chdir (".."); } void install () { makeprogs (); printf ("\nInstalling shell program icmake\n"); inst ("icmake.exe"); printf ("\nInstalling preprocessor program icm-pp\n"); inst ("icm-pp.exe"); printf ("\nInstalling compiler program icm-comp\n"); inst ("icm-comp.exe"); printf ("\nInstalling executor program icm-exec\n"); inst ("icm-exec.exe"); printf ("\nInstalling unassembler program icmun\n"); inst ("icmun.exe"); } void clean (string dir, string lib, string prog) { chdir (dir); printf ("Cleaning ", dir, "\n"); lib = rss_changeExt (lib, ".bak"); if (exists (lib)) system (RM + " " + lib); if (prog && exists (prog)) system (RM + " " + prog); chdir (".."); printf (dir, ": clean.\n"); } void cleanup () { clean ("rss", LIB_ICRSS, ""); clean ("make", LIB_ICMAKE, "icmake.exe"); clean ("pp", LIB_ICMPP, "icm-pp.exe"); clean ("comp", LIB_ICMCOMP, "icm-comp.exe"); clean ("exec", LIB_ICMEXEC, "icm-exec.exe"); clean ("un", LIB_ICMUN, "icmun.exe"); } void main (int argc, list argv) { string av1; echo (1); av1 = element (1, argv); if (av1 == "libs") makelibs (); else if (av1 == "progs") makeprogs (); else if (av1 == "install") install (); else if (av1 == "clean") cleanup (); else if (av1 == "fresh") { install (); cleanup (); } else printf ("Make what?\n" "Select one of the following:\n" " \"icmake dos-msc -- libs\" to make libraries\n" " \"icmake dos-msc -- progs\" to make programs\n" " \"icmake dos-msc -- install\" to install programs to ", BINDIR, "\n" " \"icmake dos-msc -- clean\" to remove old mush\n" " \"icmake dos-msc -- fresh\" to install and clean\n" "\n"); } icmake-9.02.06/LICENSE0000644000175000017500000010451313237047127013124 0ustar frankfrank GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . icmake-9.02.06/pp/0000755000175000017500000000000013232314213012516 5ustar frankfrankicmake-9.02.06/pp/state/0000755000175000017500000000000013232314213013636 5ustar frankfrankicmake-9.02.06/pp/state/state.h0000644000175000017500000000131013176557635015152 0ustar frankfrank#ifndef INCLUDED_STATE_H_ #define INCLUDED_STATE_H_ #include int state_active(); void state_init(void); /* call once to initialze the state stack */ void state_push(int active); /* active: 1, passive: 0, push also takes the previous state into account. */ void state_pop(unsigned linenr); /* restores the former state */ void state_negate(unsigned linenr); /* negates the current state, assuming the previous state was active */ unsigned state_size(void); void state_eof(void); /* generates error if there are open #if(n)defs. Called by the scanner at EOF */ #endif icmake-9.02.06/pp/state/push.c0000644000175000017500000000056013176557635015012 0ustar frankfrank#define msgx #include "state.ih" void state_push(int active) { st_available(); /* make room if necessary */ State *sp = st_stack + st_size++; sp->active = (sp - 1)->active == 0 ? 0 : active; sp->elseCount = 0; msg("%s size = %u", filestack_tos()->filename, st_size); } icmake-9.02.06/pp/state/stavailable.c0000644000175000017500000000023413176557635016320 0ustar frankfrank#include "state.ih" void st_available() { if (st_size == st_capacity) st_stack = rss_realloc(st_stack, (st_capacity += 10) * sizeof(State)); } icmake-9.02.06/pp/state/eof.c0000644000175000017500000000046113176557635014604 0ustar frankfrank#include "state.ih" static char plural[2]; void state_eof() { if (st_size != 1) { if (st_size != 2) plural[0] = 's'; rss_fatal(0, 0, "at EOF: #endif%s missing for %u #if(n)def%s", plural, st_size - 1, plural); } } icmake-9.02.06/pp/state/pop.c0000644000175000017500000000050113176557635014624 0ustar frankfrank#define msgx #include "state.ih" void state_pop(unsigned linenr) { msg("%s %u size = %u, before pop", \ filestack_tos()->filename, linenr, st_size); --st_size; if (st_size == 0) rss_fatal(filestack_tos()->filename, linenr, "#endif without a matching #if(n)def encountered"); } icmake-9.02.06/pp/state/negate.c0000644000175000017500000000061113176557635015273 0ustar frankfrank#include "state.ih" void state_negate(unsigned linenr) { State *sp = st_stack + st_size - 1; if (sp->elseCount++) rss_fatal(filestack_tos()->filename, linenr, "multiple #else directives of #if(n)def encountered"); if ((sp - 1)->active) /* previous state is active */ sp->active = !sp->active; /* then negate */ } icmake-9.02.06/pp/state/data.c0000644000175000017500000000011613176557635014741 0ustar frankfrank#include "state.ih" State *st_stack; unsigned st_size; unsigned st_capacity; icmake-9.02.06/pp/state/active.c0000644000175000017500000000012513176557635015303 0ustar frankfrank#include "state.ih" int state_active() { return st_stack[st_size - 1].active; } icmake-9.02.06/pp/state/state.ih0000644000175000017500000000046113176557635015331 0ustar frankfrank#include "state.h" #include "../../rss/rss.h" #include "../filestack/filestack.h" typedef struct { int active; int elseCount; } State; extern State *st_stack; extern unsigned st_size; extern unsigned st_capacity; void st_available(); /* make sure there's enough room available */ icmake-9.02.06/pp/state/size.c0000644000175000017500000000010313176557635014776 0ustar frankfrank#include "state.ih" unsigned state_size() { return st_size; } icmake-9.02.06/pp/state/frame0000644000175000017500000000004213176557635014677 0ustar frankfrank#include "state.ih" void st_ { } icmake-9.02.06/pp/state/init.c0000644000175000017500000000023113176557635014771 0ustar frankfrank#include "state.ih" void state_init() { st_available(); st_size = 1; st_stack[0].active = 1; /* initialize to an active state */ } icmake-9.02.06/pp/usage.c0000644000175000017500000000141613176557635014020 0ustar frankfrank#include "icm-pp.ih" void usage(char const *argv0) { char const *progname = rss_programName(argv0); rss_copyright(progname); printf("%s%s%s%s", "This program is commonly run as a child process of icmake.\n" "Usage: ", progname, "[flags] inputfile outputfile\n" "where:\n" " flags - optional flags, which may be:\n" " -define SYM : defines SYM having value \"1\"\n" " -nostdsymbols : don't load predefined symbols " "(UNIX etc.)\n", " -dumpsymbols : show predefined symbols\n" " inputfile - icmake file\n" " outputfile - result of preprocessing\n" "\n"); exit(0); } icmake-9.02.06/pp/linear/0000755000175000017500000000000013232314213013770 5ustar frankfrankicmake-9.02.06/pp/linear/linear.h0000644000175000017500000000114713176557635015446 0ustar frankfrank#ifndef INCLUDED_LINEAR_H_ #define INCLUDED_LINEAR_H_ typedef struct { char *id; char *definition; } Linear; Linear const *linear_search(char const *ident); /* add: ident may not yet have been stored */ void linear_add(char const *ident, char const *definition); int linear_undef(char const *ident); /* return 1: OK */ void linear_show(); /* defined symbols to stdout */ #endif icmake-9.02.06/pp/linear/undef.c0000644000175000017500000000110213176557635015257 0ustar frankfrank#include "linear.ih" int linear_undef(char const *ident) { Linear *item = (Linear *)linear_search(ident); if (item == NULL) return 0; free(item->id); // free the item to undef free(item->definition); --l_size; // reduce the size if (l_table + l_size != item) // not the last item was removed: { item->id = l_table[l_size].id; // store the last item item->definition = l_table[l_size].definition; // at the free spot } return 1; } icmake-9.02.06/pp/linear/lreplacedefines.c0000644000175000017500000000236513176557635017317 0ustar frankfrank#include "linear.ih" char *l_replaceDefines(char *definition) { char *begin = definition; unsigned replacement = 0; while ((begin = strstr(begin, "${"))) /* find the opening characters */ { char *end = strchr(begin, '}'); /* find the end-brace */ if (end == NULL) /* none found, then done */ break; *end = 0; /* end the ID */ /* look for the identifier */ Linear const *item = linear_search(begin + 2); if (item == NULL) /* not found: keep ${...} */ { *end = '}'; /* restore the brace */ begin = end + 1; /* continue beyond ${...} */ continue; } if (++replacement > maxReplacements) rss_fatal(filestack_tos()->filename, scanner_lineNr(), "too many replacements in #define definition"); definition = l_updateDefinition(definition, &begin, end, item->definition); } return definition; } icmake-9.02.06/pp/linear/lupdatedefinition.c0000644000175000017500000000220413176557635017671 0ustar frankfrank#include "linear.ih" /* xxxxxxxxxxxx ^ repl ................${.......}.............. ^ ^ ^ def begin end Changes to: ................xxxxxxxxxxxx................ ^ ^ def begin */ char *l_updateDefinition(char *def, char **begin, char *end, char const *repl) { /* append what's beyond ${...} to definition of ${...} */ char *new = rss_strjoin(repl, end + 1); **begin = 0; /* end curr. def. at ${...} */ /* length of the processed section */ unsigned doneLength = *begin - def + strlen(repl); def = rss_strcat(def, new); /* append replacement + org tail*/ free(new); *begin = def + doneLength; /* continue replacing at *begin */ return def; /* new def. location */ } icmake-9.02.06/pp/linear/add.c0000644000175000017500000000050713176557635014716 0ustar frankfrank#include "linear.ih" void linear_add(char const *ident, char const *definition) { if (l_size == l_capacity) l_table = rss_realloc(l_table, (l_capacity += 10) * sizeof(Linear)); l_table[l_size].id = rss_strdup(ident); l_table[l_size].definition = l_replaceDefines(rss_strdup(definition)); ++l_size; } icmake-9.02.06/pp/linear/search.c0000644000175000017500000000021713176557635015431 0ustar frankfrank#include "linear.ih" Linear const *linear_search(char const *ident) { return lfind(ident, l_table, &l_size, sizeof(Linear), l_compare); } icmake-9.02.06/pp/linear/lcompare.c0000644000175000017500000000017513176557635015771 0ustar frankfrank#include "linear.ih" int l_compare(const void *ident, const void *item) { return strcmp(ident, ((Linear *)item)->id); } icmake-9.02.06/pp/linear/data.c0000644000175000017500000000012113176557635015067 0ustar frankfrank#include "linear.ih" Linear *l_table; size_t l_size; unsigned l_capacity; icmake-9.02.06/pp/linear/linear.ih0000644000175000017500000000101713176557635015613 0ustar frankfrank#include "linear.h" #include "stdlib.h" #include #include #include "../../rss/rss.h" #include "../filestack/filestack.h" #include "../scanner/scanner.h" enum { maxReplacements = 100 }; extern Linear *l_table; extern size_t l_size; extern unsigned l_capacity; int l_compare(const void *ident, const void *item); char *l_replaceDefines(char *definition); char *l_updateDefinition(char *def, char **begin, char *end, char const *repl); icmake-9.02.06/pp/linear/frame0000644000175000017500000000004213176557635015031 0ustar frankfrank#include "linear.ih" void l_ { } icmake-9.02.06/pp/linear/show.c0000644000175000017500000000042313176557635015143 0ustar frankfrank#include "linear.ih" void linear_show() { printf("Defined symbols: %u\n", (unsigned)l_size); Linear const *item = l_table; Linear const *end = l_table + l_size; for ( ; item != end; ++item) printf(" %20s: `%s'\n", item->id, item->definition); } icmake-9.02.06/pp/options.c0000644000175000017500000000155413176557635014412 0ustar frankfrank#include "icm-pp.ih" void options(int argc, char **argv) { int dump_symbols = 0; int load_symbols = 1; while (argc > 1 && *argv[1] == '-') { if (! strcmp(argv[1], "-define")) { if (argc < 3) rss_fatal(0, 0, "missing symbol after \"-define\""); linear_add(argv[2], "1"); ++argv; --argc; } else if (! strcmp(argv[1], "-nostdsymbols")) load_symbols = 0; else if (! strcmp(argv[1], "-dumpsymbols")) ++dump_symbols; else rss_fatal(0, 0, "Option `%s' not supported", argv[1]); ++argv; ++argc; } if (argc < 3) usage(*argv); if (load_symbols) loadSymbols(); /* platform specific #define's */ if (dump_symbols) linear_show(); } icmake-9.02.06/pp/icm-pp.ih0000644000175000017500000000032413176557635014254 0ustar frankfrank#include #include #include "../rss/rss.h" #include "linear/linear.h" #include "parser/parser.h" void options(int argc, char **argv); void usage(char const *progname); void loadSymbols(); icmake-9.02.06/pp/out/0000755000175000017500000000000013232314213013325 5ustar frankfrankicmake-9.02.06/pp/out/oclose.c0000644000175000017500000000023513176557635015005 0ustar frankfrank#define msgx #include "out.ih" void o_close() { fputc('\n', o_file); fclose(o_file); if (rss_nErrors() != 0) unlink(o_outFilename); } icmake-9.02.06/pp/out/out.ih0000644000175000017500000000055013176557635014506 0ustar frankfrank#include "out.h" #include #include #include #include "../../rss/rss.h" #include "../state/state.h" #include "../scanner/scanner.h" extern FILE *o_file; extern int o_space; extern unsigned o_nl; extern int o_atBOL; extern char *o_outFilename; void o_newLines(void); void o_close(void); void o_eof(void); icmake-9.02.06/pp/out/ateof.c0000644000175000017500000000010713176557635014615 0ustar frankfrank#include "out.ih" void (*out_atEOF(void))(void) { return o_eof; } icmake-9.02.06/pp/out/oeof.c0000644000175000017500000000024113176557635014446 0ustar frankfrank#include "out.ih" void o_eof() { if (!o_atBOL) fputc('\n', o_file); fprintf(o_file, "#\n"); o_space = 0; o_nl = 0; o_atBOL = 1; } icmake-9.02.06/pp/out/onewlines.c0000644000175000017500000000065213176557635015527 0ustar frankfrank#define msgx #include "out.ih" void o_newLines() { unsigned lineNr = scanner_lineNr(); msg("lineNr: %u, o_nl: %u", lineNr, o_nl); if (lineNr - o_nl > 4) { if (!o_atBOL) fputc('\n', o_file); fprintf(o_file, "#%u\n", lineNr); } else { for ( ; o_nl <= lineNr; ++o_nl) fputc('\n', o_file); } o_space = 0; o_nl = 0; o_atBOL = 1; } icmake-9.02.06/pp/out/data.c0000644000175000017500000000036313176557635014434 0ustar frankfrank#include "out.ih" FILE *o_file; int o_space; /* if != 0 then write one space */ unsigned o_nl; /* if 0, remembers the last scanner_lineNr() value */ int o_atBOL; /* if 1 we're at Begin of line */ char *o_outFilename; icmake-9.02.06/pp/out/space.c0000644000175000017500000000015213176557635014612 0ustar frankfrank#define msgx #include "out.ih" void out_space() { msg(""); if (!o_atBOL) o_space = 1; } icmake-9.02.06/pp/out/nl.c0000644000175000017500000000020413176557635014126 0ustar frankfrank#define msgx #include "out.ih" void out_nl() { if (o_nl == 0) o_nl = scanner_lineNr(); msg("o_nl = %u", o_nl); } icmake-9.02.06/pp/out/out.c0000644000175000017500000000054113176557635014330 0ustar frankfrank #define msgx #include "out.ih" void out(char const *text) { msg("%u %s", state_active(), text); if (state_active()) { if (o_nl != 0) o_newLines(); else if (o_space) { o_space = 0; fputc(' ', o_file); } fprintf(o_file, "%s", text); o_atBOL = 0; } } icmake-9.02.06/pp/out/out.h0000644000175000017500000000045313176557635014337 0ustar frankfrank#ifndef INCLUDED_OUT_ #define INCLUDED_OUT_ void out_init(char const *im, char const *pim); void out(char const *text); void out_space(void); void out_nl(void); void (*out_atEOF(void))(void); /* returns a function to be called at EOF */ #endif icmake-9.02.06/pp/out/frame0000644000175000017500000000003713176557635014372 0ustar frankfrank#include "out.ih" void o_ { } icmake-9.02.06/pp/out/init.c0000644000175000017500000000042013176557635014460 0ustar frankfrank#include "out.ih" void out_init(char const *im, char const *pim) { if ((o_file = fopen(pim, "w")) == NULL) rss_fatal(0, 0, "cannot write output file `%s'", pim); o_outFilename = rss_strdup(pim); fprintf(o_file, "#>%s\n", im); atexit(o_close); } icmake-9.02.06/pp/scanner/0000755000175000017500000000000013232314213014147 5ustar frankfrankicmake-9.02.06/pp/scanner/lexer0000644000175000017500000000347313176557635015250 0ustar frankfrank%{ #define msgx #include "scanner.ih" #define YY_NO_INPUT #include "pushfile.f" #include "scpopfile.f" %} %option 8bit yylineno %x string comment pointed ident [[:alpha:]_][[:alnum:]_]* %% "//".* /* ignore eoln comment */ ^[ \t]*"#"[ \t]*"!".* /* ignore #! lines */ [ \t]*"\\"\n | [ \t]+ { strcpy(yytext, " "); return ' '; } "/*" BEGIN comment; .|\n /* ignore chars inside comment */ "*/" { BEGIN INITIAL; return ' '; } "\"" { yymore(); BEGIN string; } \" { BEGIN INITIAL; return STRING; } "\\".|. yymore(); \n { rss_error(filestack_tos()->filename, yylineno, "double quote at end of string not found"); BEGIN INITIAL; } #define return DEFINE; #else return ELSE; #endif return ENDIF; #ifdef return IFDEF; #ifndef return IFNDEF; #include return INCLUDE; #undef return UNDEF; {ident} return IDENT; [[:digit:]]+ | 0x[[:xdigit:]]+ | "\\". | . return WORD; \n return '\n'; <> { if (!sc_popFile()) yyterminate(); } icmake-9.02.06/pp/scanner/scappenddefinition.c0000644000175000017500000000120713176557635020211 0ustar frankfrank#include "scanner.ih" void sc_appendDefinition(int cutoff) { if (cutoff) yytext[yyleng - 2] = 0; char *lhs = rss_trimLeft(yytext); char *rhs = rss_trimRight(lhs); free(lhs); if (!strlen(rhs)) /* nothing to append */ { free(rhs); return; } if (sc_definition == 0) /* nothing there yet */ { sc_definition = rhs; return; } sc_definition = strcat( strcat(sc_definition, " "), /* add separating blank */ rhs /* and trimmed yytext */ ); free(rhs); } icmake-9.02.06/pp/scanner/scstartdefinition.c0000644000175000017500000000014513176557635020077 0ustar frankfrank#include "scanner.ih" void sc_startDefinition() { free(sc_definition); sc_definition = 0; } icmake-9.02.06/pp/scanner/lastlinenr.c0000644000175000017500000000012313176557635016512 0ustar frankfrank#include "scanner.ih" unsigned scanner_lastLineNr() { return sc_lastLineNr; } icmake-9.02.06/pp/scanner/pushfile.f0000644000175000017500000000052113176557635016163 0ustar frankfrank/* included by lexer */ void scanner_pushFile(char const *filename) { if (state_active()) { msg("pushing %s %u", filename, YY_BUF_SIZE); yypush_buffer_state( yy_create_buffer( sc_pushFile(filename), YY_BUF_SIZE ) ); msg("pushed `%s'", filename); } } icmake-9.02.06/pp/scanner/eof.c0000644000175000017500000000010013176557635015103 0ustar frankfrank#include "scanner.ih" int scanner_eof() { return sc_eof; } icmake-9.02.06/pp/scanner/ateof.c0000644000175000017500000000012313176557635015435 0ustar frankfrank#include "scanner.ih" void scanner_atEOF(void (*ptr)(void)) { sc_ptr = ptr; } icmake-9.02.06/pp/scanner/scpopfile.f0000644000175000017500000000054513176557635016336 0ustar frankfrank/* included by lexer */ int sc_popFile() { yypop_buffer_state(); sc_lastLineNr = yylineno; yylineno = filestack_tos()->popLineNr; filestack_pop(); msg("returning to previous file"); size_t size = filestack_size(); if (size) (*sc_ptr)(); else { state_eof(); sc_eof = 1; } return size; } icmake-9.02.06/pp/scanner/data.c0000644000175000017500000000020713176557635015253 0ustar frankfrank#include "scanner.ih" char *sc_definition; int sc_getDefine; void (*sc_ptr)(void); int sc_eof; unsigned sc_lastLineNr; icmake-9.02.06/pp/scanner/scanner.ih0000644000175000017500000000165513176557635016161 0ustar frankfrank#include "scanner.h" #include #include #include #include "../../rss/rss.h" #include "../filestack/filestack.h" #include "../state/state.h" #include "../parser/tokens.h" /* parser.h" */ #ifndef fileno int fileno(FILE *stream); #endif #ifdef unput /* If this stops working, have a look at lexer2.c to see what was */ /* changed in the flex-implementation */ static void yyunput (int c,char *buf_ptr ); void (*unusedUnput)(int c,char *buf_ptr) = &yyunput; #endif extern FILE *yyin; extern FILE *yyout; extern char *yytext; extern size_t yyleng; extern int yylineno; extern unsigned sc_lastLineNr; extern char *sc_definition; extern int sc_getDefine; extern int sc_eof; extern void (*sc_ptr)(void); FILE *sc_pushFile(char const *filename); void sc_startDefinition(void); void sc_appendDefinition(int cutoff); icmake-9.02.06/pp/scanner/definition.c0000644000175000017500000000012613176557635016472 0ustar frankfrank#include "scanner.ih" char const *scanner_definition() { return sc_definition; } icmake-9.02.06/pp/scanner/scanner.c0000644000175000017500000000045613176557635016001 0ustar frankfrank#define msgx #include "scanner.ih" void scanner(char const *infile, void (*ptr)(void)) { filestack_push(yylineno, infile); yyin = filestack_tos()->file; sc_ptr = ptr; /* function called at EOF, when popping a previous file */ } icmake-9.02.06/pp/scanner/linenr.c0000644000175000017500000000011213176557635015624 0ustar frankfrank#include "scanner.ih" unsigned scanner_lineNr() { return yylineno; } icmake-9.02.06/pp/scanner/text.c0000644000175000017500000000011113176557635015320 0ustar frankfrank#include "scanner.ih" char const *scanner_text() { return yytext; } icmake-9.02.06/pp/scanner/lexer.c0000644000175000017500000014552513176557635015476 0ustar frankfrank#line 2 "lexer.c" #line 4 "lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 39 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires * access to the local variable yy_act. Since yyless() is a macro, it would break * existing scanners that call yyless() from OUTSIDE yylex. * One obvious solution it to make yy_act a global. I tried that, and saw * a 5% performance hit in a non-yylineno scanner, because yy_act is * normally declared as a register variable-- so it is not worth it. */ #define YY_LESS_LINENO(n) \ do { \ int yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ }while(0) #define YY_LINENO_REWIND_TO(dst) \ do {\ const char *p;\ for ( p = yy_cp-1; p >= (dst); --p)\ if ( *p == '\n' )\ --yylineno;\ }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ yy_size_t yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ (yytext_ptr) -= (yy_more_len); \ yyleng = (size_t) (yy_cp - (yytext_ptr)); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 25 #define YY_END_OF_BUFFER 26 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[82] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 23, 4, 24, 8, 23, 23, 20, 20, 19, 23, 4, 23, 10, 11, 9, 10, 6, 6, 25, 4, 0, 0, 0, 0, 0, 5, 1, 20, 0, 19, 22, 3, 4, 0, 0, 2, 10, 7, 0, 0, 0, 0, 0, 0, 1, 21, 2, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 14, 15, 0, 0, 18, 12, 16, 0, 17, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, 1, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 13, 1, 1, 12, 1, 11, 11, 14, 15, 16, 17, 12, 12, 18, 12, 12, 19, 12, 20, 12, 12, 12, 12, 21, 12, 22, 12, 12, 23, 12, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[24] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 3, 3, 3, 4, 1, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 } ; static yyconst flex_int16_t yy_base[91] = { 0, 0, 22, 22, 26, 117, 116, 0, 0, 122, 125, 24, 125, 125, 25, 25, 35, 39, 0, 118, 40, 32, 125, 125, 125, 0, 125, 112, 125, 48, 116, 102, 32, 37, 97, 125, 0, 46, 0, 0, 125, 125, 57, 58, 62, 0, 125, 125, 99, 94, 99, 52, 99, 97, 0, 0, 0, 93, 94, 91, 92, 92, 87, 89, 84, 125, 86, 83, 80, 70, 54, 53, 125, 125, 51, 50, 125, 125, 125, 22, 125, 125, 72, 76, 80, 82, 86, 90, 94, 27, 98 } ; static yyconst flex_int16_t yy_def[91] = { 0, 81, 1, 82, 82, 83, 83, 84, 84, 81, 81, 81, 81, 81, 81, 81, 81, 81, 85, 86, 81, 14, 81, 81, 81, 87, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 88, 81, 89, 85, 81, 81, 81, 81, 81, 90, 81, 81, 81, 81, 81, 81, 81, 81, 88, 89, 90, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81 } ; static yyconst flex_int16_t yy_nxt[149] = { 0, 10, 11, 12, 10, 13, 14, 10, 15, 16, 17, 18, 18, 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 23, 29, 24, 21, 23, 55, 24, 35, 36, 44, 25, 45, 30, 80, 25, 31, 32, 42, 33, 37, 37, 43, 34, 37, 37, 29, 49, 50, 30, 51, 37, 37, 52, 38, 42, 44, 30, 45, 43, 44, 79, 45, 60, 78, 77, 30, 76, 61, 22, 22, 22, 22, 26, 26, 26, 26, 28, 28, 28, 28, 39, 39, 40, 40, 40, 40, 46, 75, 46, 46, 54, 74, 54, 54, 56, 73, 56, 56, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 59, 58, 57, 53, 48, 41, 47, 41, 81, 27, 27, 9, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81 } ; static yyconst flex_int16_t yy_chk[149] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 11, 3, 2, 4, 89, 4, 15, 15, 21, 3, 21, 11, 79, 4, 14, 14, 20, 14, 16, 16, 20, 14, 17, 17, 29, 32, 32, 20, 33, 37, 37, 33, 16, 42, 43, 29, 43, 42, 44, 75, 44, 51, 74, 71, 42, 70, 51, 82, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, 84, 85, 85, 86, 86, 86, 86, 87, 69, 87, 87, 88, 68, 88, 88, 90, 67, 90, 90, 66, 64, 63, 62, 61, 60, 59, 58, 57, 53, 52, 50, 49, 48, 34, 31, 30, 27, 19, 9, 6, 5, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81 } ; /* Table of booleans, true if rule could match eol. */ static yyconst flex_int32_t yy_rule_can_match_eol[26] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, }; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected static int yy_more_flag = 0; static int yy_more_len = 0; #define yymore() ((yy_more_flag) = 1) #define YY_MORE_ADJ (yy_more_len) #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "lexer" #line 2 "lexer" #define msgx #include "scanner.ih" #define YY_NO_INPUT #include "pushfile.f" #include "scpopfile.f" #line 552 "lexer.c" #define INITIAL 0 #define string 1 #define comment 2 #define pointed 3 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * in_str ); FILE *yyget_out (void ); void yyset_out (FILE * out_str ); yy_size_t yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 18 "lexer" #line 775 "lexer.c" while ( 1 ) /* loops until end-of-file is reached */ { (yy_more_len) = 0; if ( (yy_more_flag) ) { (yy_more_len) = (yy_c_buf_p) - (yytext_ptr); (yy_more_flag) = 0; } yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 82 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 125 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) { yy_size_t yyl; for ( yyl = (yy_more_len); yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) yylineno++; ; } do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 20 "lexer" /* ignore eoln comment */ YY_BREAK case 2: YY_RULE_SETUP #line 21 "lexer" /* ignore #! lines */ YY_BREAK case 3: /* rule 3 can match eol */ #line 24 "lexer" case 4: /* rule 4 can match eol */ YY_RULE_SETUP #line 24 "lexer" { strcpy(yytext, " "); return ' '; } YY_BREAK case 5: YY_RULE_SETUP #line 29 "lexer" BEGIN comment; YY_BREAK case 6: /* rule 6 can match eol */ YY_RULE_SETUP #line 31 "lexer" /* ignore chars inside comment */ YY_BREAK case 7: YY_RULE_SETUP #line 33 "lexer" { BEGIN INITIAL; return ' '; } YY_BREAK case 8: YY_RULE_SETUP #line 38 "lexer" { yymore(); BEGIN string; } YY_BREAK case 9: YY_RULE_SETUP #line 42 "lexer" { BEGIN INITIAL; return STRING; } YY_BREAK case 10: YY_RULE_SETUP #line 46 "lexer" yymore(); YY_BREAK case 11: /* rule 11 can match eol */ YY_RULE_SETUP #line 48 "lexer" { rss_error(filestack_tos()->filename, yylineno, "double quote at end of string not found"); BEGIN INITIAL; } YY_BREAK case 12: YY_RULE_SETUP #line 54 "lexer" return DEFINE; YY_BREAK case 13: YY_RULE_SETUP #line 55 "lexer" return ELSE; YY_BREAK case 14: YY_RULE_SETUP #line 56 "lexer" return ENDIF; YY_BREAK case 15: YY_RULE_SETUP #line 57 "lexer" return IFDEF; YY_BREAK case 16: YY_RULE_SETUP #line 58 "lexer" return IFNDEF; YY_BREAK case 17: YY_RULE_SETUP #line 59 "lexer" return INCLUDE; YY_BREAK case 18: YY_RULE_SETUP #line 60 "lexer" return UNDEF; YY_BREAK case 19: YY_RULE_SETUP #line 62 "lexer" return IDENT; YY_BREAK case 20: #line 65 "lexer" case 21: #line 66 "lexer" case 22: #line 67 "lexer" case 23: YY_RULE_SETUP #line 67 "lexer" return WORD; YY_BREAK case 24: /* rule 24 can match eol */ YY_RULE_SETUP #line 69 "lexer" return '\n'; YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(string): case YY_STATE_EOF(comment): case YY_STATE_EOF(pointed): #line 71 "lexer" { if (!sc_popFile()) yyterminate(); } YY_BREAK case 25: YY_RULE_SETUP #line 75 "lexer" ECHO; YY_BREAK #line 993 "lexer.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 82 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 82 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 81); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; if ( c == '\n' ){ --yylineno; } (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol ) yylineno++; ; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ yy_size_t yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ /* We do not touch yylineno unless the option is enabled. */ yylineno = 1; (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 74 "lexer" icmake-9.02.06/pp/scanner/length.c0000644000175000017500000000011013176557635015614 0ustar frankfrank#include "scanner.ih" unsigned scanner_length() { return yyleng; } icmake-9.02.06/pp/scanner/scanner.h0000644000175000017500000000056413176557635016006 0ustar frankfrank#ifndef INCLUDED_SCANNER_H_ #define INCLUDED_SCANNER_H_ #include void scanner(char const *infile, void (*ptr)(void)); int yylex(); char const *scanner_text(); char const *scanner_definition(); unsigned scanner_lineNr(); unsigned scanner_length(); void scanner_pushFile(char const *filename); int scanner_eof(void); unsigned scanner_lastLineNr(void); #endif icmake-9.02.06/pp/scanner/frame0000644000175000017500000000004413176557635015212 0ustar frankfrank#include "scanner.ih" void sc_ { } icmake-9.02.06/pp/scanner/scpushfile.c0000644000175000017500000000034413176557635016511 0ustar frankfrank#define msgx #include "scanner.ih" FILE *sc_pushFile(char const *filename) { msg("push %s", filename); filestack_push(yylineno, filename); msg("done"); yylineno = 1; return yyin = filestack_tos()->file; } icmake-9.02.06/pp/icm_bootstrap0000755000175000017500000000024013176557635015335 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/${LIBDIR}/icm-pp build icm-pp filestack state scanner out linear parser icmake-9.02.06/pp/parser/0000755000175000017500000000000013232314213014012 5ustar frankfrankicmake-9.02.06/pp/parser/parse.c0000644000175000017500000000020213176557635015312 0ustar frankfrank #define msgx #include "parser.ih" int parser_parse() { msg("Current status: %u", state_active()); return yyparse(); } icmake-9.02.06/pp/parser/pundef.c0000644000175000017500000000045213176557635015470 0ustar frankfrank#define msgx #include "parser.ih" void p_undef() { if (state_active() && !linear_undef(p_text)) rss_warning(filestack_tos()->filename, scanner_lineNr() - 1, "#undef %s: `%s' not defined\n", p_text, p_text); msg("active: %u", state_active()); } icmake-9.02.06/pp/parser/pquotedname.c0000644000175000017500000000023513176557635016530 0ustar frankfrank#include "parser.ih" char const *p_quotedName(char *name) { name[strlen(name) - 1] = 0; /* remove the last character */ return name; } icmake-9.02.06/pp/parser/parser.h0000644000175000017500000000021713176557635015507 0ustar frankfrank#ifndef INCLUDED_PARSER_H_ #define INCLUDED_PARSER_H_ void parser(char **argv); /* call once */ int parser_parse(void); #endif icmake-9.02.06/pp/parser/yyparse.c0000644000175000017500000013416413176557635015713 0ustar frankfrank/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Copy the first part of user declarations. */ #line 1 "grammar" /* yacc.c:339 */ #define msgx #include "parser.ih" #line 71 "yyparse.c" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* In a future release of Bison, this section will be replaced by #include "tokens.h". */ #ifndef YY_YY_TOKENS_H_INCLUDED # define YY_YY_TOKENS_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { DEFINE = 258, ELSE = 259, ENDIF = 260, IFDEF = 261, IFNDEF = 262, INCLUDE = 263, STRING = 264, UNDEF = 265, IDENT = 266, WORD = 267, POINTED = 268 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_TOKENS_H_INCLUDED */ /* Copy the second part of user declarations. */ #line 136 "yyparse.c" /* yacc.c:358 */ #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE # if (defined __GNUC__ \ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C # define YY_ATTRIBUTE(Spec) __attribute__(Spec) # else # define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif #ifndef YY_ATTRIBUTE_PURE # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) #endif #ifndef YY_ATTRIBUTE_UNUSED # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif #if !defined _Noreturn \ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) # if defined _MSC_VER && 1200 <= _MSC_VER # define _Noreturn __declspec (noreturn) # else # define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 6 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 39 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 16 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 12 /* YYNRULES -- Number of rules. */ #define YYNRULES 27 /* YYNSTATES -- Number of states. */ #define YYNSTATES 42 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 268 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 22, 22, 25, 29, 34, 42, 49, 55, 57, 61, 68, 73, 78, 85, 91, 97, 103, 109, 115, 123, 127, 130, 137, 138, 143, 148, 153 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "DEFINE", "ELSE", "ENDIF", "IFDEF", "IFNDEF", "INCLUDE", "STRING", "UNDEF", "IDENT", "WORD", "POINTED", "'\\n'", "' '", "$accept", "input", "line", "wsTail", "identToken", "ident", "filenameToken", "includeFile", "content", "ws", "optWs", "text", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 10, 32 }; # endif #define YYPACT_NINF -14 #define yypact_value_is_default(Yystate) \ (!!((Yystate) == (-14))) #define YYTABLE_NINF -1 #define yytable_value_is_error(Yytable_value) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { -13, -14, 1, -14, -10, 3, -14, -14, -14, -14, -13, -13, -13, -13, -13, -13, -14, -13, -14, -14, -14, -14, -14, 7, -14, -11, -14, -14, 19, -14, 20, -14, -14, -14, -14, -13, -14, -14, -14, -13, -14, -14 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 24, 22, 24, 3, 23, 0, 1, 2, 21, 20, 0, 24, 24, 0, 0, 0, 27, 0, 26, 25, 11, 4, 12, 0, 14, 0, 15, 16, 0, 18, 0, 17, 13, 5, 6, 24, 8, 9, 10, 24, 7, 19 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -14, -14, 17, -12, -14, 22, -14, -14, -14, 11, 31, -14 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 2, 3, 24, 35, 27, 38, 39, 21, 4, 25, 22 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { 26, 6, 1, 33, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 20, 32, 7, 0, 23, 8, 40, 28, 28, 30, 41, 28, 36, 34, 5, 37, 5, 8, 8, 29, 0, 0, 31 }; static const yytype_int8 yycheck[] = { 12, 0, 15, 14, 1, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 14, 11, 2, -1, 10, 15, 35, 13, 14, 15, 39, 17, 9, 11, 0, 12, 2, 15, 15, 14, -1, -1, 17 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 15, 17, 18, 25, 26, 0, 18, 15, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 24, 27, 25, 19, 26, 19, 21, 25, 21, 25, 21, 11, 14, 11, 20, 9, 12, 22, 23, 19, 19 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 16, 17, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 26, 26, 27, 27, 27 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 1, 2, 2, 1, 3, 1, 1, 1, 1, 1, 3, 2, 2, 2, 2, 2, 4, 1, 2, 1, 1, 0, 1, 1, 1 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*----------------------------------------. | Print this symbol's value on YYOUTPUT. | `----------------------------------------*/ static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyo = yyoutput; YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyoutput, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T yystrlen (const char *yystr) { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (void) { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 5: #line 36 "grammar" /* yacc.c:1646 */ { out_nl(); } #line 1234 "yyparse.c" /* yacc.c:1646 */ break; case 6: #line 43 "grammar" /* yacc.c:1646 */ { p_saveYYtext(); } #line 1242 "yyparse.c" /* yacc.c:1646 */ break; case 10: #line 62 "grammar" /* yacc.c:1646 */ { p_saveYYtext(); } #line 1250 "yyparse.c" /* yacc.c:1646 */ break; case 11: #line 69 "grammar" /* yacc.c:1646 */ { out_nl(); } #line 1258 "yyparse.c" /* yacc.c:1646 */ break; case 12: #line 74 "grammar" /* yacc.c:1646 */ { p_textLine((yyvsp[0])); } #line 1266 "yyparse.c" /* yacc.c:1646 */ break; case 13: #line 81 "grammar" /* yacc.c:1646 */ { p_define(); } #line 1274 "yyparse.c" /* yacc.c:1646 */ break; case 14: #line 87 "grammar" /* yacc.c:1646 */ { p_else(); } #line 1282 "yyparse.c" /* yacc.c:1646 */ break; case 15: #line 93 "grammar" /* yacc.c:1646 */ { p_endif(); } #line 1290 "yyparse.c" /* yacc.c:1646 */ break; case 16: #line 99 "grammar" /* yacc.c:1646 */ { p_ifdef(); } #line 1298 "yyparse.c" /* yacc.c:1646 */ break; case 17: #line 105 "grammar" /* yacc.c:1646 */ { p_undef(); } #line 1306 "yyparse.c" /* yacc.c:1646 */ break; case 18: #line 111 "grammar" /* yacc.c:1646 */ { p_ifndef(); } #line 1314 "yyparse.c" /* yacc.c:1646 */ break; case 19: #line 119 "grammar" /* yacc.c:1646 */ { p_pushFile(); } #line 1322 "yyparse.c" /* yacc.c:1646 */ break; case 22: #line 131 "grammar" /* yacc.c:1646 */ { out_space(); } #line 1330 "yyparse.c" /* yacc.c:1646 */ break; case 25: #line 144 "grammar" /* yacc.c:1646 */ { (yyval) = WORD; } #line 1338 "yyparse.c" /* yacc.c:1646 */ break; case 26: #line 149 "grammar" /* yacc.c:1646 */ { (yyval) = IDENT; } #line 1346 "yyparse.c" /* yacc.c:1646 */ break; case 27: #line 154 "grammar" /* yacc.c:1646 */ { (yyval) = STRING; } #line 1354 "yyparse.c" /* yacc.c:1646 */ break; #line 1358 "yyparse.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 159 "grammar" /* yacc.c:1906 */ int yywrap(void) { return 1; } icmake-9.02.06/pp/parser/pyyerror.c0000644000175000017500000000050013176557635016074 0ustar frankfrank#include "parser.ih" int yyerror(char *s) { if (scanner_eof()) rss_fatal(p_filename, scanner_lastLineNr(), "Unexpected end of file"); rss_error(filestack_tos()->filename, scanner_lineNr(), "Syntax error at `%s'", scanner_text()); return 0; } icmake-9.02.06/pp/parser/parser.ih0000644000175000017500000000164513176557635015666 0ustar frankfrank#include "parser.h" #include #include #include #include #include "../../rss/rss.h" #include "../filestack/filestack.h" #include "../scanner/scanner.h" #include "../state/state.h" #include "../linear/linear.h" #include "../out/out.h" #include "tokens.h" extern int yynerrs; extern char *p_filename; extern char *p_text; extern char *p_im; extern char p_dirsep[]; void p_saveYYtext(void); void p_define(void); void p_addDef(char const *ident, char const *definition); void p_semantic(char const *s, ...); void p_ifdef(void); void p_ifndef(void); void p_undef(void); void p_else(void); void p_endif(void); void p_inspectIdent(void); void p_textFile(void); void p_textLine(int token); void p_pushIMfile(void); void p_pushFile(void); char const *p_nextFile(void); char const *p_quotedName(char *name); char const *p_IMfile(void); char const *p_getIMname(void); int yyerror(char *s); icmake-9.02.06/pp/parser/pelse.c0000644000175000017500000000020613176557635015314 0ustar frankfrank#define msgx #include "parser.ih" void p_else() { state_negate(scanner_lineNr() - 1); msg("active: %u", state_active()); } icmake-9.02.06/pp/parser/tokens.h0000644000175000017500000000425213176557635015521 0ustar frankfrank/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ #ifndef YY_YY_TOKENS_H_INCLUDED # define YY_YY_TOKENS_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { DEFINE = 258, ELSE = 259, ENDIF = 260, IFDEF = 261, IFNDEF = 262, INCLUDE = 263, STRING = 264, UNDEF = 265, IDENT = 266, WORD = 267, POINTED = 268 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_TOKENS_H_INCLUDED */ icmake-9.02.06/pp/parser/ppushfile.c0000644000175000017500000000045513176557635016211 0ustar frankfrank#define msgx #include "parser.ih" void p_pushFile() /* switch to another file */ { char const *filename = p_nextFile(); msg("%s", filename); if (state_active()) { out("#>"); out(filename); out("\n"); scanner_pushFile(filename); } } icmake-9.02.06/pp/parser/padddef.c0000644000175000017500000000055013176557635015575 0ustar frankfrank#define msgx #include "parser.ih" void p_addDef(char const *ident, char const *definition) { msg("id: %s, def: %s", ident, definition); if (linear_search(ident) != NULL) { rss_error(filestack_tos()->filename, scanner_lineNr(), "%s multiply defined", ident); return; } linear_add(ident, definition); } icmake-9.02.06/pp/parser/pinspectident.c0000644000175000017500000000031013176557635017051 0ustar frankfrank#define msgx #include "parser.ih" void p_inspectIdent() { char const *ident = scanner_text(); Linear const *item = linear_search(ident); out(item == NULL ? ident : item->definition); } icmake-9.02.06/pp/parser/pendif.c0000644000175000017500000000020413176557635015447 0ustar frankfrank#define msgx #include "parser.ih" void p_endif() { state_pop(scanner_lineNr() - 1); msg("active: %u", state_active()); } icmake-9.02.06/pp/parser/psaveyytext.c0000644000175000017500000000021513176557635016611 0ustar frankfrank#define msgx #include "parser.ih" void p_saveYYtext() { free(p_text); p_text = rss_strdup(scanner_text()); msg("%s", p_text); } icmake-9.02.06/pp/parser/pdefine.c0000644000175000017500000000113413176557635015617 0ustar frankfrank#define msgx #include "parser.ih" void p_define() { char *ident = rss_strdup(scanner_text()); char *definition = rss_strdup(""); while (1) { int token = yylex(); if (token == 0 || token == '\n') break; definition = rss_strcat(definition, scanner_text()); } out_nl(); if (!state_active()) { free(definition); return; } char *trimLeft = rss_trimLeft(definition); definition = rss_trimRight(trimLeft); free(trimLeft); p_addDef(ident, definition); free(ident); free(definition); } icmake-9.02.06/pp/parser/grammar0000644000175000017500000000252013176557635015412 0ustar frankfrank%{ #define msgx #include "parser.ih" %} %token DEFINE ELSE ENDIF IFDEF IFNDEF INCLUDE STRING UNDEF IDENT WORD POINTED %% input: input line | line ; line: optWs content ; wsTail: optWs '\n' { out_nl(); } ; identToken: IDENT { p_saveYYtext(); } ; ident: ws identToken wsTail ; filenameToken: STRING | WORD ; includeFile: filenameToken { p_saveYYtext(); } ; content: '\n' { out_nl(); } | text { p_textLine($1); } | DEFINE ws IDENT { p_define(); } | ELSE wsTail { p_else(); } | ENDIF wsTail { p_endif(); } | IFDEF ident { p_ifdef(); } | UNDEF ident { p_undef(); } | IFNDEF ident { p_ifndef(); } | INCLUDE ws includeFile wsTail { p_pushFile(); } | error ; ws: ws ' ' | ' ' { out_space(); } ; optWs: ws | /* empty */ ; text: WORD { $$ = WORD; } | IDENT { $$ = IDENT; } | STRING { $$ = STRING; } ; %% int yywrap(void) { return 1; } icmake-9.02.06/pp/parser/parser.c0000644000175000017500000000033513176557635015503 0ustar frankfrank#include "parser.ih" void parser(char **argv) { p_im = rss_strdup(getenv("IM")); state_init(); p_filename = rss_strdup(argv[1]); out_init(p_filename, argv[2]); scanner(p_filename, out_atEOF()); } icmake-9.02.06/pp/parser/pgetimname.c0000644000175000017500000000123413176557635016334 0ustar frankfrank#include "parser.ih" static char buffer[MAX_PATHLEN]; char const *p_getIMname() { strcpy(buffer, p_dirsep); /* not an absolute path: IM paths are prepended to dest */ while (1) { switch (yylex()) /* already saw the initial '<' */ { case 0: case '\n': rss_fatal(0, 0, "#include file specification not ending in >"); case WORD: if (scanner_text()[0] == '>') return buffer; // FALLING THRU default: strcat(buffer, scanner_text()); break; } } } icmake-9.02.06/pp/parser/data.c0000644000175000017500000000020213176557635015111 0ustar frankfrank#include "parser.ih" char *p_filename; /* initial filename */ char *p_text; char *p_im; char p_dirsep[] = {DIRSEP, 0}; icmake-9.02.06/pp/parser/pimfile.c0000644000175000017500000000142613176557635015636 0ustar frankfrank#define msgx #include "parser.ih" static char buffer[MAX_PATHLEN]; char const *p_IMfile() { char const *filename = p_getIMname(); msg("looking for IM file `%s'", filename); char *im = rss_strdup(p_im); char *path = strtok(im, ":"); /* get the first path element */ while (path) { strcpy(buffer, path); strcat(buffer, filename); if (access(buffer, R_OK) == 0) /* return the 1st readable file */ { free(im); return buffer; } path = strtok(NULL, ":"); /* not found: next IM element */ } rss_fatal(0, 0, "can't find `%s' in IM directories (%s)", filename, p_im); free(im); return NULL; /* to satisfy the compiler */ } icmake-9.02.06/pp/parser/pnextfile.c0000644000175000017500000000024213176557635016202 0ustar frankfrank#include "parser.ih" char const *p_nextFile() { return *p_text == '"' ? p_quotedName(p_text + 1) : p_IMfile(); } icmake-9.02.06/pp/parser/pifdef.c0000644000175000017500000000023113176557635015437 0ustar frankfrank#define msgx #include "parser.ih" void p_ifdef() { state_push(linear_search(p_text) != NULL); msg("active %s: %u", p_text, state_active()); } icmake-9.02.06/pp/parser/pifndef.c0000644000175000017500000000021713176557635015621 0ustar frankfrank#define msgx #include "parser.ih" void p_ifndef() { state_push(linear_search(p_text) == NULL); msg("active: %u", state_active()); } icmake-9.02.06/pp/parser/frame0000644000175000017500000000004213176557635015053 0ustar frankfrank#include "parser.ih" void p_ { } icmake-9.02.06/pp/parser/ptextline.c0000644000175000017500000000050513176557635016222 0ustar frankfrank#define msgx #include "parser.ih" void p_textLine(int token) { do { msg("saw %u, `%s'", token, scanner_text()); if (token == IDENT) p_inspectIdent(); else out(scanner_text()); token = yylex(); } while (token != '\n' && token != 0); out_nl(); } icmake-9.02.06/pp/loadsymbols.c0000644000175000017500000000154613176557635015250 0ustar frankfrank/* Load platform specific defines. Modify this file to your taste before compiling icmake: new symbols can be added by adding a macro block, as the ones defined below, using the name of your symbol. If your modification is useful outside of your local computing environment, please e-mail f.b.brokken@rug.nl so your suggestion can be handled in icmake's next release. */ #include "icm-pp.ih" void loadSymbols() { #ifdef UNIX linear_add("UNIX", "1"); #endif #ifdef unix linear_add("unix", "1"); #endif #ifdef LINUX linear_add("LINUX", "1"); #endif #ifdef linux linear_add("linux", "1"); #endif #ifdef M_SYSV linear_add("M_SYSV", "1"); #endif #ifdef M_UNIX linear_add("M_UNIX", "1"); #endif #ifdef _POSIX_SOURCE linear_add("_POSIX_SOURCE", "1"); #endif #ifdef __hpux linear_add("__hpux", "1"); #endif } icmake-9.02.06/pp/icmconf0000644000175000017500000000156513176557635014116 0ustar frankfrank#define USE_ECHO ON #define MAIN "main.c" #define COMPILER "gcc" #define COMPILER_OPTIONS "-Wall -Werror -O2 -fdiagnostics-color=never" #define SOURCES "*.c" #define LINKER_OPTIONS "-s" #define ADD_LIBRARIES "icrss" #define ADD_LIBRARY_PATHS "../../tmp" #define REFRESH #define CLS #define SCANNER_DIR "scanner" #define SCANGEN "flex" #define SCANFLAGS "-o lexer.c" #define SCANSPEC "lexer" #define SCANOUT "lexer.c" #define PARSER_DIR "parser" #define PARSGEN "bison" #define PARSSPEC "grammar" #define PARSFLAGS "--defines=tokens.h -o yyparse.c" #define PARSOUT "yyparse.c" #define TMP_DIR "tmp" #define LIBRARY "modules" #define OBJ_EXT ".o" #define DEFCOM "program" icmake-9.02.06/pp/build0000755000175000017500000000023113176557635013567 0ustar frankfrank#!/bin/bash if [ scanner/pushfile.f -nt scanner/lexer \ -o scanner/scpopfile.f -nt scanner/lexer ] ; then touch scanner/lexer fi icmbuild $1 icmake-9.02.06/pp/CLASSES0000644000175000017500000000006513176557635013567 0ustar frankfrankfilestack state # scanner out linear # parser # main icmake-9.02.06/pp/main.c0000644000175000017500000000173713176557635013646 0ustar frankfrank/* Function {\em main()} checks if two arguments are present on the invoking command line. If not, an error occurs. The environment variable {\em IM} is inspected to ensure that included files are searched from this directory. When not set, included files are searched in the current directory. Next the input- and output files are opened. The input file is opened using function {\em pushfile()}. The output file is pointed to by {\em FILE $*$outfile}. To process the input, function {\em lexer()} is called and its return value is passed to {\em process()}. This is repeated until the filestack pointer {\em filesp}(increased by {\em pushfile()}, decreased by {\em popfile()}) indicates that the file stack is empty. */ #define msgx #include "icm-pp.ih" int main(int argc, char **argv) { options(argc, argv); parser(argv); parser_parse(); return rss_nErrors() != 0; } icmake-9.02.06/pp/filestack/0000755000175000017500000000000013232314213014463 5ustar frankfrankicmake-9.02.06/pp/filestack/push.c0000644000175000017500000000073213176557635015640 0ustar frankfrank#define msgx #include "filestack.ih" void filestack_push(unsigned currentLineNr, char const *fname) { fs_stack = rss_realloc(fs_stack, (fs_size + 1) * sizeof(FileStack)); if (! (fs_stack[fs_size].file = fopen(fname, "r")) ) rss_fatal(0, 0, "cannot open #include file `%s'", fname); fs_stack[fs_size].filename = rss_strdup(fname); fs_stack[fs_size].popLineNr = currentLineNr; msg("Pushed file %u: `%s'", fs_size, fname); ++fs_size; } icmake-9.02.06/pp/filestack/filestack.ih0000644000175000017500000000017113176557635017001 0ustar frankfrank#include "filestack.h" #include #include "../../rss/rss.h" extern FileStack *fs_stack; extern int fs_size; icmake-9.02.06/pp/filestack/filestack.h0000644000175000017500000000075613176557635016641 0ustar frankfrank#ifndef INCLUDED_FILESTACK_H_ #define INCLUDED_FILESTACK_H_ #include typedef struct /* yylex itself maintains its own YY_BUFFERs */ { char *filename; /* name of the currently active file */ FILE *file; int popLineNr; /* value of yylineno when popping this element */ } FileStack; void filestack_push(unsigned currentLineNr, char const *fname); void filestack_pop(); FileStack const *filestack_tos(); unsigned filestack_size(); #endif icmake-9.02.06/pp/filestack/pop.c0000644000175000017500000000013213176557635015451 0ustar frankfrank#include "filestack.ih" void filestack_pop() { free(fs_stack[--fs_size].filename); } icmake-9.02.06/pp/filestack/data.c0000644000175000017500000000014213176557635015565 0ustar frankfrank#include "filestack.ih" FileStack *fs_stack; int fs_size; /* initial empty stack. */ icmake-9.02.06/pp/filestack/size.c0000644000175000017500000000011313176557635015624 0ustar frankfrank#include "filestack.ih" unsigned filestack_size() { return fs_size; } icmake-9.02.06/pp/filestack/tos.c0000644000175000017500000000023213176557635015461 0ustar frankfrank#define msgx #include "filestack.ih" FileStack const *filestack_tos() { msg("tos() looks at %u", fs_size - 1); return &fs_stack[fs_size - 1]; } icmake-9.02.06/pp/filestack/frame0000644000175000017500000000004613176557635015530 0ustar frankfrank#include "filestack.ih" void fs_ { } icmake-9.02.06/QUICKINSTALL0000644000175000017500000000225713176557635013763 0ustar frankfrank0. After unpacking the icmake_X.YY.tar.gz icmake archive, make your current working directory equal to the directory in which you found this file. 1. Inspect and modify if necessary the current locations in INSTALL.im. 2. If you want the compiler to insert debugging code in the icmake programs then define a CFLAGS environment variable. E.g., CFLAGS="-Wall -O2 -g" 3. To prepare for the compilations of the programs, run ./icm_prepare / 3. Compile the various programs (x is a dummy argument required by ./icm_bootstrap to run): ./icm_bootstrap x 4. As root: install the programs and documentation: ./icm_install strip all 5. Remove intermediate construction area: rm -rf tmp Following these commands (referring to the #defines in INSTALL.im): icmake is in /BINDIR skeleton files, installed by icmstart, are in /SKELDIR manual pages are in /MANDIR/man{1,7} icmake support programs are in /LIBDIR confguration files, specifying which skeleton commands to install, are in /CONFDIR icmake documentation is installed in /DOCDIR and /DOCDOCDIR icmake-9.02.06/required0000644000175000017500000000053413232311247013650 0ustar frankfrankThis file lists non-standard software only. Thus, standard utilities like cp, mv, sed, etc, etc, are not explicitly mentioned. Neither is the gcc compiler explicitly mentioned, but a fairly recent one is assumed. Required software for building Icmake ------------------------------------- Recent version of yodl (for creating documentation) icmake-9.02.06/rss/0000755000175000017500000000000013232314206012710 5ustar frankfrankicmake-9.02.06/rss/getopcode.c0000644000175000017500000000071613176557635015057 0ustar frankfrank/* Function {\em rss_getOpcode()} attempts to read an opcode from file {\em f}. This file must be opened in read/binary mode (see the constant {\em "r"} in file {\em icm.h}). When the reading operation fails, --1 is returned. */ /*#define msg */ #include "rss.ih" Opcode rss_getOpcode (FILE *f) { char op = 0; if (!fread (&op, sizeof(char), 1, f)) op = (char)-1; msg("next opcode: 0x%x", op); return (Opcode) op; } icmake-9.02.06/rss/strjoin.c0000644000175000017500000000041313176557635014570 0ustar frankfrank/* this function returns a copy of s1 to which s2 is appended. Both s1 and s2 may be NULL, in which case an empty string is returned. */ #include "rss.ih" char *rss_strjoin(char const *s1, char const *s2) { return rss_strcat(rss_strdup(s1), s2); } icmake-9.02.06/rss/rsgloberr.c0000644000175000017500000000024413176557635015103 0ustar frankfrank#include "rss.ih" /* glob() error handler returns 0: signal for glob to ignore the error */ int rs_globerr(char const *path, int errnr) { return 0; } icmake-9.02.06/rss/changeext.c0000644000175000017500000000034113176557635015046 0ustar frankfrank#include "rss.ih" char *rss_changeExt(char const *path, char const *extension) { rs_split(path); *gr_ext = 0; if (extension) strcpy(gr_ext, extension); rs_join(); return rss_strdup(gr_name); } icmake-9.02.06/rss/rsfindfirst.c0000644000175000017500000000134113176557635015436 0ustar frankfrank#include "rss.ih" unsigned rs_findFirst(char const * fspec, unsigned attrib, struct find_t_ * fileinfo) { gr_nextGlob = 1; /* next globbed name */ /* expand file spec */ glob(fspec, GLOB_NOCHECK, rs_globerr, &gr_globData); if (! gr_globData.gl_pathc) /* no files: -1 return */ return ~0; strcpy (fileinfo->name, rs_filename(gr_globData.gl_pathv[0])); /* synthetise attribute */ fileinfo->attrib = rs_makeAttribute(gr_globData.gl_pathv[0]); if (fileinfo->attrib == 0xdead ) return ~0; return 0; } icmake-9.02.06/rss/rsjoin.c0000644000175000017500000000013713176557635014407 0ustar frankfrank#include "rss.ih" void rs_join(void) { rss_makePath(gr_name, gr_dir, gr_fname, gr_ext); } icmake-9.02.06/rss/realloc.c0000644000175000017500000000146613176557635014532 0ustar frankfrank/* {\em rss_realloc()} attempts to reallocate the memory pointed to by {\em ptr}. If {\em ptr} is NULL, {\em rss_realloc()} simply behaves like {\em malloc()}. When allocation indicates failure, {\em error()} is called to terminate the program with an appropriate message. The new requested size may be zero. In this case, {\em rss_realloc()} frees the memory associated with {\em ptr}. */ /* #define msg */ #include "rss.ih" void *rss_realloc (void *ptr, unsigned size) { register void *newptr; if (! size) { if (ptr) free (ptr); return NULL; } newptr = ptr != NULL ? realloc(ptr, size) : malloc (size); if (! newptr) rss_fatal(0, 0, "out of memory"); return newptr; } icmake-9.02.06/rss/getint16.c0000644000175000017500000000107213176557635014543 0ustar frankfrank/* This function reads a 16-bit signed integer value from the binary macro file, supplied as argument. It may be used, e.g., to read an argument of a {\em op\_asp} opcode. The returned result may be cast to {\em unsigned} by the caller. */ #include "rss.ih" int16_t rss_getInt16(FILE *infile) { int16_t tmp; register int32_t offs; offs = ftell (infile); if (! fread (&tmp, sizeof (int16_t), 1, infile) ) rss_fatal(0, 0, "argument read error at offset %u", (unsigned) offs); return tmp; } icmake-9.02.06/rss/rss.ih0000644000175000017500000000230013176557635014062 0ustar frankfrank#include "rss.h" #include #include #include #include #include #include #include extern glob_t gr_globData; /* globbing struct */ extern unsigned gr_nextGlob; /* next name in list */ extern unsigned gr_nErrors; extern char gr_name[]; extern char gr_dir[]; extern char gr_fname[]; extern char gr_ext[]; extern char gr_hexDigits[]; extern IcmakeFind gr_ifs; /* icmake find-struct */ unsigned rs_findFirst(char const *, unsigned, struct find_t_ *); unsigned rs_findNext(struct find_t_ *); char *rs_filename(char *fname); /* return pointer into frame, just beyond dir. name */ int rs_makeAttribute(char *fname); /* make DOS attribs */ int rs_globerr(char const *path, int errnr); void rs_split(char const *n); /* calls rss_split */ void rs_join(void); /* calls rss_makePath */ char *rs_fileFound(void); /* test attrib/pattern */ void rs_msg(char const *src, unsigned lineNr, /* !src: no source info */ char const *prefix, char const *fmt, va_list args); icmake-9.02.06/rss/hexstring.c0000644000175000017500000000200213176557635015107 0ustar frankfrank/* \funcref{rss_hexString}{char $*$rss_hexString (\params)} { {uint16_t} {val} {value to convert} {uint16_t} {len} {requested string length} } {stringrepresentation of {\em val}} {} {} {hexstrin.c} { This function converts a value {\em val} to hexadecimal representation in a string with length {\em len}. The string may be preceded by zero's to ensure the length. The result of the conversion is stored in a static buffer, which is returned. Repetitive calls to {\em rss_hexString()} will overwrite this buffer. {\bf Note that} {\em len} may not exceed 9. The size of the static buffer is only 10 chars. } */ #include "rss.ih" char *rss_hexString(unsigned val, unsigned len) { register int dlen = len; /* until %zd format is generally available */ static char retbuf[10]; char buf[10]; sprintf (buf, "%%%d.%dx", dlen, dlen); sprintf (retbuf, buf, (uint16_t)val); return retbuf; } icmake-9.02.06/rss/warning.c0000644000175000017500000000027313176557635014551 0ustar frankfrank#include "rss.ih" void rss_warning(char const *src, unsigned lineNr, char const *fmt, ...) { va_list args; va_start(args, fmt); rs_msg(src, lineNr, "Warning", fmt, args); } icmake-9.02.06/rss/younger.c0000644000175000017500000000104313176557635014570 0ustar frankfrank#include "rss.ih" // a younger b, a newer b: returns 1 if file a is more recent than file b. The // files a and b do not have to exist: if both don’t exist 0 is returned; if b // doesn’t exist, 1 is returned; if a doesn’t exist 0 is returned; if they are // equally old 0 is returned. int rss_younger(char const *lval, char const *rval) { struct stat lbuf, rbuf; if (stat(lval, &lbuf)) lbuf.st_mtime = 0; if (stat(rval, &rbuf)) rbuf.st_mtime = 0; return lbuf.st_mtime > rbuf.st_mtime; } icmake-9.02.06/rss/exists.c0000644000175000017500000000037513176557635014426 0ustar frankfrank/* The function returns 1 if the filename given as its argument exists. Otherwise, 0 is returned. Path can be NULL */ /*#define msg */ #include "rss.ih" int rss_exists(char const *path) { struct stat buf; return !stat(path, &buf); } icmake-9.02.06/rss/findnext.c0000644000175000017500000000062613176557635014725 0ustar frankfrank#include "rss.ih" char *rss_findNext() { char *cp; /* pointer to matched filename */ while (!rs_findNext(&gr_ifs.find)) /* find next entry */ { if ( (cp = rs_fileFound()) ) /* file found ? */ return (cp); /* return its name */ } return (NULL); /* none found */ } icmake-9.02.06/rss/rsmsg.c0000644000175000017500000000045313176557635014237 0ustar frankfrank#include "rss.ih" void rs_msg(char const *src, unsigned lineNr, char const *prefix, char const *fmt, va_list args) { if (src) fprintf(stderr, "[%s, line %u] ", src, lineNr); fprintf(stderr, "%s: ", prefix); vfprintf(stderr, fmt, args); fputc('\n', stderr); } icmake-9.02.06/rss/getext.c0000644000175000017500000000030213176557635014375 0ustar frankfrank#include "rss.ih" char const *rss_getExt(char const *path) { rs_split(path); return *gr_ext == '.' ? rss_strdup(gr_ext + 1) : gr_ext; } icmake-9.02.06/rss/error.c0000644000175000017500000000026513176557635014236 0ustar frankfrank#include "rss.ih" void rss_error(char const *src, unsigned lineNr, char const *fmt, ...) { va_list args; va_start(args, fmt); rss_errorList(src, lineNr, fmt, args); } icmake-9.02.06/rss/errorlist.c0000644000175000017500000000033613176557635015131 0ustar frankfrank#include "rss.ih" void rss_errorList(char const *src, unsigned lineNr, char const *fmt, va_list args) { rs_msg(src, lineNr, "Error", fmt, args); ++gr_nErrors; } icmake-9.02.06/rss/types.ih0000644000175000017500000001425213176557635014430 0ustar frankfrank#include typedef enum { WAIT = 0, /* wait for child processes to return */ MAX_PATHLEN = 260, MAX_CMDLEN = 500, /* the max command line length * */ DIRSEP = '/', } Varia; typedef enum { REQUIRE_ZERO = 0, NOT_CHECKED = 2 } ReturnCheck; typedef enum { IS_FILE = 1, IS_DIR = 2, IS_SUBDIR = 4, IS_ALL = 8 } Dir_attributes; typedef enum { IS_IFDIR = 1, IS_IFCHR = 2, IS_IFREG = 4, IS_IREAD = 8, IS_IWRITE = 16, IS_IEXEC = 32 } IS_attributes; typedef enum { NORMAL_FILE = 0x00, READONLY_FILE = 0x01, HIDDEN_FILE = 0x02, SYSTEM_FILE = 0x04, VOLUME_ID = 0x08, SUBDIR = 0x10, ARCHIVED = 0x20 } File_attributes; typedef enum { e_null = 0, /* rss + compiler: */ e_int = (1 << 0), /* 1: int-type expression */ e_str = (1 << 1), /* 2: string-type expression */ e_list = (1 << 2), /* 4: list-type expression */ /* compiler only: */ e_bool = (1 << 3), /* 8: bool-type expression */ e_typeMask = (e_int | e_list | e_str | e_bool), e_const = (1 << 4), /* 0x10 immediate value */ e_var = (1 << 5), /* 0x20 variable */ e_reg = (1 << 6), /* 0x40 register */ e_stack = (1 << 7), /* 0x80 value available on the stack */ e_pre_inc_dec = (1 << 8), /* pre-inc or pre-dec */ e_post_inc_dec = (1 << 9) /* post-inc or post-dec */ } ExprType; /* when the ordering or entries of the following enum changes, update icmun/data.c, icm-comp/parser/data.c and icm-exec/builtin/data.c as well en rebuild all programs. It will also change the contents of the .bim file, so it also requires at least a minor version upgrade. */ typedef enum /* names of rss-functions */ { /* 0 */ f_arg_head, f_arg_tail, f_ascii_int, /* return int */ f_ascii_str, /* return str */ /* 4 */ f_backtick, f_c_base, f_c_ext, f_c_path, /* 8 */ f_chdir, f_cmd_head, f_cmd_tail, f_echo, /* c */ f_element, f_eval, f_exec, f_execute, /* only used by the compiler */ /* 10 */ f_exists, f_fgets, f_fprintf, f_g_base, /* 14 */ f_g_dext, f_g_ext, f_g_path, f_getch, /* 18 */ f_getenv, f_getpid, f_gets, f_listlen, /* 1c */ f_makelist, f_printf, f_putenv, f_stat, /* 20 */ f_str_el, f_strfind, f_strformat, f_strlen, /* 24 */ f_strlwr, f_resize, f_strtok, f_strupr, /* 28 */ f_substr, f_system, f_trim, f_trimleft, /* 2c */ f_trimright, f_strchr, f_listfind, f_listunion, /* 30 */ /* 17 left for new opcodes until f_hlt */ f_hlt = f_trimright + 21 /* dummy marker for non-existing */ } FunNr; /* update icm-exec and icmun's data files if the next enum changes */ typedef enum { /* hexnr: */ op_jmp, /* 00 */ op_jmp_false, /* 01 */ op_jmp_true, /* 02 */ op_push_1_jmp_end, /* 03 */ op_push_0, /* 04 */ op_push_imm, /* 05 */ op_push_strconst, /* 06 */ op_push_var, /* 07 */ op_push_reg, /* 08 */ op_pop_var, /* 09 */ op_umin, /* 0a */ op_atoi, /* 0b */ op_itoa, /* 0c */ op_atol, /* 0d */ op_mul, /* 0e */ op_div, /* 0f */ op_mod, /* 10 */ op_add, /* 11 */ op_sub, /* 12 */ op_eq, /* 13 */ op_neq, /* 14 */ op_sm, /* 15 */ op_gr, /* 16 */ op_younger, /* 17 */ op_older, /* 18 */ op_smeq, /* 19 */ op_greq, /* 1a */ op_call_rss, /* 1b */ op_asp, /* 1c */ op_exit, /* 1d */ op_copy_var, /* 1e */ op_inc, /* 1f */ op_dec, /* 20 */ op_call, /* 21 */ op_frame, /* 22 */ op_ret, /* 23 */ op_pop_reg, /* 24 */ op_band, /* 25 */ op_bor, /* 26 */ op_bnot, /* 27 */ op_xor, /* 28 */ op_shl, /* 29 */ op_shr, /* 2a */ op_hlt = op_shr + 10/* .. */ } Opcode; struct find_t_ /* abbreviated variant */ { char name[MAX_PATHLEN]; unsigned attrib; /* returned attribute */ }; typedef struct { unsigned attrib; /* requested attribute */ struct find_t_ find; } IcmakeFind; typedef struct { char version[4]; int32_t offset[4]; } BinHeader; /* see header structure at BOF */ typedef struct { uint16_t size; char **element; /* used as (char *) by icmcomp */ } List; typedef struct { union { uint16_t nShared; /* allocation count */ uint16_t address; /* addr. of 1st byte of a function */ }; union { char *str; List list; }; } TextData; typedef struct /* defined variable */ { ExprType type; /* maybe stringconst, int, list */ union { int16_t intValue; /* value of an int */ TextData *data; /* intermediate alloc. structure */ }; } Variable; icmake-9.02.06/rss/rsfilename.c0000644000175000017500000000053713176557635015234 0ustar frankfrank#include "rss.ih" char *rs_filename(char *fname) /* return pointer into */ { /* fname, just beyond */ register char *cp; /* directory name */ return (cp = strrchr(fname, DIRSEP)) && *(cp + 1) ? cp + 1 : fname; } icmake-9.02.06/rss/rsfilefound.c0000644000175000017500000000456013176557635015427 0ustar frankfrank/* With the MS-DOS implementation the received attribute is compared to the request: IS_FILE: accepts only NORMAL_FILE, ARCHIVED/A_READ with NORMAL_FILE accepted IS_DIR: accepts only SUBDIR IS_SUBDIR: accepts only SUBDIR, but not the . and .. IS_ALL: accepts all Not yet supported: O_VOLID: accepts VOLUME_ID */ #include "rss.ih" char *rs_fileFound() { register unsigned request, received; received = gr_ifs.find.attrib; /* use fast registers */ request = gr_ifs.attrib; /* First part: see if request */ /* matches attribute of entry */ if /* (list all accepted variants) */ ( ! /* if not: */ ( ( (request & IS_FILE) /* FILE requested, and */ && /* an attribute received */ ! /* indicating that it's no file */ ( received & (SUBDIR | HIDDEN_FILE | SYSTEM_FILE | VOLUME_ID) ) ) || ( (request & (IS_SUBDIR | IS_DIR)) /* OR: any subdir requested */ && /* and SUBDIR received */ (received & SUBDIR) ) || ( (request & IS_ALL) /* OR: ALL requested */ && /* and not volume label received */ !(received & VOLUME_ID) ) ) ) return (NULL); /* then reject the entry */ /* Second part: IS_SUBDIR (overruled by IS_ALL / IS_DIR) */ /* entries '.' and '..' are rejected */ if ( !(request & (IS_DIR | IS_ALL)) /* not IS_DIR / IS_ALL requested, */ && /* AND */ (request & IS_SUBDIR) /* clean subdir requested */ && /* AND */ ( !strcmp(gr_ifs.find.name, ".") /* . or .. found */ || !strcmp(gr_ifs.find.name, "..") ) ) return (NULL); /* then reject the entry */ return (gr_ifs.find.name); /* return found name */ } icmake-9.02.06/rss/icm_bootstrap0000755000175000017500000000031313176557635015526 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/libicrss.a echo -n . try ${CC} -c ${CFLAGS} *.c echo -n . try ar rs ../tmp/libicrss.a *.o echo -n . rm *.o echo . icmake-9.02.06/rss/changebase.c0000644000175000017500000000032413176557635015161 0ustar frankfrank#include "rss.ih" char *rss_changeBase(char const *path, char const *base) { rs_split(path); *gr_fname = 0; if (base) strcpy(gr_fname, base); rs_join(); return rss_strdup(gr_name); } icmake-9.02.06/rss/fgetz.c0000644000175000017500000000047013176557635014222 0ustar frankfrank#include "rss.ih" char *rss_fgetz (char *buf, unsigned maxlen, FILE *f) { register unsigned i; if (! maxlen) return (NULL); for (i = 0; i < maxlen - 1; i++) { buf [i] = fgetc (f); if (! buf [i]) break; } buf [i] = '\0'; return (buf); } icmake-9.02.06/rss/getstring.c0000644000175000017500000000241513176557635015112 0ustar frankfrank/* Function {\em getstring()} can be used to retrieve a string from the binary makefile. The string is identified by the offset of the string section within the file (the first {\em int32_t} value in the file) and by the offset of the string itself within the string section. {\em getstring()} returns a pointer to allocated memory, holding the read string. The caller is responsible for freeing this memory. Value --1 is returned when the reading failed; i.e., when file positioning failed or when no string was found at the specified position. */ /* #define msg */ #include "rss.ih" char *rss_getString(FILE *f, int32_t stringsec, unsigned stringofs) { int32_t curoffs; char buf [80]; register char *ret = NULL; register int done = 0; curoffs = ftell(f); if (fseek(f, stringsec + (int32_t)stringofs, SEEK_SET)) return (char *)-1; msg("Reading string at offset 0x%x", stringsec + (int32_t)stringofs); while (! done) { if (! rss_fgetz (buf, 79, f)) return (char *)-1; msg("read: %s", buf); ret = rss_strcat(ret, buf); if (strlen (buf) < 78) ++done; } fseek (f, curoffs, SEEK_SET); return ret; } icmake-9.02.06/rss/findfirst.c0000644000175000017500000000123313176557635015071 0ustar frankfrank#include "rss.ih" char *rss_findFirst(char const *fspec, unsigned attrib) { char *cp; /* pointer to matched filename */ gr_ifs.attrib = attrib; /* initialize gr_ifs */ /* find all entries */ if (rs_findFirst(fspec, (unsigned)-1, &gr_ifs.find)) return NULL; /* failed already: return NULL */ cp = rs_fileFound(); return cp ? cp /* attrib/pattern ok: return */ : rss_findNext(); /* or retry a match */ } icmake-9.02.06/rss/getbase.c0000644000175000017500000000014413176557635014513 0ustar frankfrank#include "rss.ih" char const *rss_getBase(char const *n) { rs_split(n); return gr_fname; } icmake-9.02.06/rss/spawnerr.c0000644000175000017500000000203213176557635014740 0ustar frankfrank/* This function can be called when an {\em exec()} or {\em spawn()} call indicates failure (by returning -1). Argument {\em progname} should indicate the program which should have been executed. An appropriate error message is printed and the program is halted. */ #include "rss.ih" void rss_spawnErr(char const *progname) { static char errmsg [] = "Can't exec %s: %s"; switch (errno) { case E2BIG: rss_fatal(0, 0, errmsg, progname, "command line too big"); case EACCES: rss_fatal(0, 0, errmsg, progname, "access denied"); case EMFILE: rss_fatal(0, 0, errmsg, progname, "too many open files"); case ENOENT: rss_fatal(0, 0, errmsg, progname, "no such file"); case ENOEXEC: rss_fatal(0, 0, errmsg, progname, "exec file format"); case ENOMEM: rss_fatal(0, 0, errmsg, progname, "out of memory"); default: rss_fatal(0, 0, errmsg, progname, "unknown error"); } } icmake-9.02.06/rss/getvar.c0000644000175000017500000000464713176557635014405 0ustar frankfrank/* Function {\em rss_getVar()} attempts to read the variables defined in a binary makefile. Argument {\em headerp} is expected to point to a {\em BIN\_HEADER\_} struct filled with header information. {\em var} is the address of a pointer to {\em VAR\_} structures. {\em rss_getVar()} reallocates the pointer as necessary; therefore, {\em $*$var} must point to allocated memory or must be {\em NULL}. For each created variable of the type {\bf list} or {\bf string}, data field is set to {\em NULL} reflecting that the variable is not yet in use. When no error occurs, {\em rss_getVar()} returns the number of read variables and restores the file pointer {\em f} to the location prior to reading. When an error occurs, {\em --1} is returned and the file pointer is not repositioned. */ /* #define msg */ #include "rss.ih" uint16_t rss_getVar(Variable **varDest, FILE *f, BinHeader *headerp) { register unsigned varIdx = 0; register Variable *var = NULL; int32_t curoffs; if (headerp->offset[1] == headerp->offset[2]) return 0; curoffs = ftell(f); if (fseek(f, headerp->offset[1], SEEK_SET)) return (uint16_t)-1; unsigned nVars = 0; msg("begin offset: %x, end offset: %x", headerp->offset[1], \ headerp->offset[2]); while (ftell(f) < headerp->offset[2]) { ++nVars; /* make room for the next variable record */ var = rss_realloc(var, nVars * sizeof(Variable)); char type; if (! fread(&type, sizeof(char), 1, f)) rss_fatal(0, 0, "cannot read the variable section"); msg("read variable %u, offset at: %x", nVars, ftell(f)); /* Need to receive one single standard type. One type is 1 bit, so if no bits are set or if more than one bit has been set (using the power of 2 trick) an invalid type was read */ if (type == e_null || type & (type - 1)) rss_fatal(0, 0, "bad variable type (var #%d)\n", nVars); /* initialize the new variable to 0 */ memset(var + varIdx, 0, sizeof(Variable)); var[varIdx].type = type; ++varIdx; } *varDest = var; /* set the external pointer */ fseek (f, curoffs, SEEK_SET); return nVars; } icmake-9.02.06/rss/fatal.c0000644000175000017500000000033313176557635014170 0ustar frankfrank#include "rss.ih" void rss_fatal(char const *src, unsigned lineNr, char const *fmt, ...) { va_list args; va_start(args, fmt); rs_msg(src, lineNr, "Fatal", fmt, args); ++gr_nErrors; exit(1); } icmake-9.02.06/rss/getdext.c0000644000175000017500000000024413176557635014546 0ustar frankfrank#include "rss.ih" char const *rss_getDext(char const *n) /* including the dot */ { rs_split(n); return *gr_ext == '.' ? rss_strdup(gr_ext) : gr_ext; } icmake-9.02.06/rss/programname.c0000644000175000017500000000135713176557635015420 0ustar frankfrank/* ported to non-MSDOS systems pwp 93 07 15 {The function modifies the full pathname of the program by removing the extension (e.g., {\sc .exe}), and returns a pointer to the first character of the basename of the function. Note well that the extension is removed from the original string, and that the returned pointer points sowhere inside the original string. The function {\em assumes\,} a path in which at least one DIRSEP precedes the first character of the program name. The program name may or may notr have an extension. This is not checked. } */ #include "rss.ih" char const *rss_programName(char const *argv) { register char *d; return (d = strrchr(argv, DIRSEP)) != NULL ? d + 1 : argv; } icmake-9.02.06/rss/getpath.c0000644000175000017500000000034213176557635014535 0ustar frankfrank#include "rss.ih" char const *rss_getPath(char const *n) { register int last; rs_split(n); last = strlen(gr_dir); if (last && gr_dir[last - 1] != DIRSEP) gr_dir[last] = DIRSEP; return gr_dir; } icmake-9.02.06/rss/copyright.c0000644000175000017500000000037513176557635015117 0ustar frankfrank#include "rss.ih" void rss_copyright(char const *program) { printf("\n" "%s by Frank B. Brokken (f.b.brokken@rug.nl)\n" "%s V%s, copyright (c) GPL %s.\n" "\n", program, program, version, release); } icmake-9.02.06/rss/data.c0000644000175000017500000000062313176557635014014 0ustar frankfrank#include "rss.ih" glob_t gr_globData; /* globbing struct */ unsigned gr_nextGlob; /* next name in list */ unsigned gr_nErrors; char gr_name[MAX_PATHLEN]; char gr_dir[MAX_PATHLEN]; char gr_fname[MAX_PATHLEN]; char gr_ext[MAX_PATHLEN]; IcmakeFind gr_ifs; /* icmake find-struct */ char gr_hexDigits[] = "0123456789abcdef"; icmake-9.02.06/rss/rss.h0000644000175000017500000000643313176557635013724 0ustar frankfrank#ifndef _INCLUDED_RSS_H_ #define _INCLUDED_RSS_H_ #include "types.ih" #include #include extern char version[]; extern char release[]; inline int rss_checkMode(int mode) { return !(mode & NOT_CHECKED); } void rss_makePath(char *path, char const *dir, char const *fname, char const *ext); void rss_splitPath(char const *path, char *dir, char *fname, char *ext); /* The rss_change* functions return dynamically allocated NTBSs */ char *rss_changeExt(char const *path, char const *ext); /* adds . unless already in ext */ char *rss_changeBase(char const *path, char const *base); char *rss_changePath(char const *path, char const *newDirs); void rss_copyright(char const *program); /* copyright message */ char *rss_findFirst(char const *fspec, unsigned attrib); char *rss_findNext(void); /* remaining matching entries */ char *rss_fgetz (char *, unsigned, FILE *); char const *rss_getExt(char const *path); char const *rss_getDext(char const *path); char const *rss_getBase(char const *path); char const *rss_getPath (char const *path); char *rss_getString(FILE *, int32_t, unsigned); char *rss_hexString (unsigned, unsigned); /* make programname from argv[0] */ char const *rss_programName(char const *argv0); char *rss_strdup(char const *str); /* duplicates 'str ? str : ""' */ char *rss_strcat(char *s1, char const *s2); /* resizes and returns s1 */ char *rss_strjoin(char const *s1, char const *s2); /* new s1|s2 */ char *rss_trimLeft(char const *begin); /* returns newly allocated ntbs */ char *rss_trimRight(char const *begin); void rss_msg_(char const *path, char *fmt, ...); /* prints a msg to stderr. Use it by doing #define msg before reading rss.h, and then call msg(fmt, ...) to specify a message */ void rss_fatal(char const *src, unsigned lineNr, char const *fmt, ...); void rss_error(char const *src, unsigned lineNr, char const *fmt, ...); void rss_errorList(char const *src, unsigned lineNr, char const *fmt, va_list args); void rss_warning(char const *src, unsigned lineNr, char const *fmt, ...); unsigned rss_nErrors(); void rss_spawnErr(char const *program); void *rss_realloc(void *oldPtr, unsigned size_in_bytes); int rss_exists(char const *path); /* 0 is returned if path exists. path can be NULL */ int rss_older(char const *, char const *); int rss_younger(char const *, char const *); int16_t rss_getInt16(FILE *); Opcode rss_getOpcode (FILE *); uint16_t rss_getVar(Variable **varVector, FILE *bimFile, BinHeader *hdr); BinHeader *rss_readHeader(FILE *f, unsigned v); /* to activate msg(...) calls do '#define msg' before reading rssh.h */ #ifdef msg #undef msg #define msg(...) rss_msg_(__FILE__, __VA_ARGS__) #else #undef msg #define msg(...) #endif #endif icmake-9.02.06/rss/rsfindnext.c0000644000175000017500000000120413176557635015263 0ustar frankfrank#include "rss.ih" unsigned rs_findNext(struct find_t_ * fileinfo) { if (gr_nextGlob >= gr_globData.gl_pathc) /* done with list ? */ { globfree (&gr_globData); /* yes.. free data */ return ~0; } strcpy (fileinfo->name, /* make next name available */ rs_filename(gr_globData.gl_pathv [gr_nextGlob])); /* make attribute */ fileinfo->attrib = rs_makeAttribute (gr_globData.gl_pathv[gr_nextGlob]); ++gr_nextGlob; /* set next name index */ return 0; } icmake-9.02.06/rss/strdup.c0000644000175000017500000000100713176557635014421 0ustar frankfrank/* {\em rss_strdup()} behaves like {\em strdup()}, except that when memory is exhausted (therefore, when the string cannot be duplicated) function {\em error()} is called to terminate the program. The string to duplicate, {\em s}, may be {\em NULL}. In this case a duplicate of a zero-length string is returned. */ #include "rss.ih" char *rss_strdup(char const *str) { register char *ret; if (!(ret = strdup(str ? str : ""))) rss_fatal(0, 0, "out of memory"); return ret; } icmake-9.02.06/rss/icmconf0000644000175000017500000000063013176557635014276 0ustar frankfrank#define USE_ECHO ON #define COMPILER "gcc" #define COMPILER_OPTIONS "-Wall -Werror -O2 -fdiagnostics-color=never" #define SOURCES "*.c" #define LINKER_OPTIONS "-s" #define ADD_LIBRARIES "" #define ADD_LIBRARY_PATHS "" #define CLS #define TMP_DIR "tmp" #define LIBRARY "icrss" #define OBJ_EXT ".o" #define DEFCOM "library" icmake-9.02.06/rss/build0000755000175000017500000000010513176557635013757 0ustar frankfrank#!/bin/bash icmbuild $1 [ "$1" == "" ] && cp tmp/libicrss.a ../tmp/ icmake-9.02.06/rss/trimright.c0000644000175000017500000000142613176557635015116 0ustar frankfrank/* #define msg */ #include "rss.ih" char *rss_trimRight(char const *begin) { char const *end = begin + strlen(begin); char org = *begin; *(char *)begin = 'S'; /* sentinel when looking for no ' ' */ while (isspace(*--end)) /* find the last non-ws char. pos */ ; ++end; *(char *)begin = org; /* restore the 1st char */ if (begin == end && !isspace(org)) /* accept 1st char if not isspace */ ++end; org = *end; *(char *)end = 0; /* terminate the reduced string */ char *ret = rss_strdup(begin); msg("trimmed: `%s'", ret); *(char *)end = org; /* restore the original contents */ return ret; } icmake-9.02.06/rss/nerrors.c0000644000175000017500000000010513176557635014570 0ustar frankfrank#include "rss.ih" unsigned rss_nErrors() { return gr_nErrors; } icmake-9.02.06/rss/readheader.c0000644000175000017500000000557113176557635015176 0ustar frankfrank/* Function {\em rss_readHeader()} attempts to read the header in a binary makefile and checks the major version numbers of the makefile and the program. When the header cannot be read or when the versions do not match, an error is issued. {\em rss_readHeader()} expects to be called prior to any reading from the binary file: the file pointer is not repositioned before or after the header processing. The return value points to a static {\em BIN\_HEADER\_} struct which is filled with information. The fields of the return value are: \begin{itemize} \item {\em ret$\rightarrow$version} : a string of four characters stating the version of the binary makefile. The string is {\bf not} terminated by `$\backslash$0'. \item {\em ret$\rightarrow$offset[0]} : an {\em int32_t} value stating the offset of the strings area. \item {\em ret$\rightarrow$offset[1]} : an {\em int32_t} value stating the offset of the variables area. \item {\em ret$\rightarrow$offset[2]} : an {\em int32_t} value stating the offset of the filenames area. \end{itemize} The strings area is present when the offset of this area is smaller than the offset of the variables area. The strings are represented as {\em ascii-z} strings. The variables area is present when the offset of this area is smaller than the offset of the filenames area. The variables are {\em VAR\_} structs. The filenames area is always present. The filenames are represented as `$\backslash$n'-terminated strings. */ #include "rss.ih" static BinHeader header; BinHeader *rss_readHeader(FILE *f, unsigned v) { struct stat buffer; int idx; int32_t f_size; if (! fread(&header, sizeof (BinHeader), 1, f) ) rss_fatal(0, 0, "cannot read header from binary file, corrupted?"); if ((unsigned)header.version[0] % 100 < v % 100) rss_fatal(0, 0, "The binary file was created with an older version of icmake.\n" "Remake the binary file."); if ((unsigned)header.version[0] < v ) rss_fatal(0, 0, "The binary file was created with an older version " "of icmake.\n" "Recompile the original script.\n"); if ((unsigned)header.version[0] > v) rss_fatal(0, 0, "This program does not support the version which is indicated" " by the binary\n" "file. Upgrade to a newer `icmake' version."); fstat(fileno(f), &buffer); f_size = buffer.st_size; for (idx = 0; idx != 4; ++idx) { if (header.offset[idx] >= f_size) rss_fatal(0, 0, "invalid .bim file, corrupted?"); } return &header; } icmake-9.02.06/rss/rssplit.c0000644000175000017500000000015213176557635014600 0ustar frankfrank#include "rss.ih" void rs_split(char const *path) { rss_splitPath(path, gr_dir, gr_fname, gr_ext); } icmake-9.02.06/rss/changepath.c0000644000175000017500000000031313176557635015201 0ustar frankfrank#include "rss.ih" char *rss_changePath(char const *path, char const *newDirs) { rs_split(path); if (newDirs) strcpy(gr_dir, newDirs); rs_join(); return rss_strdup(gr_name); } icmake-9.02.06/rss/trimleft.c0000644000175000017500000000022013176557635014722 0ustar frankfrank#include "rss.ih" char *rss_trimLeft(char const *begin) { while (isspace(*begin)) ++begin; return rss_strdup(begin); } icmake-9.02.06/rss/strcat.c0000644000175000017500000000102513176557635014400 0ustar frankfrank/* Function {\em rss_strcat()} reallocates the string {\em s1} and then concatenates {\em s2} to it. Therefore, the first argument of the function must point to allocated memory. The second argument may be any string, and can be freed after the call. */ #include "rss.ih" char *rss_strcat(char *s1, char const *s2) { if (!s1 || !*s1) return rss_strdup(s2); if (!s2 || !*s2) return rss_strdup(s1); s1 = rss_realloc(s1, strlen(s1) + strlen(s2) + 1); strcat(s1, s2); return s1; } icmake-9.02.06/rss/makepath.c0000644000175000017500000000232613176557635014677 0ustar frankfrank/* makepath.c pwp 93 07 14 replacement function _makepath for NON-MSDOS systems ONLY Arguments: path: buffer to contain the combined name; length MAX_PATHLEN this is NOT checked dir: directory string, can be NULL or empty (""); if not-empty, may have a trailing DIRSEP character fname: basename string, can be NULL or empty ("") ext: extension string, can be NULL or empty (""); if not empty, can have optional leading dot */ #include "rss.ih" static char dot[] = "."; void rss_makePath(char *path, char const *dir, char const *fname, char const *ext) { path[0] = 0; /* prepare for strcats */ if (dir && dir[0]) { strcat(path, dir); if (dir[strlen(dir) - 1] != DIRSEP) { unsigned l; path[l = strlen(path)] = DIRSEP; path[++l] = 0; /* make it an asciiz */ } } if (fname && fname[0]) strcat(path, fname); if (ext && ext[0]) { if (ext[0] != dot[0]) strcat(path, dot); strcat(path, ext); } } icmake-9.02.06/rss/frame0000644000175000017500000000004013176557635013745 0ustar frankfrank#include "rss.ih" void rs_ { } icmake-9.02.06/rss/splitpath.c0000644000175000017500000000217113176557635015113 0ustar frankfrank/* splitpath.c pwp 93 07 14 replacement function for _splitpath for NON-MSDOS systems ONLY Parameters: path: source path to be split The drive, dir fname, ext parameters are buffers provided by the caller; they should be large enough; this is NOT checked dir: directory part of path; if found, contains the leading DIRSEP fname: the base file name without extensions ext: the extension, if any, including the leading period */ #include "rss.ih" void rss_splitPath(char const *path, char *dir, char *fname, char *ext) { char *p; if ( (p = strrchr(path, DIRSEP)) ) { char fname_first; fname_first = *(++p); *p = '\x0'; strcpy(dir, path); *p = fname_first; path = p; /* path now points to filename part */ } else dir[0] = '\x0'; if ( (p = strrchr(path, '.')) ) { *p = '\x0'; strcpy(fname, path); *p = '.'; strcpy(ext, p); } else { strcpy(fname, path); ext[0] = '\x0'; } } icmake-9.02.06/rss/msg.c0000644000175000017500000000044313176557635013671 0ustar frankfrank#include "rss.ih" /* Prints a msg to stderr. Use it by doing '#define msg' before reading rss.h, and then call msg(fmt, ...) to specify a message */ void rss_msg_(char const *path, char *fmt, ...) { va_list args; va_start(args, fmt); rs_msg(0, 0, path, fmt, args); } icmake-9.02.06/rss/older.c0000644000175000017500000000156013176557635014211 0ustar frankfrank/* O L D E R . C % 1 name \funcref {older} % 2 declaration {int \fname (\params\ )} % 3 arguments { {char *}{lval}{name of a file} {char *}{rval}{name of a file} } % 4 return value { 1: the file \Var{lval} is older than \Var{rval} or \Var{rval} does't exist. \Var{lval} exists. 0: the reversed condition: the file \Var{lval} is younger or as old as \Var{rval} (\Var{rval} exists), or \Var{lval} doesn't exist } % 5 functions used {} % 6 see also {} % 7 source file {older.c} % 8 description {See the return value description} */ #include "rss.ih" int rss_older(char const *lval, char const *rval) { struct stat lbuf, rbuf; if (stat(lval, &lbuf)) lbuf.st_mtime = 0; if (stat(rval, &rbuf)) rbuf.st_mtime = 0; return (lbuf.st_mtime < rbuf.st_mtime); } icmake-9.02.06/rss/version.c0000644000175000017500000000024513176557635014570 0ustar frankfrank/* V E R S I O N . C */ #include "../rss/rss.ih" #include "../tmp/INSTALL.im" char version[] = VERSION, release[] = YEARS; icmake-9.02.06/rss/rsmakeattribute.c0000644000175000017500000000151013176557635016305 0ustar frankfrank#include "rss.ih" int rs_makeAttribute(char *fname) /* make DOS attribs */ { register int ret = 0; /* returned attribute */ struct stat statbuf; /* stat () buffer */ if (stat(fname, &statbuf) == -1) /* if not stat-able .. */ return 0xdead; /* dead flag return */ if (S_ISDIR(statbuf.st_mode)) /* directory entry */ ret |= SUBDIR; if (!(statbuf.st_mode & S_IWUSR)) /* S_IWRITE: not POSIX */ ret |= READONLY_FILE; /* non-writable entry */ if (*fname == '.' && /* .file */ strcmp(fname, ".") && strcmp(fname, "..") ) ret |= HIDDEN_FILE; return ret; /* return attrib */ } icmake-9.02.06/scripts/0000755000175000017500000000000013237046464013605 5ustar frankfrankicmake-9.02.06/scripts/icmbuild.in0000644000175000017500000003637113237046464015737 0ustar frankfrank#include "icmconf" #ifndef SHAREDREQ #define SHAREDREQ "" #endif #ifdef USE_VERSION #include "VERSION" #else #define VERSION "0.00.00" #endif #ifndef ICM_DEP #define ICM_DEP "-V go" #endif string g_command; // command to execute string g_sources; // Pattern for the sources to use string g_libpath; // the extra library paths string g_libs; // the extra libraries list g_classes; // all class-directories int g_nClasses; // number of class-directories int g_compiled; // any source compiled (but main)? list g_classLines; // list of all lines in CLASSES list g_classLine; // line of the CLASSES file list g_buildprog = strtok("program strip", " "); int g_base; // compile the sources in the base directory int g_chdir; // display chdirs to directories without sources to // compile string g_version = VERSION; string g_compiler; string g_cwd = chdir(""); // initial working directory void md(string dir) { if (!exists(dir)) system("mkdir -p " + dir); } void showCd(string dir) { if (USE_ECHO) printf("\n" "chdir ", dir, "\n"); } string setOpt(string install_im, string envvar) { list optvar = getenv(envvar); return optvar[0] == "1" ? optvar[1] : install_im; } void setGcompiler() { // try a C++ compiler; if not found: try a C compiler; if not found // try COMPILER. // Same for matching options. #ifdef CXX g_compiler = setOpt(CXX, "CXX") + " " + setOpt(CXXFLAGS, "CXXFLAGS"); #else #ifdef CC g_compiler = setOpt(CC, "CC") + " " + setOpt(CFLAGS, "CFLAGS"); #else #ifdef COMPILER #ifdef COMPILER_OPTIONS g_compiler = COMPILER + " " + COMPILER_OPTIONS; #endif #endif // COMPILER #endif // CC #endif // CXX } list patternList(string pattern) { list ret; list in = strtok(pattern, " \t"); for (int idx = listlen(in); idx--; ) ret += makelist(in[idx]); return ret; } #ifdef PARSER_DIR void parser() { chdir(PARSER_DIR); list gramfiles = makelist(PARSSPEC); #ifdef PARSFILES gramfiles += makelist(PARSFILES); #endif for (int idx = listlen(gramfiles); idx--; ) { if (gramfiles[idx] younger PARSOUT) // need new parser { showCd(PARSER_DIR); if (USE_ECHO) printf("New parser: `", gramfiles[idx], "' changed\n"); system(PARSGEN " " PARSFLAGS " " PARSSPEC); break; } } chdir(".."); } #endif #ifdef SCANNER_DIR void scanner() { chdir(SCANNER_DIR); int rerun = PARSER_DIR != "" && "../"PARSER_DIR"/"PARSOUT younger SCANOUT; if (!rerun) { list scanfiles = makelist(PARSSPEC) + makelist(SCANSPEC); #ifdef SCANFILES scanfiles += makelist(SCANFILES); #endif for (int idx = listlen(scanfiles); idx--; ) { if (scanfiles[idx] younger SCANOUT) { showCd(SCANNER_DIR); rerun = 1; break; } } } if (rerun) system(SCANGEN " " SCANFLAGS " " SCANSPEC); chdir(".."); } #endif int isEmpty(string line) // needs stripped line { return strlen(line) == 0 || line[0] == "#" || strfind(line, "//") == 0; } int lineRead() { g_classLine = fgets("CLASSES", g_classLine); return listlen(g_classLine) && g_classLine[2] == "OK"; } list nextCLASSESline() // return entries of CLASSES as a list { string ret; // get the next line from CLASSES: while (lineRead()) { string line = trim(g_classLine[0]); // remove blanks if (isEmpty(line)) // nothing there { if (strlen(ret) != 0) // ret already contains txt break; // so we're done } else // the next line isn't empty { int last = strlen(line) - 1; int backslash = line[last] == "\\"; if (backslash) // its last char is backsl. line = trimright(resize(line, last)); // remove it and // trim rhs blanks ret += line + " "; // append line if (! backslash) // done unless backslash break; } } if (!isEmpty(ret)) g_classLines += (list)ret; return strtok(ret, " \t"); } void setClasses() { #ifdef SCANNER_DIR // make sure that scanner/parser // directories come first, so they // don't get reordered if (SCANNER_DIR != "") g_classes = (list)SCANNER_DIR; // add the scanner-dir #endif #ifdef PARSER_DIR if (PARSER_DIR != "") g_classes += (list)PARSER_DIR; #endif list class; while (listlen(class = nextCLASSESline())) g_classes = listunion(g_classes, class[0]); // g_classLines contains the full lines of the CLASSES file, and thus // stores its dependencies. g_nClasses = listlen(g_classes); } list inspect(string destDir, int prefix, string srcDir, list srcList, string library) { string oprefix = destDir + "/" + (string)prefix; srcDir += "/"; #ifdef USE_ALL string all = srcDir + USE_ALL; #endif for (int idx = listlen(srcList); idx--; ) { string file = srcList[idx]; string source = srcDir + file; string ofile = oprefix + change_ext(file, "o"); // make o-filename // A file s must be recompiled if: // the ofile exists and is older than ALL // the ofile doesn't exist but the lib. exists and is older than ALL // neither the ofile nor the lib. exists and ALL exists // if ALL doesn't exist it must be recompiled if: // it's newer than its object file o or newer than its target // library l, // if neither o nor l exist. // Since `a newer b' is true if a is newer than b, or if a exists and // b doesn't exist s must be compiled if s newer o and s newer l. // So, it doesn't have to be compiled if s older o or s older l. // redo if file has changed #ifdef USE_ALL if (ofile older all) srcList += (list)file; else #endif if (source older ofile || source older library) srcList -= (list)file; } return srcList; } void c_compile(int prefix, string destDir, string srcDir, list cfiles) { showCd(srcDir); if (srcDir != "") srcDir += "/"; string compiler = g_compiler + " -c -o " + destDir + "/" + (string)prefix; for (int idx = listlen(cfiles); idx--; ) { string file = cfiles[idx]; system(compiler + change_ext(file, OBJ_EXT) + " " + srcDir + file); g_compiled = 1; } } void std_cpp(int ignoreMain, string destDir, int prefix, string srcDir, string library) { chdir(""); // make list of all files md(destDir); chdir(srcDir); list files = makelist(g_sources); #ifdef MAIN if (ignoreMain) files -= (list)MAIN; #endif chdir(""); files = inspect(destDir, prefix, srcDir, files, library); if (listlen(files)) c_compile(prefix, destDir, srcDir, files); // compile files } void static_library() { #ifdef LIBRARY chdir(TMP_DIR "/o"); if (listlen(makelist("*" OBJ_EXT))) { showCd(TMP_DIR "/o"); system("ar cr ../lib" LIBRARY + ".a *" OBJ_EXT); system("ranlib ../lib" LIBRARY + ".a"); system("rm *" OBJ_EXT); } chdir(""); #endif } void shared_library(string libso, string libsoshared) { if (listlen(makelist("*/o/*.o"))) { string libsomajor = libso + "." + element(0, strtok(g_version, ".")); system(g_compiler + " -shared -Wl,--as-needed,-z,defs,-soname," + libsomajor + " -o " + TMP_DIR + "/" + libsoshared + " */o/*.o " SHAREDREQ); chdir(TMP_DIR); system("ln -sf " + libsoshared + " " + libsomajor); system("ln -sf " + libsomajor + " " + libso); system("rm o/*.o"); chdir(""); } } void precompile(string class) { #ifdef PRECOMP string classIH = class + IH; if (!exists(classIH)) { #ifndef NO_PRECOMP_WARNING printf("[Warning] CAN'T PRECOMPILE ", class, "/", classIH, " (unavailable)\n"); #endif return; } if (!exists(classIH + ".gch")) system(g_compiler + " " PRECOMP " " + classIH); #endif } void precompileHeaders() { list classes = makelist(O_SUBDIR, "*"); for (int idx = listlen(g_classes); idx--; ) { string class = g_classes[idx]; chdir(class); precompile(class); chdir(g_cwd); } } void build_libraries() { setClasses(); #ifdef PARSER_DIR if (PARSER_DIR != "") parser(); #endif #ifdef SCANNER_DIR if (SCANNER_DIR != "") scanner(); #endif if (strlen(ICM_DEP)) system("icmake -d " ICM_DEP); #ifdef PRECOMP precompileHeaders(); string mainBase; #ifdef MAIN mainBase = get_base(MAIN); #endif if (DEFCOM == "program" && mainBase != "") precompile(mainBase); #endif md(TMP_DIR); g_sources = SOURCES; g_compiled = 0; if ( exists("version.cc") && ( "VERSION" younger "version.cc" || "YEARS" younger "version.cc" || "AUTHOR" younger "version.cc" ) ) system("touch version.cc"); string staticLib; #ifdef LIBRARY staticLib = g_cwd + TMP_DIR "/lib" LIBRARY ".a"; #endif // compile all files in subdirs for (int idx = g_nClasses; idx--; ) std_cpp(0, TMP_DIR "/o", idx + 1, g_classes[idx], staticLib); // compile all files in g_cwd std_cpp(1, TMP_DIR "/o", 0, ".", staticLib); static_library(); // make the library #ifdef SHARED #ifdef LIBRARY string libso = "lib" LIBRARY ".so"; string libsoshared = libso + "." + g_version; // add option for shared lib g_compiler += " -fPIC "; for (int idx = g_nClasses; idx--; ) std_cpp(0, TMP_DIR "/o", idx + 1, g_classes[idx], libsoshared); // compile all files in g_cwd std_cpp(1, TMP_DIR "/o", 0, ".", libsoshared); shared_library(libso, libsoshared);// make a shared library #endif // LIBRARY #endif // SHARED chdir(""); } void setLibs() { list cut = strtok(ADD_LIBRARIES, " "); // cut op libraries int n = listlen(cut); for (int index = 0; index != n; ++index) g_libs += " -l" + cut[index]; cut = strtok(ADD_LIBRARY_PATHS, " "); // cut up the paths n = listlen(cut); for (int index = 0; index != n; ++index) g_libpath += " -L" + cut[index]; } void link(string maino, string strip) { if (g_command != "program") return; chdir(TMP_DIR); string compiler = g_compiler + " -o bin/binary " + maino; #ifdef LIBRARY compiler += " -l" LIBRARY " -L."; #else if (listlen(makelist("o/*" OBJ_EXT))) compiler += " o/*" OBJ_EXT; #endif setLibs(); if (strlen(g_libs)) compiler += g_libs + g_libpath; #ifdef LDFLAGS compiler += " " + setOpt(LDFLAGS, "LDFLAGS"); #else #ifdef LINKER_OPTIONS compiler += " " + LINKER_OPTIONS; #endif #endif #ifndef REFRESH if ( maino younger "bin/binary" #ifdef LIBRARY || "lib" LIBRARY ".a" younger "bin/binary" #endif || g_compiled ) #endif { showCd(TMP_DIR); printf("LINKING:\n"); system(compiler + " " + strip); } chdir(""); } void strip_shared() { #ifdef LIBRARY string libsoshared = "lib" LIBRARY ".so." + g_version; chdir(TMP_DIR); if (exists(libsoshared)) system("strip --strip-unneeded " + libsoshared); else printf("Can't find " TMP_DIR "/" + libsoshared + "\n"); #endif } #ifdef USE_ALL void rmUSE_ALLfiles() { echo(OFF); exec("find ./ -name " + USE_ALL + " -exec rm '{}' \\;"); echo(USE_ECHO); } #endif void program(string strip) { #ifdef MAIN string maino = change_ext(MAIN, OBJ_EXT); md(TMP_DIR "/bin"); #ifdef USE_ALL g_base = exists(USE_ALL); #endif build_libraries(); if (g_base || MAIN younger TMP_DIR "/" + maino) { printf("\n" "chdir .\n" "RECOMPILE: main.cc\n"); system(g_compiler + " -c -o " TMP_DIR "/" + maino + " " MAIN); } link(maino, strip); #ifdef USE_ALL rmUSE_ALLfiles(); #endif #endif exit(0); } void clean() { chdir(""); #ifdef USE_ALL system("rm -rf " USE_ALL " */" USE_ALL " " TMP_DIR); #else system("rm -rf " TMP_DIR); #endif #ifdef PRECOMP system("find ./ -type f -name \"*" IH ".gch\" -exec rm -f \\{\\} \\;"); #endif exit(0); } void install(string what, string path) { if (what == "program") { string dir = get_path(path); if (dir != "") md(dir); system("cp " TMP_DIR "/bin/binary " + path); } #ifdef LIBRARY else if (what == "static") { md(path); system("cp " TMP_DIR "/lib" LIBRARY ".a " + path); } #ifdef SHARED else if (what == "shared") { md(path); system("cp -d " TMP_DIR "/lib" LIBRARY ".so.* " + path); } #endif // SHARED #endif // LIBRARY exit(0); } void clearScreen(int cls) { if (cls) system("tput clear"); } void main(int argc, list argv, list envp) { echo(USE_ECHO); setGcompiler(); g_command = argv[1]; int cls; if (g_command == "-c") { cls = 1; g_command = argv[2]; } else cls = 0; #ifdef CLS cls = 1; #endif #ifdef DEFCOM if (g_command == "") { argv = (list)"" + strtok(DEFCOM, " \t"); g_command = argv[1]; } #endif if (g_command == "clean") clean(); if (g_command == "install") install(argv[2], argv[3]); string option; if (listfind(g_buildprog, g_command) != -1) { clearScreen(cls); if (g_command == "strip") { g_command = "program"; option = "-s"; } program(option); // exits } if (g_command == "library") { clearScreen(cls); build_libraries(); #ifdef USE_ALL rmUSE_ALLfiles(); #endif return; } if (g_command == "strip-shared") { strip_shared(); return; } exec("icmbuild -h"); } icmake-9.02.06/scripts/conversions0000644000175000017500000000241713176557635016115 0ustar frankfrankCONFIG=INSTALL.im . VERSION . tmp/ROOT ROOT=`echo ${ROOT}/ | sed 's,//,/,g' | sed 's,//,/,g'` EXTENSION=`grep '^#' $CONFIG | grep "#define[[:space:]]\+EXTENSION" | \ sed 's,.*EXTENSION[[:space:]]\+\"\([^"]*\)".*,'${ROOT}'\1,'` BINDIR=`grep "#define[[:space:]]\+BINDIR" $CONFIG | \ sed 's,.*BINDIR[[:space:]]\+\"\([^"]\+\)".*,'${ROOT}'\1,'` SKELDIR=`grep "#define[[:space:]]\+SKELDIR" $CONFIG | \ sed 's,.*SKELDIR[[:space:]]\+\"\([^"]\+\)".*,'${ROOT}'\1,'` MANDIR=`grep "#define[[:space:]]\+MANDIR" $CONFIG | \ sed 's,.*MANDIR[[:space:]]\+\"\([^"]\+\)".*,'${ROOT}'\1,'` LIBDIR=`grep "#define[[:space:]]\+LIBDIR" $CONFIG | \ sed 's,.*LIBDIR[[:space:]]\+\"\([^"]\+\)".*,'${ROOT}'\1,'` CONFDIR=`grep "#define[[:space:]]\+CONFDIR" $CONFIG | \ sed 's,.*CONFDIR[[:space:]]\+\"\([^"]\+\)".*,'${ROOT}'\1,'` DOCDIR=`grep "#define[[:space:]]\+DOCDIR" $CONFIG | \ sed 's,.*DOCDIR[[:space:]]\+\"\([^"]\+\)".*,'${ROOT}'\1,'` DOCDOCDIR=`grep "#define[[:space:]]\+DOCDOCDIR" $CONFIG | \ sed 's,.*DOCDOCDIR[[:space:]]\+\"\([^"]\+\)".*,'${ROOT}'\1,'` # CPPFLAGS=`grep "#define[[:space:]]\+CPPFLAGS" $CONFIG | sed 's,^.[^"]*,,'` # LDFLAGS=`grep "#define[[:space:]]\+LDFLAGS" $CONFIG | sed 's,^.[^"]*,,'` icmake-9.02.06/scripts/convert0000755000175000017500000000051013176557635015220 0ustar frankfrank#!/bin/bash SCRIPTNAME=$1 DESTDIR=$2 . scripts/conversions mkdir -p tmp/${DESTDIR} sed ' s,@BINDIR@,'${BINDIR}',g s,@SKELDIR@,'${SKELDIR}',g s,@MANDIR@,'${MANDIR}',g s,@LIBDIR@,'${LIBDIR}',g s,@CONFDIR@,'${CONFDIR}',g s,@DOCDIR@,'${DOCDIR}',g s,@DOCDOCDIR@,'${DOCDOCDIR}',g ' tmp/${SCRIPTNAME}.in > ${DESTDIR}/${SCRIPTNAME} icmake-9.02.06/scripts/icmstart.in0000755000175000017500000003370113232306464015764 0ustar frankfrank#!@BINDIR@/icmake -t. string g_confPath; string g_home = getenv("HOME")[1] + "/.icmake"; string g_skelPath = "@SKELDIR@"; string g_program = "icmstart"; string g_defaultCommand; string g_defaultCommandArg; list g_defaultCommands = strtok("program library", " "); string g_destPath; string g_destSpec; string g_cwd = chdir(""); string g_icmconf; list g_mkdir; list g_installed; list g_actions = strtok("b P L D PD Pb bP DP pL Lp LD DL", " "); // possible initial // actions on rc-file // lines int g_confirmInstall = 0; int g_skeletons = 1; int g_replace = 0; int g_debug = 0; int g_askReplace = 1; int g_version = 1; int g_basic = 0; int g_modIcmconf = 1; void usage() { printf("Usage: ", g_program, " [Options] dir [program|library]\n" "Where:\n" " Options:\n" " -b: basic: the files usage.cc and version.cc are not " "installed\n" " -c confpath: Use the configuration files (icmstart.rc, " "AUTHOR,\n" " VERSION, YEARS found in `confpath' rather than\n" " if found in $HOME/.icmake or @CONFDIR@\n" " -d: debug: do not execute any commands, but show commands\n" " that would have been executed\n" " -I: do NOT install any files.\n" " -r: replace existing files/directories\n" " -s skelPath: Read the skeleton information from the directory\n" " `skelPath' rather than @SKELDIR@\n" " dir: the directory to install the files into\n" " program, library: command passed by default to the icmbuild " "script\n" "\n"); exit(0); } void die(string s) { printf(g_program, ": ", s, "\n"); exit(1); } int isFileOrDir(string s) { return (int)stat(P_NOCHECK, s)[0] & (S_IFREG | S_IFDIR); } int isFile(string s) { return (int)stat(P_NOCHECK, s)[0] & S_IFREG; } void ignore(string dest) { g_installed += (list)(g_destPath + dest); } void syscall(string command) { if (g_debug) printf(command, "\n"); else system(command); } void md(string dir) { // skip dir if it has already been handled for (int idx = 0; idx < listlen(g_mkdir); ++idx) { if (g_mkdir[idx] == dir) return; } syscall("mkdir -p " + dir); g_mkdir += (list)dir; } string readlink(string name) { name = eval("readlink -f " + name)[0]; return resize(name, strlen(name) - 1); } string absPath(string arg) { if (arg[0] != "/") arg = g_cwd + arg; return readlink(arg) + "/"; } string absSource(string source) { int abs = strchr(source, "~/") == 0; if (abs == 0) source = g_skelPath + source; source = readlink(source); if (abs == 0 && strfind(source, g_skelPath) != 0) die("source: `" + source + "' not in `" + g_skelPath + "'"); if (!isFileOrDir(source)) die("Can't find file or dir. `" + source + "'"); return source; } string absDest(string dest) { if (strchr(dest, "~/") == 0) // absolute path name die("absolute destination specifications (`" + dest + "') not supported"); dest = readlink(g_destPath + dest); if (strfind(dest, g_destPath) != 0) die("dest: `" + dest + "' not in `" + g_destPath + "'"); return dest; } void arguments(int argc, list argv) { list icm = getenv("ICM"); // ICM environment var defined? if ((int)icm[0] == 1) g_skelPath = icm[1]; // then re-assign skelPath int cmdidx = 1; while (cmdidx < argc) { string arg = argv[cmdidx]; if (arg[0] != "-") // no (more) options break; if (arg[1] == "b") // -b: basic installation { g_basic = 1; g_version = 0; } else if (arg[1] == "c") // -c: re-assign g_confPath { arg = substr(arg, 2, 999); // get all beyond -c if (arg == "") // or get then next argument { if (cmdidx == argc) die("-c lacks configuration file specification"); arg = argv[++cmdidx]; } g_confPath = absPath(arg); // reassign confpath } else if (arg[1] == "d") // -d: debug g_debug = 1; else if (arg[1] == "I") // -I: no skeletons g_skeletons = 0; else if (arg[1] == "r") // -r: replace existing file(s) { g_askReplace = 0; g_replace = 1; } else if (arg[1] == "s") // -s: re-assign g_skelPath { arg = substr(arg, 2, 999); // get all beyond -s if (arg == "") // or get then next argument { if (cmdidx == argc) die("-s lacks skeleton dir specification"); arg = argv[++cmdidx]; } g_skelPath = arg; // reassign skelPath } else die("Option `" + arg + "' not supported\n"); ++cmdidx; } g_skelPath = absPath(g_skelPath); g_destSpec = argv[cmdidx]; g_destPath = absPath(g_destSpec); g_icmconf = g_destPath + "icmconf"; if (++cmdidx < argc) { g_defaultCommandArg = argv[cmdidx]; if (listfind(g_defaultCommands, g_defaultCommandArg) == -1) { printf("Initial command `", g_defaultCommandArg, "' not supported\n"); exit(1); } if (g_defaultCommandArg == "library") g_version = 0; g_defaultCommand = "\n" "#define DEFCOM \"" + g_defaultCommandArg + "\"\n"; } md(g_destPath); // install the target dir } int replace(string target) { while (g_askReplace) { printf("`", target, "' exists.\n" "Replace [?akNqy] ? "); string answer = getch(); if (answer == "a") { g_replace = 1; g_askReplace = 0; break; } if (answer == "k") { g_askReplace = 0; g_modIcmconf = 0; break; } if (answer == "y") return 1; if (answer == "q") exit(0); if (answer == "n" || answer == "\n") { if (target == "icmconf") g_modIcmconf = 0; return 0; } // ? or something else requested printf("Press `a' : replace ", target, " and ALL remaining files,\n" " `k' : KEEP ", target, " and all remaining files\n" " `n' : (or press Enter) do NOT replace ", target, " (default)\n" " `q' : QUIT (do NOT replace ", target, ", and END icmstart NOW)\n" " 'y' : REPLACE ", target, "\n" " `?' : show this help\n"); } return g_replace; } int install(string dest, string target) { return (int)(!exists(target) || replace(dest)); } int install_file(string realSource, string dest, string realDest) { if (!install(dest, realDest)) return 0; md(get_path(realDest)); syscall("cp -rd " + realSource + " " + realDest); g_installed += (list)realDest; return 1; } string find(string path, string file) { string ret = path + "/" + file; return exists(ret) ? ret : ""; } string findFile(string file) { string ret; if (g_confPath != "") // locate file in -c path ret = find(g_confPath, file); if (ret == "") // not found, locate in $HOME ret = find(g_home, file); if (ret == "") // not found, locate in CONFDIR ret = find("/etc/icmake", file); return ret; } void install_conf(string file, string default) { if (g_skeletons) { string ret = findFile(file); if (ret != "") system("cat " + ret + " >> " + g_destPath + "VERSION"); else fprintf(g_destPath + "VERSION", "#define ", file, " \"", default, "\"\n"); } } void install_version() { if (!g_version) return; string str = g_destPath + "VERSION"; if (install("VERSION", str)) { system(P_NOCHECK, "rm -f " + str); install_conf("AUTHOR", ""); install_conf("VERSION", "0.00.00"); str = "date '+%Y'"; str = `str`[0]; install_conf("YEARS", resize(str, strlen(str) - 1)); } } void defaultCommand() { if (g_modIcmconf == 0) // no icmconf modification requested return; // write a default command if if (g_defaultCommand != "") // if provided as last arg. fprintf(g_icmconf, g_defaultCommand); // for libraries: uncomment the // #define LIBRARY spec, and // comment out #define MAIN if (strfind(g_defaultCommand, "library") != -1) syscall("sed -i '\n" "s?^//\\(#define LIBRARY\\)?\\1?\n" "s?^\\(#define MAIN\\)?//\\1?\n" "' " + g_icmconf); if (!g_version) // uncomment syscall("sed -i '\n" // #define USE_VERSION "s?^\\(#define USE_VERSION\\)?//\\1?\n" "' " + g_icmconf); } int confirmInstall(string source, string dest) { if (!g_confirmInstall) return 1; if (source == dest) printf("Install `", dest, "' [yN] ? "); else printf("Install `", source, "' as `", dest, "' [yN] ? "); return getch() == "y"; } list shift(list source) // shift away the first element { list ret; for (int idx = 1; idx != listlen(source); ++idx) ret += (list)source[idx]; return ret; } // ignore 'P' for library construction, // ignore 'L' for program construction // do not ignore the 'D' specificied entries int ignoreEntry(string install) { return (int) ( g_basic && strchr(install, "b") != -1 || strchr(install, "D") == -1 // not by default && ( g_defaultCommandArg == "library" && strchr(install, "P") != -1 || g_defaultCommandArg == "program" && strchr(install, "L") != -1 ) ); } // a line in the conffile may be organized as follows (name is either // a file or a directory; directories are copied completely): // name - name is located in skelPath and installed at destPath // name dest - name is located in skelPath and installed at destPath/name // if name is a directory then the destination will be // destPath/dest/name. dest may also be /dest // path/name - relative or absolute path's name will be installed at // destPath. Relative is relative to the startup directory // path/name dest - relative or absolute path's name will be installed // at destPath/dest. dest may also be /dest // All lines may start with a P, L, D, or b. // b and D may also be added to P or L // A source at a P-line is installed when using 'icmstart xxx program' // A source at an L-line is installed when using 'icmstart xxx library' // A source at a D line, or a source withoug P,L,D prefixes is // unconditionally installed. // A source at a b-line is ignored with the -b (basic) flag // Following a P,L,D,b combination (+space) an optional ? (+ space) may be // specificed in which case installation of the source must be confirmed // by the user void install_line(string confline) { list fields = strtok(confline, " \t\n"); string source = fields[0]; // ignore empty line or comment if (listlen(fields) == 0 || source[0] == "#") return; // remove any P/L/D flags string install = source; if (listfind(g_actions, install) == -1) install = ""; else { fields = shift(fields); source = fields[0]; } g_confirmInstall = source == "?"; // need confirmation ? if (g_confirmInstall) { fields = shift(fields); // rm the ?-mark source = fields[0]; } if (ignoreEntry(install)) return; string realSource = absSource(source); string dest = listlen(fields) > 1 ? fields[1] : source; string realDest = absDest(dest); if (listfind(g_installed, realDest) != -1) // already processed 'dest' return; if (!g_replace && !g_askReplace && exists(realDest)) return; if (!confirmInstall(source, dest)) return; install_file(realSource, dest, realDest); } void install_rc() { string conffile = findFile("icmstart.rc"); if (!isFile(conffile)) die("Can't find configuration file `icmstart.rc'"); while (list line = fgets(conffile, line)) install_line(line[0]); install_version(); defaultCommand(); } void main(int argc, list argv) { echo(OFF); if (argc == 1) usage(); arguments(argc, argv); install_rc(); // install .rc file elements printf("Done. "); if (g_modIcmconf) printf("Don't forget to inspect the #defines in " "'", g_destSpec, "/icmconf'\n\n"); else printf("'", g_destSpec, "/icmconf' not modified\n\n"); } icmake-9.02.06/un/0000755000175000017500000000000013232311417012524 5ustar frankfrankicmake-9.02.06/un/funadd.c0000644000175000017500000000010313176557635014150 0ustar frankfrank#include "icmun.ih" void fun_add () { puts (" add"); } icmake-9.02.06/un/icmun.ih0000644000175000017500000000302013176557635014201 0ustar frankfrank#include #include #include //#include "../rss/icrssdef.h" #include "../rss/rss.h" extern BinHeader *headerp; extern char invalid_macro_file []; extern char *funname []; extern char release[]; extern char version []; extern void (*p_procfun []) (void); extern FILE *infile; extern int8_t *local_types; extern unsigned curoffs; extern unsigned nvar; extern Variable *var; extern char *varname (ExprType); extern char *printvar (int); void dumpchar(int); void dumpint(int); void dumpstring(char *); void fun_jmp(void); void fun_jmp_false(void); void fun_jmp_true(void); void fun_push_1_jmp_end(void); void fun_push_0(void); void fun_push_imm(void); void fun_push_strconst(void); void fun_push_var(void); void fun_push_reg(void); void fun_pop_var(void); void fun_umin(void); void fun_atoi(void); void fun_itoa(void); void fun_atol(void); void fun_mul(void); void fun_div(void); void fun_mod(void); void fun_add(void); void fun_sub(void); void fun_eq(void); void fun_neq(void); void fun_sm(void); void fun_gr(void); void fun_younger(void); void fun_older(void); void fun_smeq(void); void fun_greq(void); void fun_exit(void); void fun_asp(void); void fun_ret(void); void fun_copy_var(void); void fun_inc(void); void fun_dec(void); void fun_call(void); void fun_call_rss(void); void fun_frame(void); void fun_ret(void); void fun_pop_reg(void); void fun_ascii(void); void process(void); void fun_band(void); void fun_bor(void); void fun_bnot(void); void fun_xor(void); void fun_shl(void); void fun_shr(void); icmake-9.02.06/un/funshr.c0000644000175000017500000000011113176557635014213 0ustar frankfrank#include "icmun.ih" void fun_shr () { puts (" shr"); } icmake-9.02.06/un/fundiv.c0000644000175000017500000000010313176557635014202 0ustar frankfrank#include "icmun.ih" void fun_div () { puts (" div"); } icmake-9.02.06/un/funbor.c0000644000175000017500000000011013176557635014200 0ustar frankfrank#include "icmun.ih" void fun_bor () { puts (" or"); } icmake-9.02.06/un/fungreq.c0000644000175000017500000000010513176557635014360 0ustar frankfrank#include "icmun.ih" void fun_greq () { puts (" greq"); } icmake-9.02.06/un/fundec.c0000644000175000017500000000076413176557635014170 0ustar frankfrank#include "icmun.ih" void fun_dec () { int16_t idx = rss_getInt16 (infile); dumpint (idx); if ((uint16_t)idx < 0x8000) printf ("dec global %s %s\n", varname (var [idx].type), printvar (idx)); else if (idx < (int16_t) 0xc000) printf ("dec local %s %s\n", varname (local_types[ (int16_t) 0xc000 - (int16_t) 1 - idx]), printvar (idx)); else printf ("dec arg %s\n", printvar (idx)); } icmake-9.02.06/un/funpopre.c0000644000175000017500000000011313176557635014546 0ustar frankfrank#include "icmun.ih" void fun_pop_reg () { puts (" pop reg"); } icmake-9.02.06/un/dumpstri.c0000644000175000017500000000020713176557635014563 0ustar frankfrank#include "icmun.ih" void dumpstring (s) char *s; { while (*s) { putchar(iscntrl(*s) ? '.' : *s); s++; } } icmake-9.02.06/un/dumpchar.c0000644000175000017500000000016413176557635014521 0ustar frankfrank#include "icmun.ih" void dumpchar(int val) { printf ("%s ", rss_hexString ((unsigned)(val & 0xff), 2)); } icmake-9.02.06/un/varname.c0000644000175000017500000000026113176557635014345 0ustar frankfrank#include "icmun.ih" char *varname (type) ExprType type; { if (type & e_str) return ("string"); if (type & e_int) return ("int"); return ("list"); } icmake-9.02.06/un/funjmpf.c0000644000175000017500000000036013176557635014361 0ustar frankfrank#include "icmun.ih" void fun_jmp_false () { int16_t offs; offs = rss_getInt16 (infile); dumpint ( (uint16_t) offs); printf ("jmp false [%s]\n", rss_hexString ((unsigned) (ftell (infile) + offs), 4)); } icmake-9.02.06/un/fungr.c0000644000175000017500000000010113176557635014026 0ustar frankfrank#include "icmun.ih" void fun_gr () { puts (" gr"); } icmake-9.02.06/un/funpushi.c0000644000175000017500000000026713176557635014563 0ustar frankfrank#include "icmun.ih" void fun_push_imm () { int16_t val = rss_getInt16 (infile); dumpint ( (uint16_t) val); printf ("push int %s\n", rss_hexString ((unsigned)val, 4)); } icmake-9.02.06/un/funitoa.c0000644000175000017500000000010513176557635014356 0ustar frankfrank#include "icmun.ih" void fun_itoa () { puts (" itoa"); } icmake-9.02.06/un/funatoi.c0000644000175000017500000000010513176557635014356 0ustar frankfrank#include "icmun.ih" void fun_atoi () { puts (" atoi"); } icmake-9.02.06/un/funsmeq.c0000644000175000017500000000010513176557635014367 0ustar frankfrank#include "icmun.ih" void fun_smeq () { puts (" smeq"); } icmake-9.02.06/un/funret.c0000644000175000017500000000010313176557635014212 0ustar frankfrank#include "icmun.ih" void fun_ret () { puts (" ret"); } icmake-9.02.06/un/funpushs.c0000644000175000017500000000074713176557635014600 0ustar frankfrank#include "icmun.ih" void fun_push_strconst () { uint16_t offs; register char *str; offs = (uint16_t) rss_getInt16 (infile); if ( (str = rss_getString (infile, headerp->offset[0], offs)) == (char *) -1 ) rss_fatal(0, 0, "cannot get string, opcode at %s", rss_hexString (curoffs, 4)); dumpint (offs); printf ("push string \""); dumpstring (str); puts ("\""); free (str); } icmake-9.02.06/un/funsm.c0000644000175000017500000000010113176557635014035 0ustar frankfrank#include "icmun.ih" void fun_sm () { puts (" sm"); } icmake-9.02.06/un/icm_bootstrap0000755000175000017500000000041513176557635015344 0ustar frankfrank#!/bin/bash . ../bootstrap/functions . ../bootstrap/flags echo Creating tmp/${BINDIR}/icmun echo -n . try ${CC} ${CFLAGS} -o ../tmp/${LIBDIR}/icmun *.c ../tmp/libicrss.a \ ${LDFLAGS} echo . icmake-9.02.06/un/funmul.c0000644000175000017500000000010313176557635014215 0ustar frankfrank#include "icmun.ih" void fun_mul () { puts (" mul"); } icmake-9.02.06/un/funbnot.c0000644000175000017500000000011213176557635014362 0ustar frankfrank#include "icmun.ih" void fun_bnot () { puts (" not"); } icmake-9.02.06/un/funpopva.c0000644000175000017500000000102413176557635014550 0ustar frankfrank#include "icmun.ih" void fun_pop_var () { int16_t idx; idx = (int16_t) rss_getInt16 (infile); dumpint (idx); if ((uint16_t)idx < 0x8000) printf ("pop global %s %s\n", varname (var [idx].type), printvar (idx)); else if (idx < (int16_t) 0xc000) printf ("pop local %s %s\n", varname (local_types[ (int16_t) 0xc000 - (int16_t) 1 - idx]), printvar (idx)); else printf ("pop arg %s\n", printvar (idx)); } icmake-9.02.06/un/funolder.c0000644000175000017500000000010713176557635014531 0ustar frankfrank#include "icmun.ih" void fun_older () { puts (" older"); } icmake-9.02.06/un/funinc.c0000644000175000017500000000102513176557635014175 0ustar frankfrank/* #define msg */ #include "icmun.ih" void fun_inc() { int16_t idx; idx = rss_getInt16(infile); msg("op_inc argument = %x", idx); dumpint(idx); if ((uint16_t)idx < 0x8000) printf ("inc global %s %s\n", varname(var[idx].type), printvar(idx)); else if (idx < (int16_t)0xc000) { printf ("inc local %s %s\n", varname(local_types[(int16_t)0xc000 - (int16_t)1 - idx]), printvar(idx)); } else printf ("inc arg %s\n", printvar (idx)); } icmake-9.02.06/un/funexit.c0000644000175000017500000000010513176557635014373 0ustar frankfrank#include "icmun.ih" void fun_exit () { puts (" exit"); } icmake-9.02.06/un/funasp.c0000644000175000017500000000023013176557635014204 0ustar frankfrank#include "icmun.ih" void fun_asp () { char val; val = rss_getOpcode (infile); dumpchar (val); printf ("add sp, %u\n", val); } icmake-9.02.06/un/funframe.c0000644000175000017500000000113313176557635014516 0ustar frankfrank#include "icmun.ih" void fun_frame () { unsigned i; unsigned nlocals; nlocals = rss_getOpcode (infile); dumpchar ((int)nlocals); local_types = rss_realloc(local_types, nlocals * sizeof(int8_t)); printf ("frame %s\n", rss_hexString (nlocals, 2)); if (nlocals) { printf (" "); for (i = 0; i < nlocals; i++) { local_types[i] = rss_getOpcode (infile); printf ("%s ", rss_hexString ((unsigned)local_types[i], 2)); local_types[i] &= e_int | e_str | e_list; } putchar ('\n'); } } icmake-9.02.06/un/funjmp.c0000644000175000017500000000034213176557635014213 0ustar frankfrank#include "icmun.ih" void fun_jmp () { int16_t offs; offs = rss_getInt16 (infile); dumpint ( (uint16_t) offs); printf ("jmp [%s]\n", rss_hexString ((unsigned)(ftell(infile) + offs), 4)); } icmake-9.02.06/un/funjmpt.c0000644000175000017500000000033413176557635014400 0ustar frankfrank#include "icmun.ih" void fun_jmp_true () { int16_t offs = rss_getInt16 (infile); dumpint ( (uint16_t) offs); printf ("jmp true [%s]\n", rss_hexString ((unsigned) (ftell (infile) + offs), 4)); } icmake-9.02.06/un/funcallr.c0000644000175000017500000000061513176557635014525 0ustar frankfrank #include "icmun.ih" void fun_call_rss () { unsigned char funnr; funnr = (unsigned char)rss_getOpcode(infile); dumpchar(funnr); if (funnr >= f_hlt) rss_fatal(0, 0, "non-existing function call\n" "attempt to call function %x, %x are defined", funnr, f_hlt); printf ("callrss %u (%s)\n", (unsigned int)funnr, funname [ (int) funnr]); } icmake-9.02.06/un/data.c0000644000175000017500000000426113176557635013631 0ustar frankfrank#include "icmun.ih" BinHeader *headerp; char *funname [] = { /* 0 */ "arghead", "argtail", "ascii_int2str", "ascii_str2int", /* 4 */ "backtick", "change_base", "change_ext", "change_path", /* 8 */ "chdir", "cmdhead", "cmdtail", "echo", /* c */ "list_element", "eval", "exec", "execute", /* 10 */ "exists", "fgets", "fprintf", "get_base", /* 14 */ "get_dext", "get_ext", "get_path", "getch", /* 18 */ "getenv", "getpid", "gets", "listlen", /* 1c */ "makelist", "printf", "putenv", "stat", /* 20 */ "string_element", "strfind", "strformat", "strlen", /* 24 */ "strlwr", "resize", "strtok", "strupr", /* 28 */ "substr", "system", "trim", "trimleft", /* 2c */ "trimright", "strchr", "listfind", "listunion" }; FILE *infile; int8_t *local_types; unsigned curoffs, nvar; Variable *var; void (*p_procfun[])(void) = { fun_jmp, fun_jmp_false, fun_jmp_true, fun_push_1_jmp_end, fun_push_0, fun_push_imm, fun_push_strconst, fun_push_var, fun_push_reg, fun_pop_var, fun_umin, fun_atoi, fun_itoa, fun_atol, fun_mul, fun_div, fun_mod, fun_add, fun_sub, fun_eq, fun_neq, fun_sm, fun_gr, fun_younger, fun_older, fun_smeq, fun_greq, fun_call_rss, fun_asp, fun_exit, fun_copy_var, fun_inc, fun_dec, fun_call, fun_frame, fun_ret, fun_pop_reg, fun_band, fun_bor, fun_bnot, fun_xor, fun_shl, fun_shr, /* fun_hlt : bogus value... op_hlt does not really exist */ }; icmake-9.02.06/un/funsub.c0000644000175000017500000000010313176557635014211 0ustar frankfrank#include "icmun.ih" void fun_sub () { puts (" sub"); } icmake-9.02.06/un/funpushv.c0000644000175000017500000000101613176557635014571 0ustar frankfrank#include "icmun.ih" void fun_push_var () { int16_t idx; idx = rss_getInt16 (infile); dumpint (idx); if ((uint16_t)idx < 0x8000) printf ("push global %s %s\n", varname (var [idx].type), printvar (idx)); else if (idx < (int16_t) 0xc000) printf ("push local %s %s\n", varname (local_types[ (int16_t) 0xc000 - (int16_t) 1 - idx]), printvar (idx)); else printf ("push arg %s\n", printvar (idx)); } icmake-9.02.06/un/funpush1.c0000644000175000017500000000024313176557635014465 0ustar frankfrank#include "icmun.ih" void fun_push_1_jmp_end () { printf (" push int 1, jmp [%s]\n", rss_hexString((unsigned)(curoffs + 2), 4)); } icmake-9.02.06/un/funband.c0000644000175000017500000000011213176557635014324 0ustar frankfrank#include "icmun.ih" void fun_band () { puts (" and"); } icmake-9.02.06/un/funyoung.c0000644000175000017500000000011313176557635014562 0ustar frankfrank#include "icmun.ih" void fun_younger () { puts (" younger"); } icmake-9.02.06/un/funcopyv.c0000644000175000017500000000100613176557635014563 0ustar frankfrank#include "icmun.ih" void fun_copy_var () { int16_t idx; idx = rss_getInt16 (infile); dumpint (idx); if ((uint16_t)idx < 0x8000) printf ("copy global %s %s\n", varname (var [idx].type), printvar (idx)); else if (idx < (int16_t) 0xc000) printf ("copy local %s %s\n", varname (local_types[ (int16_t) 0xc000 - (int16_t) 1 - idx]), printvar (idx)); else printf ("copy arg %s\n", printvar (idx)); } icmake-9.02.06/un/icmconf0000644000175000017500000000075313176557635014117 0ustar frankfrank#define USE_ECHO ON #define MAIN "main.c" #define REFRESH #define COMPILER "gcc" #define COMPILER_OPTIONS "-Wall -O2 -Werror -fdiagnostics-color=never" #define SOURCES "*.c" #define LINKER_OPTIONS "-s" #define ADD_LIBRARIES "icrss" #define ADD_LIBRARY_PATHS "../../tmp" #define CLS #define TMP_DIR "tmp" #define LIBRARY "modules" #define OBJ_EXT ".o" #define DEFCOM "program" icmake-9.02.06/un/build0000755000175000017500000000003113176557635013570 0ustar frankfrank#!/bin/bash icmbuild $1 icmake-9.02.06/un/funshl.c0000644000175000017500000000011113176557635014205 0ustar frankfrank#include "icmun.ih" void fun_shl () { puts (" shl"); } icmake-9.02.06/un/funeq.c0000644000175000017500000000010113176557635014023 0ustar frankfrank#include "icmun.ih" void fun_eq () { puts (" eq"); } icmake-9.02.06/un/funxor.c0000644000175000017500000000011113176557635014227 0ustar frankfrank#include "icmun.ih" void fun_xor () { puts (" xor"); } icmake-9.02.06/un/process.c0000644000175000017500000000365313176557635014402 0ustar frankfrank#include "icmun.ih" void process() { register Opcode op; register unsigned i; int32_t oldoffs; static char buf[200]; printf("Binary file statistics:\n" "\tstrings at offset\t0x%s\n" , rss_hexString((unsigned)headerp->offset[0], 4 )); printf("\tvariables at offset\t0x%s\n", rss_hexString((unsigned)headerp->offset[1], 4 )); printf("\tfilenames at offset\t0x%s\n", rss_hexString((unsigned)headerp->offset[2], 4 )); printf("\tfirst instruction at offset\t0x%s\n\n", rss_hexString((unsigned)headerp->offset[3], 4 )); if (nvar) { puts("Variable section dump:"); for (i = 0; i < nvar; i++) printf("\tvariable %s: %s\n", rss_hexString(i, 4), varname(var [i].type)); putchar('\n'); } if (headerp->offset[0] < headerp->offset[1]) { oldoffs = ftell(infile); puts("String constants dump:"); fseek(infile, headerp->offset[0], SEEK_SET); while (ftell(infile) < headerp->offset[1]) { rss_fgetz(buf, 199, infile); printf("\t\""); dumpstring(buf); printf("\"\n"); } putchar('\n'); fseek(infile, oldoffs, SEEK_SET); } puts("Disassembled code:"); while ((curoffs =(unsigned)ftell(infile)) <(unsigned)headerp->offset[0] ) { if ((op = rss_getOpcode(infile)) < op_hlt && op != (Opcode)-1 ) { printf("\t[%s] ", rss_hexString(curoffs, 4)); printf("%s ", rss_hexString((unsigned)op, 2)); p_procfun[op](); } else rss_fatal(0, 0, "At offset %s: opcode %s not defined", rss_hexString(curoffs, 4), rss_hexString((unsigned)op, 2)); } putchar('\n'); } icmake-9.02.06/un/funneq.c0000644000175000017500000000010313176557635014203 0ustar frankfrank#include "icmun.ih" void fun_neq () { puts (" neq"); } icmake-9.02.06/un/funatol.c0000644000175000017500000000010513176557635014361 0ustar frankfrank#include "icmun.ih" void fun_atol () { puts (" atol"); } icmake-9.02.06/un/funcall.c0000644000175000017500000000024113176557635014336 0ustar frankfrank#include "icmun.ih" void fun_call() { int offs = rss_getInt16 (infile); dumpint(offs); printf ("call [%s]\n", rss_hexString((unsigned)offs, 4)); } icmake-9.02.06/un/funumin.c0000644000175000017500000000010513176557635014372 0ustar frankfrank#include "icmun.ih" void fun_umin () { puts (" umin"); } icmake-9.02.06/un/funpush0.c0000644000175000017500000000011513176557635014462 0ustar frankfrank#include "icmun.ih" void fun_push_0 () { puts (" push int 0"); } icmake-9.02.06/un/dumpint.c0000644000175000017500000000033113176557635014372 0ustar frankfrank#include "icmun.ih" void dumpint (int val) { printf ("%s ", rss_hexString((unsigned)(val & 0xff), 2)); unsigned len = printf ("%s", rss_hexString((unsigned)(val >> 8), 2)); printf("%*c", 5 - len, ' '); } icmake-9.02.06/un/funpushr.c0000644000175000017500000000011513176557635014564 0ustar frankfrank#include "icmun.ih" void fun_push_reg () { puts (" push reg"); } icmake-9.02.06/un/funmod.c0000644000175000017500000000010313176557635014177 0ustar frankfrank#include "icmun.ih" void fun_mod () { puts (" mod"); } icmake-9.02.06/un/main.c0000644000175000017500000000163713176557635013650 0ustar frankfrank#include "icmun.ih" int main (int argc, char **argv) { register char const *progname = rss_programName(argv[0]); static char bimext [] = ".bim"; rss_copyright (progname); if (argc != 2) { printf ("Usage: %s bimfile\n" "where: bimfile - binary makefile (default extension: %s)\n\n" , progname, bimext); return 2; } register char *infname = rss_exists(argv[1]) ? argv[1] : rss_changeExt(argv[1], bimext); if (! (infile = fopen(infname, "r")) ) rss_fatal(0, 0, "cannot open %s for reading", infname); headerp = rss_readHeader(infile, (unsigned)version [0]); if ((int16_t)(nvar = rss_getVar(&var, infile, headerp)) == -1 ) rss_fatal(0, 0, "invalid macro file, cannot read variable section"); process(); return 0; } icmake-9.02.06/un/printvar.c0000644000175000017500000000113113176557635014556 0ustar frankfrank#include "icmun.ih" static char buffer [10] = "["; char *printvar(int idx) { register int16_t i; if ((uint16_t)idx < 0x8000 ) /* pure variable number */ strcpy(buffer + 1, rss_hexString ((unsigned)idx, 4)); else { i = idx - 0xc000; /* correct for BP pos */ strcpy (buffer + 1, "bp"); if (i < 0) { strcat (buffer, "-"); i = -i; } else strcat (buffer, "+"); strcat (buffer, rss_hexString ((unsigned)i, 4)); } strcat (buffer, "]"); return (buffer); } icmake-9.02.06/usr/0000755000175000017500000000000013176557635012740 5ustar frankfrankicmake-9.02.06/usr/share/0000755000175000017500000000000013176557635014042 5ustar frankfrankicmake-9.02.06/usr/share/icmake/0000755000175000017500000000000013232310166015246 5ustar frankfrankicmake-9.02.06/usr/share/icmake/scanner/0000755000175000017500000000000013176557635016724 5ustar frankfrankicmake-9.02.06/usr/share/icmake/scanner/lexer0000644000175000017500000000023113176557635017762 0ustar frankfrank%filenames scanner //%interactive //%debug %% [ \t]+ // Often used: skip white space \n // same icmake-9.02.06/usr/share/icmake/scanner/scanner.ih0000644000175000017500000000040113176557635020672 0ustar frankfrank// Declare here // what's only used in the Scanner class // and let Scanner's sources include "scanner.ih" #include "scanner.h" //#include "../parser/parserbase.h" // end of scanner.ih icmake-9.02.06/usr/share/icmake/parser/0000755000175000017500000000000013176557635016567 5ustar frankfrankicmake-9.02.06/usr/share/icmake/parser/grammar0000644000175000017500000000135713176557635020146 0ustar frankfrank//%default-actions quiet %filenames parser %scanner ../scanner/scanner.h //%baseclass-preinclude x.h or // Semantic values used by the parser. // Two often used types are predefined, extend or alter as seems fit. // When %union is not used, use: //%stype struct-name/class-name //%union //{ // // define union fields here. The fields shown are for demo-use only // int i; // unsigned u; // std::string *s; //}; // Typed nonterminals indicate the union-value that's returned: //%type // rule1 or TOKEN // rule2 // lowest precedence //%token //%nonassoc //%left //%right // highest precedence %% // Define the start-rule below (the name `startrule' may be altered) startrule: ; icmake-9.02.06/usr/share/icmake/main.ih0000644000175000017500000000031513176557635016540 0ustar frankfrank#include #include namespace Icmbuild { extern char version[]; extern char years[]; extern char author[]; }; void usage(std::string const &progname); using namespace std; icmake-9.02.06/usr/share/icmake/main.cc0000644000175000017500000000013213176557635016522 0ustar frankfrank#include "main.ih" int main(int argc, char **argv) try { } catch (...) { return 1; } icmake-9.02.06/usr/share/icmake/icmconf0000644000175000017500000001365613232310166016622 0ustar frankfrank // Inspect the following #defines. Change them to taste. If you don't // need a particular option, change its value into an empty string // For more information about this file: 'man 7 icmconf' // MAINTENANCE RELATED DEFINES THAT ARE OFTEN ADAPTED: // =================================================== // Uncomment to clear the screen starting the compilation //#define CLS // Uncomment to construct a library. Optionally use another name (don't // use lib or an extension like .a) //#define LIBRARY "modules" // The source containing main(): #define MAIN "main.cc" // The pattern locating sources in a directory: #define SOURCES "*.cc" // The extension of object modules: #define OBJ_EXT ".o" // Uncomment to construct a shared library //#define SHARED // If the constructed shared library requires additional libraries then // specify these here. E.g., if a library /usr/lib/special/libspecial.so // is required then specify "-L/usr/lib/special -lspecial" // Predefined paths (e.g., /lib, /usr/lib) do not have to be specified #define SHAREDREQ "" // Directory to contain temporary results #define TMP_DIR "tmp" // Uncomment to use the ALL facility and a class dependency setup in the // CLASSES file. When a directory contains a file ALL (optionally rename // this filename by providing an alternative name) then all its sources // and all sources of all classes depending on it are also compiled. // Class dependencies are indicated by the class name (as the first // word on a line) optionally followed by additional class names, which // are the classes directly depending on the line's first class name. //#define USE_ALL "a" // By default dependencies are determined by icm-dep (via icmake -d), // passing it the following options. If icm-dep should not be called, // activate ICM_DEP as an empty string. Alternatively specify your own // icm-dep options //#define ICM_DEP "-V go" // should commands be echoed (ON) or not (OFF) ? #define USE_ECHO ON // Use the VERSION file #define USE_VERSION // When DEFCOM "program" is specified './icmbuild' is shorthand for // './icmbuild program' // When DEFCOM "library" is specified './icmbuild' is shorthand for // './icmbuild library' // The icmstart script may add a DEFCOM specification to this file. //#define DEFCOM "program" //#define DEFCOM "library" // COMPILATION AND LINKING RELATED DEFINES // ======================================= // The compiler to use. Define CC if a C compiler is used. #define CXX "g++" //#define CC "gcc" // The compiler options to use. Define CFLAGS if a C compiler is used // To suppress colored error messages add option -fdiagnostics-color=never // To add debug-code to object files add option -g #define CXXFLAGS " --std=c++17 -Wall -O2" //#define CFLAGS " -Wall -O2" // The extension of internal header files. See PRECOMP below #define IH ".ih" // Uncomment to generate precompiled headers. When activated internal // header files are precompiled when they are more recent than their // precompiled versions. PRECOMP requires IH //#define PRECOMP "-x c++-header" // Uncomment to suppress warnings about non-existing IH files in // class-directories. This option is only interpreted when PRECOMP has // also been defined //#define NO_PRECOMP_WARNING // Uncomment to relink the binary, even when no sources were changed //#define REFRESH // Options passed to the linker: #define LDFLAGS "" // LIBRARIES REQUIRED BY THE CONSTRUCTED PROGRAM OR LIBRARY: // ========================================================= // any additional libraries the program may need: #define ADD_LIBRARIES "" // additional paths (other than the standard paths) to locate additional // libraries (specify absolute paths or relative to TMP_DIR): #define ADD_LIBRARY_PATHS "" // IF NO SCANNER AND NO PARSER ARE USED ALL OF THE FOLLOWING DEFINES // CAN BE REMOVED // DEFINES RELATED TO USING A PARSER GENERATOR // =========================================== // The subdirectory containing the parser's specification file // If this directive is REMOVED, then all parser-related #defines // can also be removed from icmconf. #define PARSER_DIR "" // What is the program generating a parser? #define PARSGEN "bisonc++" // Flags to pass to PARSGEN: #define PARSFLAGS "-V" // What is the top-level (or only) grammar specification file? #define PARSSPEC "grammar" // Optionally use patterns to specify additional grammar specification // files. These files are (in)directly included by PARSSPEC. Specify // patterns relative to PARSER_DIR //#define PARSFILES "" // The source file generated by the parser generator #define PARSOUT "parse.cc" // DEFINES RELATED TO USING A SCANNER GENERATOR // ============================================ // The subdirectory containing the scanner's specification file // If this directive is REMOVED, then all scanner-related #defines // can also be removed from icmconf. #define SCANNER_DIR "" // What is the program generating the lexical scanner? #define SCANGEN "flexc++" // Flags to provide SCANGEN with: #define SCANFLAGS "" // Name of the lexical scanner specification file #define SCANSPEC "lexer" // Optionally use patterns to specify additional scanner specification // files. These files are (in)directly included by SCANSPEC. Specify // patterns relative to SCANNER_DIR //#define SCANFILES "" // The source file generated by the lexical scanner #define SCANOUT "lex.cc" icmake-9.02.06/usr/share/icmake/CLASSES0000644000175000017500000000140713176557635016315 0ustar frankfrank# This file is used by icmbuild(1) and should contains the names of all # 1-level deep subdirectories containing sources to compile. Each directory # should be specified on a line of its own. Initial blanks are ok. # If a parser or scanner is used, (see icmconf's USE_PARSER and USE_SCANNER # defines) then those directories are automatically included (although they # could be included here as well) # Lines starting with # or with // are ignored, as are empty lines. # Sources in the current directory (i.e., the directory containing CLASSES) # are also compiled. # Class dependencies are handled by icm_dep, called from icmake using option # -d (enter icmake -d for short usage info, or see the section on icm_dep # in icmake(1) and icmbuild(1)'s man-pages icmake-9.02.06/usr/share/icmake/frame0000644000175000017500000000002313176557635016303 0ustar frankfrank#include "main.ih" icmake-9.02.06/usr/share/icmake/version.cc0000644000175000017500000000056313176557635017273 0ustar frankfrank// version.cc #include "main.ih" #include "icmconf" #ifdef USE_VERSION #include "VERSION" #endif #ifndef AUTHOR #define AUTHOR "" #endif #ifndef VERSION #define VERSION "0.00.00" #endif #ifndef YEARS #define YEARS "2012" #endif namespace Icmbuild { char version[] = VERSION; char years[] = YEARS; char author[] = AUTHOR; } icmake-9.02.06/usr/share/icmake/usage.cc0000644000175000017500000000110613176557635016704 0ustar frankfrank// usage.cc #include "main.ih" void usage(std::string const &progname) { cout << "\n" << progname << " by " << Icmbuild::author << "\n" << progname << " V" << Icmbuild::version << " " << Icmbuild::years << "\n" "\n" "Usage: " << progname << " [options] args\n" "Where:\n" " [options] - optional arguments (short options between parentheses):\n" " --help (-h) - provide this help\n" " --version (-v) - show version information and terminate\n" " args - explain additional arguments.\n" "\n"; } icmake-9.02.06/VERSION0000644000175000017500000000004013237047040013147 0ustar frankfrankVERSION=9.02.06 YEARS=1992-2018 icmake-9.02.06/where-is-what0000644000175000017500000000273613176557635014546 0ustar frankfrankchangelog overview of changes at new releases INSTALL description of the installation process INSTALL.im definitions of pathnames used by icmake QUICKINSTALL short description of required steps to install icmake VERSION latest icmake version and year build build-script that can be used once icmake has been installed icm_bootstrap bootstrap script to prepare icmake installation icm_github internal use only icm_install installation script icm_prepare script installing path-definitions: also called by icm_bootstrap doc/ documentation and man-pages (including Yodl manpage sources) comp/ sources of the icm-comp icmake compiler dep/ sources of the icm-dep dependency inspecting program exec/ sources of the icm-exec interpreter pp/ sources of the icm-pp preprocessor icmake/ sources of the icmake shell program un/ sources of the icmun unassembler rss/ sources of functions shared by the icmake programs scripts/ scripts used to build icmake, source texts of icm* scripts legacy/ legacy files examples/ various examples of icmake scripts usr/ default skeletons in share/icmake etc/ icmake/ contains default icmstart.rc, VERSION, AUTHOR, YEARS iuo/ internal use only: files used by my when working towards the next release where-is-what this file