Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
icmake(1)		 A program maintenance utility		     icmake(1)

       icmake -	A program maintenance (make) utility using a C-like grammar

       icmake [options]	source[.im] [dest[.bim]] [-- [args]]

       icmun bimfile

       Icmake(1)  is  a	 generic tool handling program maintenance that	can be
       used as an alternative for make(1). It's	a generic  tool	 in  that  ic-
       make-scripts,  written  in a language closely resembling	the C program-
       ming language, can perform tasks	that are traditionally the  domain  of
       scripting languages.

       Icmake allows programmers to use	a programming language (closely	resem-
       bling the well-known C-programming language) to define the actions that
       are required for	(complex) program maintenance. For this, icmake	offers
       various special operators as well as a set of  support  functions  that
       have shown their	usefulness in program maintenance.

       Although	icmake scripts can be written from scratch, often the required
       activities are highly comparable. This observation resulted in the con-
       struction of two	icmake scripts,	which are now part of the standard ic-
       make distribution: icmstart(1), initializing a  directory  for  program
       development  and	 icmbuild(1), handling the actual program maintenance.
       Both come predefined as scripts tailored	to initializing	and  maintain-
       ing  C++	 programs  (or,	after minimal adaptation, C programs), but can
       easily be adapted to other programming  languages.  Both	 icmstart  and
       icmbuild	can be run without explicitly calling icmake.

       This  man-page  covers  icmake (the program), its support programs, and
       the syntax and facilities offered by icmake's scripting language. Refer
       to  the icmstart(1)) man-page for information about how a directory can
       be initialized (created)	in which (by default) a	C++ or C  program  can
       be  developed  and  refer  to  the icmbuild(1) man-page for information
       about how icmbuild can be used to handle	program	maintenance.

       Icmake, its support programs, and scripts do not	 offer	an  Integrated
       Development  Environment	 (IDE).	Icmake merely performs tasks for which
       scripts can be written, and only	a minimal set of  pre-defined  scripts
       (icmstart   and	icmbuild)  that	 repeatedly have shown to be extremely
       useful when developing and maintaining programs are included in the ic-
       make distribution.

       In its standard operation mode, icmake calls the	following programs:

       o      icm-pp  to preprocess the	icmake file

       o      icm-comp	 to byte-code compile the icmake  s

       o      icm-dep  to  handle  class-dependencies (see sections ICM-DEP in
	      this and icmbuild(1)'s  man-pages	 for  more  information	 about

       o      icm-exec	 to execute the	byte-code file

       The  program icmun(1) disassembles compiled byte-code (.bim) files. Ic-
       mun is mainly used for illustration, education, and debugging. As it is
       not  required  for icmake's daily use it	is not installed in a standard
       PATH directory but (since icmake's version 9.02.00) in icmake's lib di-
       rectory,	which commonly is /usr/lib/icmake.

       Traditional make-utilities recompile sources once header	files are mod-
       ified. When developing 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  icmbuld(1)
       may  inspect  class  dependencies,  (re)compiling  sources of dependent
       classes whenever	necessary.  By default,	class-dependencies are not in-
       terpreted,  but	this  can  easily be changed by	activating the PRECOMP
       and/or USE_ALL defines which are	found in the file  icmconf.  Refer  to
       the icmconf(7) man-page for further details.

       Precompiled  header  files  can	also be	used. Precompiled header files
       dramatically reduce the time that is required for compiling the	source
       files  of  classes. Refer to the	icmconf(7) man-page (in	particular the
       description of the PRECOMP define) for further details.

       This manpage describes icmake's options in the next section.  Following
       that  section  icmake's	C-like scripting language and support programs
       are described in	the following separate sections:

	      -	supported preprocessor directives, like	#include and #define;

       o      DATA TYPES
	      -	int, list, string, and void (for functions);

	      -	like O_FILE, OFF, and S_IFREG;

       o      OPERATORS
	      -	like +,	younger, and casts

       o      FLOW CONTROL
	      -	if, for, while,	etc. (the switch is not	available);

	      -	executing programs, changing directories, operations on	string
	      and list type variables, etc.;

	      -	 at  least  main,  with	or without its common parameters argc,
	      argv, and	envp.

       o      ICM-DEP
	      -	the icm-dep dependency analyzer.

       o      ICMUN
	      -	a brief	section	about icmun.

       Where available,	single letter options are listed  between  parentheses
       beyond their associated long-option variants.

       o      --
	      This  option separates icmake arguments from arguments passed to
	      the .bim file.
	      Arguments	beyond -- are passed to	the .bim file as-is,  and  are
	      available	from the list argv parameter available from the	icmake
	      script's main function's second parameter	(see below at  section
	      USER  DEFINED  FUNCTIONS).  For  some options (see below)	the --
	      separator	is not required.

       o      --about (-a)
	      Show information about icmake and	terminate.

       o      --compile	(-c)
	      The icmake source	file is	compiled, generating a .bim file.

       o      --execute	(-e)
	      Execute the icmake .bim file, given as icmake's first file argu-
	      ment.  Any  additional  arguments	 are  passed  to the .bim file
	      as-is, and -- should not be specified.

       o      --force (-f)
	      The icmake source	file is	recompiled (even if the	.bim  file  is
	      up-to-date)  either when no other	options	are specified, or when
	      in combination with options --source and --tmpbin.

       o      --help (-h)
	      Provides usage info.

       o      --icm-dep	(-d)
	      Calls /usr/lib/icmake/icm-dep, passing it	 all  remaining	 argu-
	      ments.  If no additional arguments are specified icm-dep's short
	      usage information	is shown to the	std. output stream.  See  sec-
	      tions ICM-DEP in this and	icbuild(1)'s man-pages for more	infor-
	      mation  about  the  icm-dep  support  program.  An  overview  of
	      icm-dep's	options	follows	below, after this overview of icmake's

       o      --preprocess (-p)
	      The icmake source	file is	only  preprocessed,  and  the  prepro-
	      cessed  file is written to icmake's second file argument (by de-
	      fault `source'.pim).

       o      --source (-i)
	      The first	argument is the	icmake source file, the	default	binary
	      file  is	constructed if necessary. Any additional arguments are
	      passed to	the .bim file as-is, and -- should not be specified.

       o      --summary	(-F)
	      The filenames and	flags as well as an overview of	all actions to
	      be performed by icmake are shown on the standard output stream.

       o      -t tmpbim
	      The tmpbim argument following -t is the name of a	temporary .bim
	      file, which is removed after icmake's call. When . is  specified
	      for tmpbim then the default temporary directory, followed	by ic-
	      make's process-id, followed by .bim is used.

	      Following	the name of the	temporary .bim file the	 name  of  the
	      icmake source script must	be specified. Any additional arguments
	      are passed to the	.bim file as-is, and --	should not  be	speci-
	      fied;  After  setting  the  source script	file's executable flag
	      (chmod +x	script), and providing it with an  initial  line  like

		  #!/usr/bin/icmake -t.

	      the icmake script	can directly be	called:

		  script arg1 arg2

	      in  which	 case  the icmake script `script' is executed while it
	      receives the arguments script arg1 arg2.

       o      -T directory
	      The specified directory is used to store temporary files.	 E.g.,
	      when  compiling  an  icmake  script, the output of icmake's pre-
	      processor	is a temporary file which is removed on	exit.  By  de-
	      fault  /tmp is used, unless /tmp is not a	writable directory, in
	      which case the current user's $HOME directory is used.  Implicit
	      temporary	filenames always start with the	process	id of the cur-
	      rent icmake process.

       o      --version	(-v)
	      Displays icmake's	version	number.

       The following preprocessor directives are recognized:

       o      comment:
	      standard C comment (everything from /* through */)  as  well  as
	      comment-to-end-of-line (line content starting at //) is ignored.

       o      Shell  startup:  The  first  line	of the icmake-script may start
	      with #!path, where path defines the absolute location of the ic-
	      make  program. By	making the script executable, it can be	called
	      without explicitly calling icmake.

	      E.g., if the first line  of  an  (executable)  icmakefile	 'icm'
	      (without extension) contains

		  #!/usr/bin/icmake -i

	      then icm may be issued as	a command, thus	executing

		  /usr/bin/icmake -i icm ...


		  #!/usr/bin/icmake -t /tmp/icm

	      may be used, resulting in	the execution of

		  #!/usr/bin/icmake -t /tmp/icm	icm ...

	      In this case the binary file is removed on exit.

       o      #include "filename"
	      The file filename	is included at the location of the directive

       o      #include _filename_
	      The  file	 filename  is included at the location of the #include
	      directive; filename is searched in the colon-separated  directo-
	      ries  specified by the IM	environment variable. The first	occur-
	      rence of filename	in the directories specified by	the  IM	 envi-
	      ronment variable is used.

       o      #define identifier [definition]
	      The  text	 identifier  is	replaced by definition.	The definition
	      may contain references to	already	defined	identifiers, using the
	      ${identifier}  format.  If the ${identifier} hasn't been defined
	      (yet), the text ${identifier} is literally kept. To prevent  in-
	      finite  recursion	at most	100 ${identifier} replacements are al-

	      Definitions continue at the next line if the last	character on a
	      line  is a backslash (\).	 (which	is not included	in the defini-
	      tion). 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 #define's identifier is optional.
	      If omitted, the macro is defined,	so it can be used in #if(n)def
	      directives (see below), but they are not replaced	by any text in
	      icmake code statements.

       o      #ifdef identifier
	      If the identifier	macro was defined the next block of code  (un-
	      til  a matching #else or #endif directive	was read) is byte-com-
	      piled. Otherwise,	the block of code is ignored.

       o      #ifndef identifier
	      If the identifier	macro was not defined the next block  of  code
	      (until  a	 matching  #else  or #endif directive was detected) is
	      byte-compiled. Otherwise,	the block of code is ignored.

       o      #else
	      Terminates a #ifdef and #ifndef directive, reversing the	accep-
	      tance  decision  about the following code. Only one #else	direc-
	      tive can be associated with #if(n)def directives.

       o      #endif
	      Terminates the  preprocessor  block  starting  at	 the  matching
	      #ifdef, #ifndef or #else directive. The #endif directory and its
	      matching #if(n)def directive must	be specified in	the same file.

       o      #undef identifier
	      Remove identifier	from the set of	defined	symbols. This does not
	      affect  the  specification  of any previously defined symbols in
	      which identifier's  definition  has  been	 used.	If  identifier
	      hasn't been defined a warning is issued.

       Icmake supports the following five data and value types:

       o      ASCII character constants
	      ASCII  character constants are individual	characters, surrounded
	      by single	or double quotes. Single characters (e.g., 'a')	repre-
	      sent  the	 character  itself.  Standard  escape sequences	(e.g.,
	      '\n') are	supported and represent	their standard converted value
	      (e.g.,  '\n'  represents ascii value 10 (decimal)). Non-standard
	      escape sequences (e.g., '\x') represent the ascii	character fol-
	      lowing  the  escape  character  (so '\x' equals 'x'). Escape se-
	      quences consisting of three octal	 digits	 represent  the	 ascii
	      character	 corresponding	to  the	 octal value modulo 256	(e.g.,
	      '\123'). Escape sequences	consisting of an  x  followed  by  two
	      hexadecimal  digits  represent the ascii character corresponding
	      to the hexadecimal value (e.g., '\xa4').

       o      int
	      Integral values, ranging from -0x8000 through 0x7fff.  int  con-
	      stants 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, fol-
	      lowed by one or more hexadecimal digits) or as  ASCII  character

       o      string
	      Text  values: text (or `string') constants are delimited by dou-
	      ble quotes. Multiple string constants may	be concatenated, but a
	      single  string constant may not span multiple lines. String con-
	      stants separated by white	space only  (i.e.,  blanks,  newlines,
	      comment)	are  concatenated and represent	one single string con-
	      stant. To	indicate an end-of-line	in a string constant  use  the
	      \n escape	sequence.

	      ASCII  character	constants using	double quotes can also be used
	      in arithmetic expressions	if one of the operands is an int.

	      Likewise,	ASCII character	constants using	single quotes  may  be
	      used in situations where	string operands	are expected.

       o      list
	      A	 data structure	containing a series of individually accessible
	      string values. When a list contains elements, its	first  element
	      has index	0.

	      List  constants can also be defined. They	consist	of comma-sepa-
	      rated strings (which may be string variables or expressions  re-
	      turning  string  values)	and are	surrounded by square brackets.

		  list words = ["a", "list", "constant"];

       o      void
	      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 inside func-
       tions (not only at the top of  compound	statements  but	 also  between
       statements  and	in the initialization section of for-statements). When
       defined inside functions, the standard C	scoping	and  visibility	 rules
       apply. Variables	are strongly typed, and	cannot have type void.

       Variables may be	initialized when they are defined. Initializations are
       expressions which may use predefined or	user-defined  functions,  con-
       stant  values, and values of variables. Functions or variables that are
       used for	initialization must be visible at the initialization point.

       The following predefined	int constants are available:

       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

       The following constants are architecture	dependent:

       symbol		1 when defined on the platform,	otherwise 0
       unix		Unix, usually with GNU'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


       All C operators (including the ternary operator)	are available  (except
       for pointer operators, as icmake	does not support pointers). They oper-
       ate like	their C-programming language's counterparts. Comparison	opera-
       tors return 1 if	the comparison is true,	otherwise 0 is returned.


       For  string  variables  and/or  constants  the  following operators are
       available (a and	b represent string variables or	constants):

       o      a	+ b: returns a new string value	containing  the	 concatenation
	      of  string values	a and b. Note that string constants may	be di-
	      rectly concatetated (without using the +	operator),  e.g.,  the
	      following	two lines both define the string "hello	world":

		  "hello "   "world"
		  "hello " + "world"

       o      a	 += b: a must be a  string variable, to	which the string vari-
	      able or value b is appended.

       o      string comparisons: operators == != _= _=	_ _ != and == return 1
	      if  the comparison is true, otherwise 0. Ordering	comparison op-
	      erators use the (case sensitive) character ordering  defined  by
	      the ASCII	character set.

       o      !a:  the	boolean	 ! (not) operator returns 1 if the string a is
	      empty, otherwise it returns 0.  Strings  containing  white-space
	      characters are not empty.

       o      a	 younger b, a newer b: returns 1 if file a is more recent than
	      file b. E.g., ""	newer "source.o". The files a and b do
	      not have to exist:
	      if both don't exist 0 is returned;
	      if a doesn't exist 0 is returned;
	      if b doesn't exist, 1 is returned;
	      if they are equally old 0	is returned.

	      The  predefined function exists()	(see below, section PREDEFINED
	      FUNCTIONS) can be	used to	test explicitly	whether	a file exists.

       o      a	older b: returns 1 if file a  is  older	 than  file  b.	 E.g.,
	      "libprog.a"  older  "source.o". The files	a and b	do not have to
	      if both don't exist 0 is returned;
	      if a doesn't exist, 1 is returned;
	      if b doesn't exist 0 is returned;
	      if they are equally old 0	is returned.

       o      []: the index operator retrieves a character from	a string vari-
	      able  or	constant:  it returns a	string as an rvalue. Thus, the
	      following	statement compiles OK:

		   // assume str1 and str2 are strings
		  str1 = str2[3];

	      but the following	statement won't	compile:

		  str2[3] = "a";

	      If an invalid (out of bounds) index value	is specified an	 empty
	      string is	returned.

       o      The `backtick` operator (`string cmd`)
	      A	 string	 placed	 between  two  backticks  is  executed	by the
	      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 stan-
	      dard error stream	output is not collected	by the backtick	opera-
	      tor.  However, standard shell redirection	may be used to collect
	      the standard error stream's output. Example:

		  printf(`"ls"`);     // prints	the elements in
				      // the current directory

	      The predefined function eval(string cmd)	behaves	 exactly  like
	      the backtick operator: they are synonyms.	 )


       For  list  type	variables  and/or  values  the following operators are

       o      a	+ b: returns a new list	value containing the concatenation  of
	      list  values a and b. This is not	a set operation: if an element
	      appears both in a	and in b, they will appear twice  in  the  re-
	      sulting  list (set-addition is provided by the built-in function

       o      a	- b: returns a new list	value containing  the  elements	 in  a
	      that  are	 not present in	b. This	is a set-difference operation:
	      the returned list	contains all elements in a that	are  not  ele-
	      ments of b.

       o      a	+= b: elements in b are	added to the elements in a, which must
	      be a  list variable.  This is not	a set operation.

       o      a	-= b: elements in b are	removed	from the elements in a,	 which
	      must  be a list variable.	 This is a set operation: all elements
	      of a that	are found in b are removed from	a.

       o      list equality comparisons: operators != and == may be applied to
	      list  values  or	variables. Operator == returns 1 if both lists
	      have element-by-element identical	elements, otherwise 0  is  re-
	      turned. Operator != reverses the result of ==.

       o      !a:  the	boolean	 !  operator returns 1 if the list a is	empty,
	      otherwise	0 is returned.

       o      []: the index operator retrieves a  list	element	 from  a  list
	      variable:	 it returns a string as	an rvalue. Therefore, the fol-
	      lowing statement compiles	OK:

		  // assume lst	is a list, str is a string
		  str =	lst[3];

	      but the following	statement won't	compile:

		  lst[3] = str;

	      If an invalid (out of bounds) index value	is specified an	 empty
	      string is	returned.


       Type-casts using	the standard C cast-operator can be used to cast

       o      strings to ints and vice versa ((int)"123", (string)55)
	      If  the  content	of a string does not represent a (decimal) int
	      value 0 the cast returns	0;

       o      Strings to lists (list lst = (list)"hello"): this	returns	a list
	      having one element (hello) (note that casting a string to	a list
	      as shown is overkill as list lst = ["hello"] performs  the  same

       Icmake  offers the following subset of C's statements. They can be used
       as in the C programming language.

       o      expression ;
	      The plain	expression statement;

       o      The compound statement
	      Variables	of any type may	be defined  and	 initialized  anywhere
	      inside  any  compound  statement.	 The  visibility of a variable
	      starts at	its point of definition.

       o      if (condition) statement
	      Inside the condition a variable may be defined and  initialized.

		  if (string str = getText())

	      In  this	example, process is not	called if getText() returns an
	      empty string. The	variable str does not exist either  before  or
	      after the	if statement.
	      Initialization  and  then	using the variable in a	subsequent ex-
	      pression,	separated by a semicolon from the  definition  is  not
	      supported	 (e.g.,	 if  (string  str = getText() ;	str) cannot be

       o      if (condition) statement else statement
	      Like the previous	statement, inside the condition	a variable may
	      be defined and initialized.

       o      for (init; condition; increment) statement
	      Variables	 (of a single type) may	be initialized (and optionally
	      be defined) in the init section. The init, condition and	incre-
	      ment  sections  may remain empty.	The empty condition section is
	      interpreted as `always true'.

       o      while (condition)	statement
	      Inside the condition a variable may be defined and initialized.
	      A	complementary  do ... while() statement	is not available. Note
	      that  defining  a	 variable,  using an initialization expression
	      means that the initialization expressing is executed at each it-
	      eration  of  the	while  statement. Thus the following statement
	      never ends, and displays a never ending stream of	values 10:

		  while	(int x = 10)
		      printf(x--, "\n");

       o      return;, and return expression;
	      Plain return statements can be used in void functions,  and  re-
	      turn  expression statements are used in other type of functions.
	      The function main	has return type	void and so in main only plain
	      return  statements  can  be used.	 By default an icmake script's
	      exit value equals	0. Use the built-in function exit (see	below)
	      to specify any other exit	value.

	      Be  advised:   the  behavior of non-void functions not returning
	      values is	undefined.

       o      break
	      Leaves for and while statements, overruling the statement's con-

       o      continue
	      Continues	with the next iteration	of a for or while statement.

       o      exit(expression)
	      Ends  the	 execution  of	an  icmake-script. The expression must
	      evaluate to an int value,	which becomes the script's exit	value.

       Icmake provides the following predefined	functions, which can  be  used
       anywhere	 in  icmake  scripts. The functions are	ordered	by categories,
       and within categories they are ordered alphabetically by	function name.
       Five categories are distinguished:

       o      Functions	operating on ints:
	      these  functions	only  have one purpose:	they receive int argu-
	      ments and	simply process those arguments;

       o      Functions	operating on lists:
	      these functions only have	one purpose: their main	argument is  a
	      list, which is somehow manipulated;

       o      Functions	operating on strings:
	      these  functions only have one purpose: their main argument is a
	      string, which is somehow manipulated;

       o      Functions	manipulating filenames:
	      these functions receive filenames	as their string	arguments, and
	      return  modified filenames (e.g.,	by changing the	argument's ex-

       o      System-related functions:
	      these functions interface	to facilities provided by the  operat-
	      ing system, like executing programs or changing the environment.

       Functions operating on ints:

       o      string ascii(int value)
	      returns value as a string: ascii(65) returns the string "A";

       o      echo(int opt)
	      controls echoing of called programs (and their arguments), spec-
	      ify OFF if echoing is not	 requested.  By	 default  echo(ON)  is

       Functions operating on lists:

       o      string element(int index,	list (or string) var)
	      acts  identically	to the index operator: refer to	the index ([])
	      operator in section OPERATORS.

       o      list fgets(string	file, list offset)
	      see the system functions section;

       o      int listfind(list	lst, string str)
	      returns the first	index in lst where the string str is found, or
	      -1 if lst	does not contain str;

       o      int listlen(list l)
	      returns the number of elements in	list;

       o      list listunion(list lhs, list rhs)
	      returns  a  list containing the union of the elements in lhs and
	      the elements of rhs;

       o      list listunion(list lst, string str)
	      returns a	list containing	the union of the elements in  lst  and

       Functions operating on strings:

       o      int ascii(string str)
	      returns  the first character of str as an	in: ascii("A") returns

       o      string resize(string str,	 int  newlength)  returns  a  copy  of
	      string  str,  resized  to	newlength characters.  If newlength is
	      negative then an empty string is returned, if newlength  exceeds
	      str's  length then the newly added characters are	initialized to
	      blank spaces;

       o      int strchr(string	str, string chars)
	      returns the first	index in str where any of  the	characters  in
	      chars is found, or -1 if str does	not contain any	of the charac-
	      ters in chars;

       o      int strlen(string	str)
	      returns the number of characters in str (not counting the	termi-
	      nating NUL-character);

       o      int strfind(string haystack, string needle)
	      returns index in haystack	where needle is	found, or -1 if	needle
	      is not found in haystack;

       o      int strformat(string format, argument(s))
	      returns a	string constructed from	the format  string  containing
	      placeholders %1 .. %2 to refer to	arguments following the	format
	      string. The specification	%1 refers to the first	argument  fol-
	      lowing the format	string.	If fewer arguments than	n are provided
	      then additional 0	arguments are provided by icmake. Example:

		  void main()
		      string s2	= = strformat("%1 %2 %1\n", 10,	20);
		      printf("s2 = ", s2);	  // shows: s2 = 10 20 10

       o      string strlwr(string str)
	      returns a	lower-case duplicate of	str;

       o      list strtok(string str, string separators)
	      returns a	list containing	all substrings of str separated	by one
	      or  more	(consecutive)  characters in separators: strtok("hello
	      icmake's+world", " +")  returns  a  list	containing  the	 three
	      strings "hello", "icmake's", and "world";

       o      string strupr(string str)
	      returns an upper-case duplicate of str.

       o      string substr(string text, int offset, int count)
	      returns  a  substring of text, starting at offset, consisting of
	      count characters.	If offset exceeds  (or	equals)	 the  string's
	      size or if count _= 0, then an empty string is returned. If off-
	      set is less than 0 then offset = 0 is used;

       o      string trim(string str)
	      returns a	copy of	str without leading and	trailing white spaces;

       o      string trimleft(string str)
	      returns a	copy of	str without leading white spaces;

       o      string trimright(string str)
	      Returns a	copy of	str without trailing white spaces;

       Functions manipulating filenames:

       o      string change_base(string	file, string base)
	      returns  file  whose   base   name   is	changed	  into	 base:
	      change_base("/path/", "out") returns "/path/";

       o      string change_ext(string file, string ext)
	      returns  file  whose  extension is changed into ext: rss_change-
	      Ext("", "o") returns "source.o".	The extension  of  the
	      returned string is separated from	the file's base	name by	a sin-
	      gle   dot	  (e.g.,   rss_changeExt("source.",   ".cc")   returns

       o      string change_path(string	file, string path)
	      return	file	whose	 path	 is    changed	  into	 path:
	      change_path("tmp/binary",	"/usr/bin") returns "/usr/bin/binary".
	      To remove	the path specify path as an empty string;

       o      string get_base(string file)
	      returns the base name of 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 fi-
	      nal dot is found,	the file name is the base name.	E.g., the base
	      name  of	a.b  equals  a,	the base name of a.b.c equals a.b, the
	      base name	of a/b/c equals	c;

       o      string get_dext(string file)
	      returns the extension of	file,  including  the  separating  dot
	      (hence the d in dext). The extension is all information starting
	      at the filename's	final dot. If file does	not have a  final  dot
	      then an empty string is returned;

       o      string get_ext(string file)
	      returns  the  extension of file, without the separating dot. The
	      extension	are all	characters in file starting  at	 file's	 final
	      dot. If no final dot is found, an	empty string is	returned;

       o      string get_path(string file)
	      returns  file's  path-prefix. The	path prefix is all information
	      up to (and including) the	final directory	separator  (which  is,
	      depending	 on  the  operating system, a forward slash or a back-
	      slash).  If no path is found, an empty strring is	returned;

       System-related functions:

       o      void arghead(string h)
	      helper function of exec()	(see also below	 at  exec()):  defines
	      the  `argument  head'  that is used with exec(). By default, the
	      `argument	head' is an empty string. The argument	head  is  text
	      that  is	prefixed  to exec arguments, like a directory in which
	      provided arguments are found;

       o      void argtail (string t)
	      helper function of exec()	(see also below	 at  exec()):  defines
	      the  `argument  tail'  that is used with exec(). By default, the
	      `argument	tail' is an empty string. The argument	tail  is  text
	      that is appended to exec arguments, like the extensions of files
	      that are passed as arguments to exec;

       o      string chdir([int	check,]	string dir)
	      returns the script's working directory at	the point where	 chdir
	      is  called as an absolute	path, and changes the script's working
	      directory	to dir (which may be specified as absolute or relative
	      to  the  script's	current	working	directory). The	first argument
	      is optional: if omitted and the change of	 directory  cannot  be
	      performed	 then  the  icmake-script  ends	 with exit value 1; by
	      specifying P_NOCHECK the function	won't terminate	the script but
	      merely returns the script's current working directory.

	      Use  chdir(".")  to merely obtain	the current working directory;
	      use chdir("") to obtain the script's startup working directory;

       o      cmdhead(string h)
	      helper function of exec()	(see also below	at exec()).  Defines a
	      `command	head'  that  is	 used with exec(). By default it is an
	      empty string. It can be used to specify, e.g., compiler  options
	      when  the	 arguments  themselves	are  modified  by  arghead and
	      argtail.	Cmdhead	is used	unmodified;

       o      cmdtail(string t)
	      helper function of exec()	(see also below	at exec()).  Defines a
	      `command	tail  that  is	used  with exec(). By default it is an
	      empty string. It can be used to specify a	 final	argument  (not
	      modified by arghead and argtail);

       o      list eval(string str)
	      this  function can be used instead of the	backtick operator. The
	      example provided with the	backtick operator could	therefore also
	      have been	written	like this:

		  printf(eval("ls")); // prints	the elements in	the current
				      // directory

       o      int exec([int check,] string cmd,	argument(s))
	      Executes	the  command cmd with (optional) arguments. Each argu-
	      ment is prefixed by arghead and postfixed	by argtail. Note  that
	      no   blanks  are	inserted  between  arghead,  argument(s),  and
	      argtail. The thus	modified arguments are concatenated, separated
	      by  single blanks. Cmdhead is inserted between cmd and the first
	      argument (delimited by single blanks) and	cmdtail	is appended to
	      the  arguments, separated	by a single blank. PATH	is searched to
	      locate cmd. 0 is returned.

	      The first	argument is optional: if omitted and the command  does
	      not  return  0  the  icmake  script  terminates.	By  specifying
	      P_NOCHECK	exec won't terminate the script	but returns the	called
	      command's	exit status, or	0x7f00 if the command wasn't found;

       o      execute([int  checking,]	string	cmd,  string  cmdhead,	string
	      arghead, argument(s), string argtail, string cmdtail)
	      Same functionality as the	previous function,  but	 the  cmdhead,
	      arghead,	argtail, and cmdtail are explicitly specified (and are
	      reset to empty strings after executing cmd);

       o      int exists(string	file)
	      if file exists, 1	is returned, otherwise 0 is returned;

       o      list fgets(string	file, list offset)
	      the next line found at offset value offset[3] is read from file.
	      Pass an empty list to fgets to read file from its	beginning.

	      The returned list	has four elements:

	      its  first  element  ([0])  contains  the	read line (without the
	      line's \n	line terminator);

	      its second element ([1]) contains	the line's \n line  terminator
	      (or an empty string if the line was not terminated by a \n);

	      its  third  element ([2])	contains the string OK if the line was
	      successfully read	and FAIL if reading from file failed;

	      its fourth element ([3]) contains	the  offset  beyond  the  last
	      read byte.

	      To  read	multiple  lines, pass the returned list	as argument to

		  list ret;
		  while	(ret = fgets("filename", ret))

       o      int fprintf(string filename, argument(s))
	      appends all (comma separated) arguments to  the  file  filename.
	      Returns the number of printed arguments.

	      If the first argument (following filename) contains placeholders
	      (%1, %2, ... %n) then  that  argument  is	 considered  a	format
	      string  (see also	the function strformat in the string functions
	      section for additional information about format  strings).  Some

		  fprintf("out", "hello", "world", '\n');
		  fprintf("out", "%1 %2\n", "hello", "world");

       o      string getch()
	      returns  the  next  pressed  key	as a string (pressing the `En-
	      ter'-key is not required);

       o      list getenv(string envvar)
	      returns the value	of environment variable	envvar in a list  con-
	      taining two elements:

	      if  the first element ([0]) is "1" then the environment variable
	      was defined;

	      environment variables are	of the form variable=value.   If  ele-
	      ment  [0]	 is  "1"  then	the returned list's second element [1]
	      holds the	value part of the environment variable,	which is empty
	      if the environment variable is merely defined;

       o      int getpid()
	      returns  the  process-id	of  the	 icmake	 byte code interpreter

       o      string gets()
	      returns the next line read from the keyboard as  a  string.  The
	      line  contains  all  enteed characters until the `Enter'-key was
	      pressed. The `Enter'-key's value itself is not stored in the re-
	      turned string;

       o      list makelist([int type =	O_FILE], string	mask)
	      the  argument  type  is  optional, in which case O_FILE is used.
	      Makelist returns a list of all type entries matching mask. E.g.,
	      makelist("*.c")  returns	a  list	containing all files ending in
	      .c. For type one of the following	set of values can be  used  to
	      obtain a more specific selection of directory entries:

	      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

	      In  Unix-type operating systems the pattern * does not match en-
	      tries starting with a dot	(hidden	entries). To obtain a list  of
	      such entries use the pattern .*;

       o      list  makelist([int  type	= O_FILE,] string mask,	{newer,older},
	      string comparefile)
	      the (optional) parameter type may	be specified as	in the	previ-
	      ous  variant  of	makelist.  The	third parameter	must be	either
	      newer (or	younger) or older. A list of  all  files  is  returned
	      matching	mask  which are, resp.,	newer or older than a provided
	      comparefile. Note	that newer  and	 younger  are  operators,  not

       o      int printf(argument(s))
	      the  function's  (comma  separated) arguments are	written	to the
	      standard output file. If the first argument contains %1, %2, ...
	      %n specifications	then it's considered a format string (see also
	      the function strformat in	the string functions section for addi-
	      tional  information  about  format strings). Like	fprintf	printf
	      returns the number of printed arguments;

       o      int putenv(string	envvar)
	      adds envvar to the current icmake-script	environment.  Use  the
	      format: "VAR=value". The function	returns	0;

       o      list stat([int check,] string entry)
	      Returns  stat(2) information of directory	entry entry as a list.
	      The first	argument is optional: if omitted and calling the  sys-
	      tem  stat	 function  fails then the icmake-script	ends with exit
	      value 1; by specifying P_NOCHECK the  function  won't  terminate
	      the script but returns the return	value of the system stat func-

	      The returned list	has two	elements:

	      its first	element	 ([0])	holds  the  entry's  attributes.   At-
	      tributes	are  returned  as  or-ed combinations of the following
	      bit-flags	(cf. stat(2)):


	      its second element ([1]) contains	the entry's size in bytes;

       o      int system([int check,] string command)
	      executes command using the system(3) function. The  first	 argu-
	      ment  is optional: if omitted and	calling	the system(3) function
	      does not return 0	then the icmake-script ends with exit value 1;
	      by specifying P_NOCHECK icmake's system function won't terminate
	      the script but returns the return	value of the  system(3)	 func-
	      tion  (normally  the  executed command's exit value). The	string
	      command may use redirection and/or piping;

       void main

       Icmake scripts must be provided with a user-defined function main.  The
       function	 main has three	optional parameters, which may be omitted from
       the last	one (envp) to the first	(argc),	like in	C. Its full  prototype
       is (note: void return type):

	   void	main(int argc, list argv, list envp)

       In main the parameter

       o      argc represents the number of elements in	argv;

       o      argv  contains  the arguments, with element 0 being equal	to the
	      name of the .bim file;

       o      envp contains the	`environment' variables. The function  listlen
	      can be used to determine the number of its elements. Elements in
	      envp have	the form variable=value. Alternatively,	 the  function
	      getenv  can  be used to retrieve a specific environment variable
	      immediately.  Example (the implementations of  the  user-defined
	      functions	 usage,	 modified, and compile are left	as an exercise
	      for the reader):

		  void main(int	argc, list argv)
		      if (argc == 1)
			  usage(element(0, argv));

		      if (list toCompile = modified("*.cc"))
			  for (int idx = listlen(toCompile); idx--; )

	      After initializing all global variables in order of their	 defi-
	      nitions  main is called by icmake's run-time support system. Ic-
	      make scripts end once main returns (or exit  is  called  by  the

       Additionally defined user functions

       Additional  functions may be defined. Once defined, they	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.

       User-defined functions must have	the following elements:

       o      The function's return type, which	must  be  one  of  void,  int,
	      string or	list.  There is	no default type.

       o      The function's name, e.g., compile.

       o      A	 parameter list, defining zero or more comma-separated parame-
	      ters. The	parameters themselves consist of  a  type  name	 (int,
	      string,  or  list) followed by the parameter's identifier. E.g.,
	      (string outfile, string source).

       o      A	body surrounded	by a pair of curly braces ({ and }).

       Function	bodies may contain (optionally initialized)  variable  defini-
       tions.  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 int variable is initialized to 0, a string	is initialized
       to an empty string ("") and a list is initialized to an empty list.

       In  addition  to	 variable definitions, bodies may contain zero or more
       statements (cf. section FLOW CONTROL). Note that	variables may  be  de-
       fined  (and optionally initialized) anywhere inside functions, and also
       in the conditions of if and while statements and	in the	initialization
       section of for statements.

       The behavior of icmake-scripts using non-void functions that do not re-
       turn values is not defined.

       The icm-dep program is  a  support  program  for	 icmake	 to  determine
       source-file  dependencies.  It  is called automatically when USE_ALL or
       PRECOMP is specified in the icmconf file	that is	processed by icmake.

       To start	its work, the dependencies-analyzer  icm_dep  needs  one  com-
       mand-line  argument: go.	Any other argument results in icm_dep perform-
       ing a `dry run':	it then	performs all its duties	(and verbose  messages
       are  displayed  as if go	had been specified), but no files (precompiled
       headers or USE_ALL files) are touched or	removed.  If  neither  options
       nor  arguments  are  specified  icm_dep writes its usage	summary	to the
       standard	output.

       Options of icm-dep may immediately after	icmake's --icm-dep  option  be
       specified. The following	options	are recognized:

       o      --classes=filename (-c)
	      by  default,  icm-dep inspects dependencies of the classes whose
	      directories are mentioned	in the file CLASSES.  Furthermore,  if
	      the  icmconf(7)  file  specifies PARSER_DIR and SCANNER_DIR then
	      those directories	are also considered.  Use this option  if  in-
	      stead of CLASSES another file should be inspected;

       o      --help (-h)
	      icm-dep writes a summary of its usage to the standard output and

       o      --icmconf=filename (-i)
	      by default icm-dep inspects the content of icmconf files,	 look-
	      ing  for	USE_ALL	and PRECOMP specifications. Use	this option if
	      instead of icmconf another file should be	inspected;

       o      --mainih=mainheader (-m)
	      the icmconf file uses the	#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  CLASSES  file.  CLASSES does	not specify a top-level	direc-
	      tory. The	name of	the top-level header file to precompile	can be
	      specified	using this option. By default it is main.ih;

       o      --gch
	      by  default  precompiled	header	files are inspected if icmconf
	      contains a #define PRECOMP specification.	If it  does  not,  but
	      precompiled  headers should nonetheless be inspected, the	option
	      --gch can	be provided;

       o      --no-gch
	      by default precompiled header files  are	inspected  if  icmconf
	      contains	a  #define PRECOMP specification. If in	that case pre-
	      compiled headers should not be inspected,	 the  option  --no-gch
	      can be provided;

       o      --no-use-all
	      by  default files	named at the #define USE_ALL specification are
	      inspected	if icmconf contains such a specification. To  suppress
	      inspections of `USE_ALL' files provide this option;

       o      --use-all=filename
	      by default files named at	#define	USE_ALL	specifications of icm-
	      conf files are inspected.	If the USE_ALL define is not specified
	      but  `USE_ALL'  files should nonetheless be inspected, then pro-
	      vide this	option,	specifying the name of files to	use as USE_ALL

       o      --verbose	(-V)
	      this option can be specified multiple times. The number of times
	      it is specified determines icm_dep's verbosity. If not used then
	      icm-dep  silently	 performs  its duties. If specified once, then
	      icm-dep reports to the standard output what actions it performs;
	      if  specified  twice  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;

       o      --version	(-v)
	      icm-dep  reports	 its version number to the standard output and

       The icmun program expects one argument, the binary (bimfile) file  pro-
       duced  by `icmake -c'. It disassembles the binary file an shows the as-
       sembler instructions and	structure of the binary	 file.	Note  that  in
       standard	 installations	icmun is not located in	one of the directories
       of the PATH environment variable, but is	located	in the /usr/lib/icmake

       As  an  illustration, assume the	following script is compiled by	icmake
       (e.g., by calling icmake	-c

	   void	main()
	       printf("hello world");

       the resulting demo.bim file can be processed by	icmun  (e.g.,  calling
       /usr/lib/icmake/icmun  demo.bim.	Icmun then writes the following	to the
       standard	output fle:

	   icmun by Frank B. Brokken (
	   icmun V9.03.00, copyright (c) GPL 1992-2020.

	   Binary file statistics:
	       strings		 at offset 0x0025
	       variables	 at offset 0x0031
	       filenames	 at offset 0x0031
	       first instruction at offset 0x001f

	   String constants dump:
	       "hello world"

	   Disassembled	code:
	       [0014] 06 00 00	 push string "hello world"
	       [0017] 05 01 00	 push int 0001
	       [001a] 1b 1d	 callrss 29 (printf)
	       [001c] 1c 02	 add sp, 2
	       [001e] 23	 ret
	       [001f] 21 14 00	 call [0014]
	       [0022] 04	 push int 0
	       [0023] 24	 pop reg
	       [0024] 1d	 exit

       The mentioned paths are sugestive only and may vary over	different  ic-

       o      /usr/bin/icmake: the main	icmake program;

       o      /usr/bin/icmbuild:  the  wrapper	program	 around	 the  icmbuild
	      script handling standard program maintenance;

       o      /usr/bin/icmstart: an icmake-script that is can be used to  cre-
	      ate the startup-files of new projects;

       o      /usr/lib/icmake/icm-comp:	the compiler called by icmake;

       o      /usr/lib/icmake/icm-exec:	 the  byte-code	 interpreter called by

       o      /usr/lib/icmake/icm-dep: the support program handling class- and
	      precompiled header dependencies;

       o      /usr/lib/icmake/icm-pp: the preprocessor called by icmake;

       o      /usr/lib/icmake/icmun: the icmake	unassembler.

       The  distribution  (usually in /usr/share/doc/icmake) contains a	direc-
       tory examples containing	additional examples of icmake script.

       icmbuild(1), icmconf(7),	icmstart(1), icmstart.rc(7), make(1)

       Standard	comment	starting  on lines containing preprocessor  directives
       may not extend over multiple lines.

       Path names containing blanks are	not supported.

       The  functions sizeof(list lst) and sizeoflist(list lst)	are deprecated
       and should no longer be used. They are removed in a future  version  of
       icmake. Use listlen(list	lst) instead.

       This  is	 free software,	distributed under the terms of the GNU General
       Public License (GPL).

       Frank B.	Brokken	(

icmake.9.03.01.tar.gz		   1992-2020			     icmake(1)


Want to link to this manual page? Use this URL:

home | help