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

FreeBSD Manual Pages

  
 
  

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

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

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

       icmun bimfile

DESCRIPTION
       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
	      icm-dep).

       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:

       o      PREPROCESSOR DIRECTIVES
	      -	supported preprocessor directives, like	#include and #define;

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

       o      PREDEFINED CONSTANTS
	      -	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);

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

       o      USER DEFINED FUNCTIONS
	      -	 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.

OPTIONS
       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
	      options.

       o      --preprocess (-p)
	      The icmake source	 file  is  only	 preprocessed,	and  the  pre-
	      processed	 file  is written to icmake's second file argument (by
	      default `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
	      this:

		  #!/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.

PREPROCESSOR DIRECTIVES
       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 ...

	      Alternatively,

		  #!/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-
	      lowed.

	      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.

DATA TYPES
       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
	      constants.

       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.
	      E.g.,

		  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.

PREDEFINED CONSTANTS
       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
       --------------------------------------------------------------

OPERATORS
       int-operators:

       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.

       string-operators:

       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., "source.cc"	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
	      exist:
	      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.	 )

       list-operators:

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

       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
	      listunion).

       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.

       Casting:

       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
	      initialization).

FLOW CONTROL
       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.
	      E.g,

		  if (string str = getText())
		      process(str);

	      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
	      used).

       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-
	      dition.

       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.

PREDEFINED FUNCTIONS
       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-
	      tension);

       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
	      used;

       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
	      str;

       Functions operating on strings:

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

       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/demo.im", "out") returns "/path/out.im";

       o      string change_ext(string file, string ext)
	      returns file whose extension is changed  into  ext:  rss_change-
	      Ext("source.cc",	"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
	      "source.cc");

       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
	      fgets:

		  list ret;
		  while	(ret = fgets("filename", ret))
		  {
		      process(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
	      examples:

		  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
	      icm-exec;

       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
	      strings;

       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-
	      tion.

	      The returned list	has two	elements:

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

		  S_IFCHR     S_IFDIR	  S_IFREG
		  S_IREAD     S_IWRITE	  S_IEXEC

	      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;

USER DEFINED FUNCTIONS
       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--; )
			      compile(toCompile[idx]);
		      }
		  }

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

       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.

ICM-DEP
       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
	      terminates;

       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
	      files;

       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
	      terminates.

icmun
       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
       directory.

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

	   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 (f.b.brokken@rug.nl)
	   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

FILES
       The  mentioned paths are	sugestive only and may vary over different ic-
       make-installations:

       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
	      icmake;

       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.

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

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

BUGS
       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.

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

AUTHOR
       Frank B.	Brokken	(f.b.brokken@rug.nl).

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

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=icmake&sektion=1&manpath=FreeBSD+Ports+15.0>

home | help