tai(S) 6 January 1993 tai(S) Name tai_end, tai_get, tai_init - get MMDF site tailoring information Syntax cc . . . -lmmdf tai_end () tai_get (maxargs, argv) int maxargs; char *argv[]; tai_init (file) char file[]; Description The tai package is designed to acquire site-dependent information, from an external, clear-text file. It supports a simple file syntax. File format Tailoring information comprises a set of lines. Lines comprise a set of fields. Usually the first field on the line is treated as the name of the line. Fields may be separated by a space, horizontal tab, comma, semicolon, colon, or an equal sign. These separators are treated simi- larly. However, a space and a tab are skipped at the beginning of a field. Also, if two fields are separated by an equal sign, they are assumed to be a key/value pair and are treated somewhat differently by taiget. Fields are formed according to a syntax that is similar to C programs. A sequence of printable, nonspecial characters is a field. To include a special character, such as a space or a comma, the character must be pre- ceded by a backslash. The sequence backslash octal-string specifies a single eight-bit character (for example, \040 indicates space). If a field is surrounded by quotation marks, only the quotation mark and the backslash are treated as special. The following shows how different argument lines are parsed. A file con- taining the following is parsed into four sets of argument lists: loc UDel-Relay que /usr/mmdf/que/home chan a,, arpa\040net\ foo=bar chan b backup blat="gelp,blat=boop" The parsed argument lists are: 'loc' 'UDel-Relay' 'que' '/usr/mmdf/que/home' 'chan' 'a' '' '=' 'arpa net foo' 'bar' 'chan' 'b' 'backup' '=' 'blat' 'gelp,blat=boop' The formal syntax for a tailoring file is given below, in modified BNF. An asterisk indicates a repetition of zero or more times. Parentheses surround alternatives. file = *line line = *field "\n" field = *(SPACE / TAB) value *value SPECIAL value = CHAR / echar / qstring qstring = '"' *qvalue '"' qvalue = CHAR / DELIM / echar echar = "\\" (SPECIAL / FORMAT / octal) SPECIAL = DELIM / '"' / "\\" DELIM = SPACE / TAB / "," / ";" / ":" CHAR = {Any ASCII character not a SPECIAL} FORMAT = 'n' / 'r' / 'f' / 'b' octal = ochar [ochar [ochar]] ochar = {Digit 0-7} Procedure calls The taiinit call initializes the tailoring package. Its argument is the name of the file that contains tailoring information. Since the name is not built into the package, it is possible to have several different tailoring files. The taiinit call returns 0 on normal termination. The taiget call acquires and parses the next line of the tailoring file. The first argument to the procedure is the maximum number of tailoring arguments (fields) that can be accepted from the line. The second pro- cedure argument is an array which will hold character pointers to the tailoring arguments. The list of pointers is terminated by a zero-valued pointer. The taiget call returns the actual number of arguments that were parsed and returns 0 when it has reached the end of the file. The data are in permanent storage, so that they do not have to be copied before the next call to taiget. The argument list is built in the same sequence as the fields are listed in the argument line. Separator characters are not returned, except for an equal-sign. When an equal-sign is used, three entries are consumed in the argument pointer array. The first entry points to the string ``='', the second entry is for the key and the third entry is for the value. (An equal-sign is treated as an infix operator, but the parsed fields are stored in prefix form.) When initialization is complete, call taiend for cleanup. The taiend call returns 0 on normal termination. Usage The user program calls taiinit and then calls taiget until all of the tailoring information has been processed. If there are several different software modules that need to be initialized, then the information returned by taiget can be passed consecutively to the modules' initiali- zation routines, until one of the routines returns a value indicating that it has ``consumed'' the information. The following code demonstrates the use of this package: #include "util.h" main () { char *taiargs[20]; int nargs; register int ind; if (tai_init ("init.tai") < OK) { perror ("tai_init"); /* initialize */ exit (-1); } while ((nargs = tai_get (20, taiargs)) > 0) for (ind = 0; ind < nargs; ind++) { if (user_init (taiargs)) /* who uses it? */ continue; /* user-level information */ if (util_init (taiargs)) continue; /* the utilities package */ /* was not consumed; ignore it */ } if (nargs < 0) /* we had some problem */ perror ("tai_get"); tai_end (); exit ((nargs < 0) ? -1 : 0); } Diagnostics All routines return -1 on error. See also llog(S), mlsend(S), mmdf(S), phs(S) Standards conformance The taiinit, taiget, and taiend calls are not part of any currently supported standard; they were developed at the University of Delaware and are used by permission.