home *** CD-ROM | disk | FTP | other *** search
- From: istvan@hhb.UUCP (Istvan Mohos)
- Newsgroups: alt.sources
- Subject: Subject: ILIB Unix Toolkit in C
- Message-ID: <552@hhb.UUCP>
- Date: 8 Jun 90 20:56:30 GMT
-
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # This is part 06 of a multipart archive
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= iman/icue.tex ==============
- echo "x - extracting iman/icue.tex (Text)"
- sed 's/^X//' << 'SHAR_EOF' > iman/icue.tex &&
- X% XREF icue inl inull
- X
- X\def\name{ICUE}
- X\def\IT{{\bb icue()}}
- X
- X\S{NAME}
- X
- X{\bb icue} --- buffer management
- X
- X{\bb inl} --- return pointer to next {\myit newline\/} or NUL byte
- X
- X{\bb inull} --- return pointer to next NUL byte
- X
- X\S{SYNOPSIS}
- X{\obeylines \bb
- Xvoid
- Xicue (ptr)
- Xchar **ptr;
- X\L
- Xchar *
- Xinl (start)
- Xchar *start;
- X\L
- Xchar *
- Xinull (start)
- Xchar *start;
- X}
- X
- X\S{DESCRIPTION}
- XBSD's {\myit sprintf()} implementation results in
- X``one of those annoying gratuitous incompatibilities among UNIX
- Xvariants'' (quoting the eloquently restrained
- XUSENET {\myit wizard\/} Doug Gwyn).
- XUnder BSD, {\myit sprintf()} returns quite uselessly the
- Xsame buffer pointer that the caller passed in;
- Xline~51 of Berkeley's {\myit /usr/include/stdio.h\/} is not ashamed to
- Xdeclare:
- X\smallskip
- X\I{\mytt /* \ats(\#)stdio.h 1.2 86/10/07 SMI; from UCB 1.4 06/30/83 */}
- X\I{\mytt char *sprintf(); /* too painful to do right */}
- X\smallskip
- XSystem~V meanwhile, returns the number of
- Xcharacters written so the user's pointer at which printing began, can
- Xeasily be incremented by the returned {\myit int\/} to
- Xcontinue printing at the end of the previous string.
- XTo achieve the same end
- Xunder BSD, the pointer would have to be incremented by the
- Xoffset gotten with an extra call to {\myit strlen()\/}.
- X\L
- XILIB's {\bb icue()} function presents an alternative method of resetting
- Xthe pointer to the end of NUL terminated strings. {\bb icue()}
- Xbypasses the {\myit sprintf\/} system dependency, and
- Xalso works hand-in-hand with any
- Xstring function that leaves a NUL byte at the end of the
- Xcaller's buffer.
- X\L
- X{\bb icue()} is called following
- X{\myit sprintf()\/} or other string function calls, and
- Xautomatically advances the passed pointer {\myit ptr\/} in the
- Xbuffer to the next NUL byte.
- XIn order to alter the address that the pointer dereferences,
- Xthe pointer should be passed to
- X{\bb icue()} by its address.
- X\L
- X{\bb inl()} and {\bb inull()} are two other ILIB routines
- Xdedicated to search for the end of NUL terminated strings.
- XSimilarly to {\myit strlen()\/}, {\bb inl()} and {\bb inull()}
- Xboth report the length of a string, but by returning a pointer to the
- Xend of the string rather than by the count of bytes. The pointer is
- Xoften more convenient than the offset.
- X{\bb inl()} finds the first {\myit unescaped\/}
- Xnewline or the first NUL (ASCII zero) byte
- Xfrom {\myit start\/}, and returns a pointer to it.
- X{\bb inull()} finds the first NUL byte
- Xfrom {\myit start\/}, and returns a pointer to it.
- XNeither {\bb inl()} or {\bb inull()} ``know when to stop'' unless they
- Xfound the delimiters they were searching for. If the buffer does not
- Xcontain the delimiter, the search will continue into restricted
- Xspace and cause a {\myit core dump\/}. {\bb inull()} is marginally
- Xfaster than the standard {\myit strlen()\/}. {\bb inl} pays a speed
- Xpenalty for having to match
- Xeither delimiter against each byte of the string.
- X
- X\S{isdef EXAMPLE PROGRAM}
- XMost C compilers contain a number of unadvertised internal definitions.
- XInternal {\myit \#define\/}s implement system debugging parameters
- Xsuch as {\myit \_\_LINE\_\_, \_\_FILE\_\_,\/} as well as
- Xglobal system or machine identifiers
- Xsuch as {\myit unix, pyr\/} (under the Pyramid 90x mini, for
- Xexample).
- XOnce in a while, identifiers of a user program will result in a
- Xcollision with an internal
- X{\myit \#define\/}.
- XTo find out beforehand whether a word belongs in the set of
- Xinternally defined tokens, one could examine the string space
- Xof the programs comprising the object set of {\myit cc\/} (a few
- Xelements of this list are
- X{\myit /lib/cpp, /lib/ccom, /lib/c2, /lib/crt0.o, /lib/libc.a\/});
- Xbut often it is simpler just to write a few-line {\myit main()\/}
- Xprogram that includes the word in question --- if the program
- Xcompiles, the word is already defined.
- X\L
- XThe {\bb isdef} program automates this process: it writes a
- Xtemporary C~program for testing the defined status
- Xof the command line parameters; it
- Xthen proceeds with compiling, executing, and finally deleting
- Xthe test program. To ascertain whether a command line parameter is
- Xdefined by the C~compiler, the generated test code will contain
- X\smallskip
- X{\obeylines \mytt \parindent=40pt
- X\#ifdef\ \dx{token}
- X\ \ \ \ printf\ ("\dx{token}\ is\ defined\bsl n");
- X\#else
- X\ \ \ \ printf\ ("\dx{token}\ not\ defined\bsl n");
- X\#endif
- X\smallskip}
- Xfor each token supplied to {\bb isdef} as a command line parameter.
- XThe {\bb isdef} process pieces the test code together in an internal
- Xbuffer {\myit fbuf\/},
- Xand writes the entire buffer to a temporary file in one
- Xoperation. While filling the buffer, the
- Xbuffer pointer {\myit ptr\/} is moved to the
- Xend of the most recently installed sub-string via {\bb icue()}, and
- Xthe next sub-string is printed from this point on.
- X
- X\S{isdef.c PROGRAM TEXT}
- X\listing{../iex/isdef.c}
- X
- X\S{excise EXAMPLE PROGRAM}
- XWhile it is ``cleaner'' to implement algorithms for in-place
- Xfile transformations by bypassing \stin\ and \stout\ (reading and
- Xwriting file data through specific file descriptors instead), the
- X{\bb excise} example program illustrates a method using standard
- Xterminal I/O. The complaint against some
- X{\myit filter\/} programs in Unix is that a filter structure is
- Xoften inappropriate, and forces the user to redirect output to a
- Xtemporary file that must then be followed by manually moving the
- Xtemporary file to replace the source file. {\bb excise} eliminates
- Xthe need for this ``manual post-processing'' by doing it within
- Xthe program: it creates the temporary file of the output, and
- Xmoves the temporary file to replace the source file with a call to the
- X{\myit system()\/} command of the standard C library.
- X\L
- X{\bb excise} searches
- Xfor a user-specified string (a mandatory command line
- Xparameter), in the text of each file given on its command line,
- XHaving found the string nearest to the beginning of the
- Xfile, {\bb excise} removes the {\myit newline\/} terminated
- Xline that contained the string, then goes on to
- Xthe next file. The ``solo minus'' option on the command line
- Xforces {\bb excise} to search each file in its entirety, and to remove
- Xall those lines of the file that contained the specified string.
- X\L
- X{\bb excise} implements the mechanics of ``removing a line'' via
- Xthe \stio\ discipline. Each source file in the queue
- Xis recast as \stin\ in turn, and is read a line at a time.
- XEach line of input is immediately reprinted to \stout\ unless the
- Xline contains the string match and is therefore to be ``removed''.
- XRemoval
- Xconsists of suppressing the line from being output. Similarly to
- Xrenaming source files \stin, \stout\ is attached to a
- Xtemporary file in {\myit /tmp\/} collecting the altered text.
- XBecause \stout\ is buffered, the system is not obliged to copy
- Xfragments of output to the temporary file unless it is forced to do
- Xthis by a
- Xcall to {\myit fflush()\/}. After this, the temporary file is made
- Xto displace the source file with the {\myit mv\/} command; and then
- Xthe process repeats with the next source file in the queue.
- X\L
- XBecause of the line-by-line processing and because
- X{\myit strcmp()\/} is used for string matching, {\bb excise}
- Xwill not find the specified string in any text if the
- Xstring contained {\myit newline\/}
- Xor NUL (ASCII zero) characters, even though
- X{\myit ifonetic()\/} pre-processes the string and converts
- XILIB's phonetic control sequences to non-alphanumeric values.
- X
- X\S{excise.c PROGRAM TEXT}
- X\listing{../iex/excise.c}
- X\eject
- SHAR_EOF
- $TOUCH -am 0605083990 iman/icue.tex &&
- chmod 0644 iman/icue.tex ||
- echo "restore of iman/icue.tex failed"
- set `wc -c iman/icue.tex`;Wc_c=$1
- if test "$Wc_c" != "7399"; then
- echo original size 7399, current size $Wc_c
- fi
- # ============= iman/idate.tex ==============
- echo "x - extracting iman/idate.tex (Text)"
- sed 's/^X//' << 'SHAR_EOF' > iman/idate.tex &&
- X% XREF idate imonth itoday itohour itomin itomonth itosec itoyear
- X
- X\def\name{IDATE}
- X\def\IT{{\bb idate()}}
- X
- X\S{NAME}
- X{\bb idate} --- print today's date in one of four formats
- X
- X{\bb imonth} --- convert month name to number 1 through 12
- X
- X{\bb itoday} --- integer value (1 $\ldots$\ 31) of current day of month
- X
- X{\bb itohour} --- integer value (0 $\ldots$\ 23) of current hour of day
- X
- X{\bb itomin} --- integer value (0 $\ldots$\ 59) of current minute
- X
- X{\bb itomonth} --- integer value (1 $\ldots$\ 12) of current month
- X
- X{\bb itosec} --- integer value (0 $\ldots$\ 59) of current second
- X
- X{\bb itoyear} --- four decimal-digit value of current year
- X
- X\S{SYNOPSIS}
- X\settabs\+{\bb mdefine SHORTUPMO} & mmm &\cr
- X\+{\bb\#define SHORTMO}&\hfill{\bb0}&\kern2em{\mytt
- X/* to get: Dec 23 1990 */}\cr
- X\+{\bb\#define SHORTUPMO}&\hfill{\bb1}&\kern2em{\mytt
- X/* to get: DEC 23 1990 */}\cr
- X\+{\bb\#define LONGMO}&\hfill{\bb2}&\kern2em{\mytt
- X/* to get: December 23, 1990 */}\cr
- X\+{\bb\#define LONGUPMO}&\hfill{\bb3}&\kern2em{\mytt
- X/* to get: DECEMBER 23, 1990 */}\cr
- X\L
- X{\obeylines \bb
- Xchar *
- Xidate (format)
- Xint format;
- X\L
- Xint
- Ximonth (ptr)
- Xchar *ptr;
- X\L
- Xint
- Xitoday (), itohour (), itomin (), itomonth (), itosec (), itoyear ();
- X}
- X
- X\S{DESCRIPTION}
- XThe \IT\ functions provide simple and convenient ``date stamping''
- Xin a variety of formats other than returned by the Unix
- X{\myit ctime()\/}
- Xand {\myit date()\/}. All \IT\ functions except {\bb imonth()}
- Xrely on an internal, ``hidden'' function {\myit \_igetdate()\/}
- Xfor consulting the system clock and storing the fields of a {\myit tm\/}
- Xstructure. The current time is saved at the first
- X{\myit \_igetdate()\/} call of the process; subsequent calls though
- Xlater in time, do not update the originally stored values.
- X\L
- X\IT\ returns a pointer to a null terminated ``today's date'' string in
- Xone of four {\myit format\/}s. The returned string does not contain
- Xa {\myit newline\/}. Error reporting is absent.
- X\L
- X{\bb imonth()} understands the string passed in via
- X{\myit ptr\/} to describe a month between January and December
- Xor between 1 and 12, and returns the {\myit int\/} value of
- Xthe month (1 through 12).
- XNames may contain arbitrary upper or lower case characters,
- Xbut must begin with the initial 3 characters of a month
- Xto be recognized.
- XIf the first character of {\myit ptr\/}
- Xis a digit, {\bb imonth()} uses {\myit atoi()\/} to extract the
- Xnumber. If the first character is alphabetic, two more characters
- Xare read, and a hash value computed from the upcased three characters
- Xis used to decode the number of the month. If the number from
- Xeither evaluation lies outside the 1--12 range, 0 is returned instead.
- XNegative {\myit sys\_nerr\/} is returned if
- X{\myit (char *)NULL\/} is passed as {\myit ptr\/},
- Xor if {\myit ptr\/} dereferences a zero length
- Xstring.
- X\L
- XThe time stamps
- X{\bb
- Xitoday(),
- Xitohour(),
- Xitomin(),
- Xitomonth(),
- Xitosec(),
- Xitoyear()}
- Xeach return the current {\myit int\/}
- Xvalue of the unit that follows {\myit ito\/} in the function name.
- XError reporting is absent.
- X
- X\S{SEE ALSO}
- X{\myit ihms\/},
- Xfor converting seconds to hours:minutes:seconds; and
- Xto access a continually updated time stamp for timing applications.
- X
- X\S{stamp EXAMPLE PROGRAM}
- XAlthough the date of creation of a Unix file is evident from the
- Xsystem time stamp displayed in a {\myit long listing\/} of the file,
- Xoccasionally it is desirable to include the date in
- Xthe file name itself. A {\myit crontab entry\/} may take regular
- Xsnapshots of some system resource for example; the inclusion of
- Xthe date in the snapshot file names eliminates the worry of having
- Xto generate
- Xfile name variants, and provides a more obvious mark of the
- Xtime of creation of a file. The {\bb stamp} program prints a
- Xfour-character digit string of the current month/day, easily included
- Xas a file name extension:
- X\smallskip
- X\I{\mytt df > diskspace.`stamp`}
- X\smallskip
- XIn this command line, {\myit back quotes\/} surround {\bb stamp};
- Xthe name of the newly written file will end in a four-digit
- Xextension generated by {\bb stamp}. On January 23 for example,
- Xthe new file would be named {\myit diskspace.0123\/}.
- X
- X\S{stamp.c PROGRAM TEXT}
- X\listing{../iex/stamp.c}
- X\eject
- SHAR_EOF
- $TOUCH -am 0607093190 iman/idate.tex &&
- chmod 0644 iman/idate.tex ||
- echo "restore of iman/idate.tex failed"
- set `wc -c iman/idate.tex`;Wc_c=$1
- if test "$Wc_c" != "4167"; then
- echo original size 4167, current size $Wc_c
- fi
- # ============= iman/idump.tex ==============
- echo "x - extracting iman/idump.tex (Text)"
- sed 's/^X//' << 'SHAR_EOF' > iman/idump.tex &&
- X% XREF idump
- X
- X\def\name{IDUMP}
- X\def\IT{{\bb idump()}}
- X
- X\S{NAME}
- X{\bb idump} --- write a buffer to \stout,
- Xtranslating NUL bytes to a different ASCII value
- X
- X\S{SYNOPSIS}
- X{\obeylines \bb
- Xvoid
- Xidump (start, end, ch)
- Xchar *start;
- Xchar *end;
- Xchar ch;
- X}
- X
- X\S{DESCRIPTION}
- XMaking repeated calls to {\myit write()\/}, \IT\
- Xprints the contents of an internal buffer
- Xbegininning at {\myit start\/} and ending one byte before
- X{\myit end\/}, to \stout. The most useful feature of \IT\
- Xis the transformation of ASCII NUL (zero) bytes
- Xto a different ASCII value in the output,
- Xmaking this hard-to-handle character
- Xeasily visible and identifiable.
- XThe internal buffer meanwhile remains intact, and
- Xprocess development can continue undisturbed by the dump.
- X\L
- XThe target character value (to substitute for NUL bytes in the output)
- Xis passed via the {\myit char~ch\/}.
- XThis character itself may be NUL
- X(passed as two successive single quotes or as '\bsl0'), producing
- Xan exact copy of the buffer on \stout.
- X\IT\ is intended mainly as a {\myit write()\/} substitute
- Xduring program development,
- X
- X\S{nulcat EXAMPLE PROGRAM}
- XThe {\bb nulcat} program described here,
- Xuses \IT\ to print a file to \stout\ with NUL bytes of the
- Xfile translated to \key{\ats} characters. Alternately,
- X{\bb nulcat} can be a filter, using \stin\ for input.
- X\L
- XThe {\bb nulcat}
- Xprocess terminates immediately after \IT, and so fails to take
- Xadvantage of the unchanged file image still in the internal
- Xbuffer. The program aims to supplement the
- Xotherwise excellent non-printing character display capabilities of
- Xthe {\myit vi\/} editor. {\myit vi\/} appears to have a
- X``blind spot'' when faced with NUL bytes; other solutions for displaying
- XNUL characters ({\myit od~-c\/}, etc.) are visually complex and
- Xhard to interpret.
- X\L
- XCommand line syntax is typical of filters. The
- Xfollowing commands give identical results:
- X\smallskip
- X\I{\mytt cat sourcefile \pip \ nulcat}
- X\I{\mytt nulcat sourcefile}
- X
- X\S{nulcat.c PROGRAM TEXT}
- X\listing{../iex/nulcat.c}
- X\eject
- SHAR_EOF
- $TOUCH -am 0607094290 iman/idump.tex &&
- chmod 0644 iman/idump.tex ||
- echo "restore of iman/idump.tex failed"
- set `wc -c iman/idump.tex`;Wc_c=$1
- if test "$Wc_c" != "2013"; then
- echo original size 2013, current size $Wc_c
- fi
- # ============= iman/iego.tex ==============
- echo "x - extracting iman/iego.tex (Text)"
- sed 's/^X//' << 'SHAR_EOF' > iman/iego.tex &&
- X% XREF iego
- X
- X\def\name{IEGO}
- X\def\IT{{\bb iego()}}
- X
- X\S{NAME}
- X{\bb iego} --- put path-less, extension-less base name into word buffer
- X
- X\S{SYNOPSIS}
- X{\obeylines \bb
- Xint
- Xiego (ptr, wbuf, delim, ext)
- Xchar *ptr;
- Xchar *wbuf;
- Xchar delim;
- Xchar ext;
- X}
- X
- X\S{DESCRIPTION}
- X\IT\ examines the null terminated
- X{\myit path/filename\/} pointed to by {\myit ptr\/},
- Xand removes from it
- Xeither the {\myit basename.extension\/} substring
- X(leaving only the {\myit path\/} component
- Xin the buffer passed in via {\myit wbuf\/}),
- Xor removes the {\myit path\/} and {\myit extension\/} substrings
- X(leaving only the {\myit basename\/} component
- Xin {\myit wbuf\/}). The original string at {\myit ptr\/} is not
- Xdisturbed.
- X\L
- XThe {\myit path\/} substring is computed as all leading bytes to
- Xand including the last {\myit delim\/} character of the name;
- X{\myit delim\/} is typically --- but not necessarily --- the
- Xslash \key{/} character.
- XThe {\myit extension\/} substring is computed as all trailing bytes
- Xincluding the first occurrence of the {\myit ext\/} character,
- Xfollowing the base name. The {\myit ext\/} parameter
- Xis typically the dot \key{.} character.
- XThe {\myit ext\/} parameter also serves to convey the choice
- Xbetween generating either the {\myit path\/} or the
- X{\myit basename.extension\/} targets:
- XIf {\myit ext\/} is NUL (passed as {\myit (int)0\/},
- Xadjacent single quotes \dx{\mytt''}\
- Xor {\mytt'\bsl0'}),
- Xthe null terminated {\myit path\/} is left in {\myit wbuf\/}.
- XOtherwise, the null terminated {\myit basename\/} is
- Xleft in {\myit wbuf\/}.
- X\L
- X\IT\ returns the byte length of the target string in {\myit wbuf\/}.
- XNegative {\myit sys\_nerr\/} is returned if
- Xaddress~0 is passed as {\myit ptr\/},
- Xor if {\myit ptr\/} dereferences a zero length string.
- X
- X\S{ego EXAMPLE PROGRAM}
- XThe {\bb ego} program provides an
- Xalternative to the Unix {\myit basename\/}
- Xcommand, with
- Xa shorter name and an easier syntax. Three other names {\bb path},
- X{\bb ext}
- Xand {\bb egoext} are {\myit links\/} of {\bb ego}, meaning that
- Xthe four command names are equivalent and refer to the same object.
- XExecution of the object begins with an internal examination of the
- Xname by which the command was invoked;
- Xthe intention of the user is inferred from the selection of the command
- Xname.
- X\smallskip
- X\I{\mytt ego file ...}
- X\smallskip
- Xprints the {\myit basename\/} of the command line
- Xarguments. Each name is terminated with a {\myit newline\/}.
- X\smallskip
- X\I{\mytt ext file ...}
- X\smallskip
- Xprints the {\myit extension\/} part of the file names
- Xgiven as command line
- Xarguments, without the period character that separates an extension
- Xfrom the base name. The extension itself may contain embedded or
- Xtrailing periods. Each name is terminated with a {\myit newline\/}.
- XSimilarly,
- X\smallskip
- X\I{\mytt path file ...}
- X\smallskip
- Xreprints the {\myit path\/}s of
- Xcommand line arguments, retaining the trailing slash \key{/}.
- X\smallskip
- X\I{\mytt egoext file ...}
- X\smallskip
- Xprints the {\myit basename.extension\/} substring of each file name
- Xsupplied on the command line.
- X
- X\S{ego.c PROGRAM TEXT}
- X\listing{../iex/ego.c}
- X\eject
- SHAR_EOF
- $TOUCH -am 0531085290 iman/iego.tex &&
- chmod 0644 iman/iego.tex ||
- echo "restore of iman/iego.tex failed"
- set `wc -c iman/iego.tex`;Wc_c=$1
- if test "$Wc_c" != "3085"; then
- echo original size 3085, current size $Wc_c
- fi
- # ============= iman/ierror.tex ==============
- echo "x - extracting iman/ierror.tex (Text)"
- sed 's/^X//' << 'SHAR_EOF' > iman/ierror.tex &&
- X% XREF ierror idamage ierflag ierbuf
- X
- X\def\name{IERROR}
- X\def\IT{{\bb ierror()}}
- X
- X\S{NAME}
- X{\bb ierror} --- report an ILIB error or a system error
- X
- X{\bb idamage} --- return TRUE on possible file damage
- X
- X\S{SYNOPSIS}
- X{\obeylines \bb
- X\#define IHALFK 512
- X\L
- Xchar ierbuf[IHALFK];
- Xint ierflag;
- X\L
- Xint
- Xierror (ustr)
- Xchar *ustr;
- X\L
- Xint
- Xidamage (error)
- Xint error;
- X}
- X
- X\S{DESCRIPTION}
- XThe \IT\ function is similar to the standard
- X{\myit perror()\/}.
- XILIB functions report internal failures exclusively through \IT.
- XIn addition to errors during
- Xsystem calls encountered within ILIB function blocks,
- XILIB functions also use \IT\ to flag improper
- Xparameters passed to ILIB functions that prevent normal
- Xfunction execution.
- X\L
- XImproper parameters are typically zero-length strings, or
- X{\myit start\/} pointers set to NULL instead of to some accessible
- Xbuffer. Exhaustive testing of parameters would impose prohibitive
- Xruntime performance penalties;
- XILIB functions with {\myit start, end\/}
- Xbuffer parameters are usually content to read the buffer from
- X{\myit start\/} if {\myit (char *)NULL\/} is passed as
- X{\myit end\/}, and assume that in these cases the caller was good
- Xenough to pass
- Xa null (byte) terminated string beginning at {\myit start\/}.
- X\L
- XIf an ILIB function makes a call to \IT\ not because of
- Xsystem call failure
- Xbut because the user's call to the
- Xthe ILIB function
- Xcontained a parameter error,
- X{\myit errno\/} will be zero. In this case,
- X\IT\ copies {\myit ustr\/} (or ``{\mytt Error\/}'' if
- X{\myit ustr\/} is NULL)
- Xinto {\bb ierbuf\/},
- Xsets {\bb ierflag\/} to the negative value of the system constant
- X{\myit sys\_nerr\/} (the number of error messages in
- X{\myit sys\_errlist\/}), and returns this value.
- X\L
- XAll system calls executed by ILIB functions are tested
- Xfor failing returns within the individual function blocks.
- XFailing system calls
- Xcause the caller ILIB function to issue a call to \IT\
- Xand then to return without further processing.
- XWhen called, \IT\ first examines the global
- X{\myit errno\/}.
- XIf {\myit errno\/} is set, an error has occurred during a previous
- Xsystem call. In this case,
- X\IT\ copies the {\myit sys\_errlist\/}
- Xmessage indexed by {\myit errno\/}, into {\bb ierbuf\/}; appends
- Xthe string ``{\mytt~---~}'' and then {\myit ustr\/}.
- XIf {\myit ustr\/} is NULL, only
- X{\myit sys\_errlist[errno]\/} is copied.
- XNewline or white space is not added after {\myit ustr\/}. The
- Xfinal {\bb ierbuf\/} message is null terminated.
- XThe ILIB error flag
- X{\bb ierflag\/} is assigned
- Xthe negative value of {\myit errno\/} before
- X\IT\ resets {\myit errno\/} to zero.
- XThe {\bb ierflag\/} value is returned from the call.
- X\L
- XPrograms linking with ILIB may utilize \IT\ as completely distinct
- Xfrom ILIB usage, for their own internal error reporting.
- XThe principal benefit from this is
- Xan orthogonal interpretation of errors across
- Xsystem calls and user functions.
- XThe \IT\ code defines
- Xthe global {\bb char ierbuf[IHALFK]\/} and
- X{\bb int ierflag\/} variables. The {\myit ilib.h\/} file
- X{\myit \#include\/}d in the user code, declares these
- Xas {\myit extern\/}.
- X\L
- XThe string sent to
- X\IT\ from the calling ILIB function in {\myit ustr\/}
- Xis a brief message noting the name of the function that recognized
- Xthe error and the specific test that failed. No restrictions are
- Xset for functions that call \IT\ externally to ILIB, except that
- Xexcessively long
- Xsystem-message/user-strings are truncated beginning at their 512th
- Xcharacter in order that \IT\ can null terminate {\bb ierbuf\/}.
- XBecause {\myit errno\/} is not automatically cleared by the system
- Xbetween system calls, any user code that makes system calls on its
- Xown (not via ILIB) and then keeps the process alive in spite of
- Xa failing system call, should reset
- X{\myit errno\/} on its own before subsequent calls to ILIB. This
- Xwill prevent misleading error reports.
- X\L
- XThe {\bb idamage()\/} function makes an informed guess as to
- Xwhether an error value returned by ILIB functions could have
- Xbeen accompanied by file damage. A number of failing system calls
- Xare benign, preventing further processing but not destroying
- Xalready computed results. For example a {\myit malloc\/} error
- Xsimply means that no more memory is available; existing buffer
- Xcontents remain unchanged. An ``out of disk space'' error on the
- Xother hand, during a {\myit write\/} could occur after a partial
- Xflush of the processed buffers,
- Xleaving a destroyed file image on disk. Programs that write to
- Xa series of files, may be able to ignore benign errors by
- Xsimply bypassing the file under whose processing the error
- Xoccurred, but would
- Xterminate the process when noticing apparent file damage.
- X\L
- XInterpreting the passed number as the negative version of a
- Xsystem error constant defined in {\myit errno.h\/},
- X{\bb idamage()\/} returns TRUE if the failing system call
- Xhad the potential of damaging a file; and returns FALSE
- Xotherwise. A {\myit -sys\_nerr\/}
- Xvalue passed is assumed to be the error return from an ILIB
- Xfunction failing not because of a system call error, and is
- Xevaluated as having no potential for file damage.
- XMore negative values, and all non-negative values are considered
- Xnot in the domain of error numbers, causing FALSE returns.
- X
- X\S{mung EXAMPLE PROGRAM}
- XThe interactive Unix interface is noted for buffering user input
- Xline-by-line. Most standard tools (such as {\myit sed, grep\/})
- Xthwart casual attempts at
- Xstring transformations with embedded
- Xline-separating {\myit newline\/} characters. The main advantage of
- Xoperating on a line
- Xof input at a time is that the entire input
- Xcan be of unlimited length; programs aiming to transform
- Xa single string can
- Xallocate just enough work space to contain the
- Xmaximum expected line length.
- X\L
- XBecause of the {\myit stream\/}
- Xnature of I/O, standard transformation tools never directly
- Xchange the input data. Instead, the output is generally collected
- Xin a new file. If the original data is to be discarded, the user
- Xwill take the extra step of moving the target file over the
- Xsource file; in effect unlinking the source file and renaming the
- Xtarget file with the name of the source file. This need for manually
- Xreorganizing the directory tends to inhibit multiple file names
- X(each requiring the same transformation) supplied as command parameters.
- X\L
- XThe {\bb mung\/} program finds all occurrences of the
- Xstring given as the first
- Xcommand line parameter, and transforms each occurrence
- Xinto the string given as the second
- Xcommand line parameter, in each file listed on the rest of
- Xthe command line. Breaking with tradition, the files themselves
- Xare transformed by the changes; each original file will be replaced
- Xby its changed version without further user intervention. Both
- Xthe source string and the target string may span lines; {\bb mung\/}
- Xuses the easy and obvious {\myit ifonetic()\/} syntax to recognize
- Xnon-printing characters specified
- Xin the exchange strings.
- X\L
- XTrue to its name (derived from {\myit mungo\/} --- the waste of
- Xmilled wool used for making cheap cloth),
- X{\bb mung\/} operates in an inelegant,
- Xbrute force fashion; ignoring traditional I/O blocking.
- XNevertheless, its easy syntax and
- Xthe convenience of arbitrary characters in the exchange strings
- Xmake {\bb mung} a useful tool.
- X\L
- XThe following command example
- Xtransforms each carriage-return/linefeed
- Xline termination (endemic in files created under DOS)
- Xof file1, file2 and file3, to the Unix
- X``newline only'' line termination:
- X\smallskip
- X\I{\mytt mung \ XretXnew \ Xnew \ file1 \ file2 \ file3}
- X\smallskip
- XAnother example restores words broken up across consecutive lines by
- Xhyphenation,
- Xto whole words (at the expense of doubling the length of an
- Xoccasional line), by deleting hyphen/newline pairs from
- Xall files in the directory with names ending in ``text'':
- X\smallskip
- X\I{\mytt mung \ -Xnew \ '' \ *text}
- X\smallskip
- XThe two adjacent single quotes in this example indicate a zero-length
- Xtarget string: occurrences of the source string are eliminated.
- XZero-length strings are different from strings containing ASCII 0
- X(NUL) bytes:
- X\smallskip
- X\I{\mytt mung \ Xnul \ '' \ *text}
- X\smallskip
- Xdeletes each NUL byte from *text.
- X\L
- XAfter updating the file, the count of
- Xupdated string instances is reported to \stout, in the form
- X\smallskip
- X\I{\mytt file2 - 75}
- X\smallskip
- Xshowing that 75 instances of the source string were changed to
- Xthe target string in file2.
- XEach examined file is rewritten (touched) only if the source string
- Xdid occur in the file; zero occurrences of the source string are
- Xnot reported.
- X\L
- XSpecifying zero-length strings for both exchange strings, results
- Xin an error message printed to \sterr. Supplying no file name
- Xon the command line triggers a ``usage'' message printed to
- X\sterr, summarizing command line syntax. Specifying a zero-length
- Xsource string and a non-zero-length target string is interpreted
- Xas a ``count~only'' option, instructing {\bb mung\/} to report
- Xthe number of occurrences of the second string in each of the
- Xfiles, without altering the files in any way.
- XUnder this option, the count of
- Xtarget string instances is reported to \stout, in the form
- X\smallskip
- X\I{\mytt file2: 75}
- X\smallskip
- Xshowing that 75 instances of the target string were encountered in
- Xfile2, but file2 was not altered.
- X\L
- XThe main concern of designs effecting in-place file transformation
- Xis the potential for damaging the file during interrupts or
- Xoperating system failures. While
- Xinterrupting a transform process acting on a stream
- Xcannot damage the source text and may
- Xat most be an inconvenience for having to restart the process,
- Xa program interrupted in the midst of altering source text itself,
- Xwill not be able to
- Xcomplete the changes, nor could it restore the source to its original
- Xcondition.
- XBecause of this, the {\bb mung} process reads source text
- Xinto a dynamically allocated buffer, and applies transformations
- Xto the buffer image only. Afterwards,
- Xthe source text is overwritten with the altered buffer text in a single
- X{\myit write()\/} function call, using the maximally {\myit atomic\/}
- Xoperation allowed for a user process by
- Xthe multiprocessing kernel. Interrupts are guaranteed
- Xto kill the process either before {\myit write()\/} or after
- X{\myit write()\/} but never during {\myit write()\/}, so
- Xthe file image conforms to the source text only, or to the target
- Xtext only.
- XBecause the system employs delayed
- X{\myit write\/} operations, the buffer image will linger in
- Xdynamic memory, and the disk image of the file may still get
- Xcorrupted if the system crashes with the dynamic memory only
- Xpartially flushed. However, unflushed crashes occur rarely.
- X\L
- XReading an entire file into an internal buffer has the obvious
- Xadvantage of making any line boundary meaningless. The disadvantage
- Xis that the file size that the program can handle is limited to
- Xthe available dynamic memory. To maximize available space, the
- X{\bb mung\/} program is frugal in assigning memory to anything
- Xelse. The {\myit ifonetic()\/} call reuses {\myit argv[1]\/} and
- X{\myit argv[2]\/} space in converting phonetic
- Xcontrol sequences to true {\myit char\/}s;
- Xand {\bb mung} uses just the one buffer allocated for the source text,
- Xfor transforming and containing the target image as well.
- XDuring the conversion, the target image
- Xwill expand if the the target string is longer than the
- Xsource string, but the program doesn't know the extent of the
- Xexpansion unless it counts the occurrences of the source string
- Xin the source text first.
- XTherefore, if the target string is longer than the source string,
- Xan extra parsing of the source text is necessary.
- X\L
- XTo be able to utilize the same transformation alogrithm regardless of
- Xthe length of the exchange strings, the ``find-and-replace''
- Xblock of the code proceeds from the end of the text toward the
- Xbeginning. When a match to the
- Xsource string is found, the source text pointer is
- Xdecremented by the length of the source string, preventing
- Xoverlapping pattern matching. Given the source text ``rococo''
- Xfor example, the source string ``oco'' will be seen to occur only
- Xonce, and if replaced with ``k'' would yield the target text
- X``rock''.
- X\L
- XA generally overlooked
- Xbenefit of in-place file transformation is that the output
- Xleaves \stout\ available for status reporting, which is normally
- Xdifferent from error reporting. {\bb mung} is able to flag
- Xunreadable files or attempted directory writes as true errors, to
- X\sterr; while summarizing the conversion count on a ``per file''
- Xbasis, to \stout. It is easy to capture the summary in a pipe
- Xto generate a ``total'', for example:
- X\smallskip
- X{\obeylines \mytt
- X\ \ \ \ mung\ ''\ '\bsl listing\lcu '\ *.tex\ |\ fcat\ 2\ |\ add
- X\smallskip}
- XIn this command {\bb mung} counts the ``per-file''
- Xoccurrences of the \dx{\mytt\bsl listing\lcu}\ token
- Xin all files with the {\myit .tex\/} extension.
- X(The \dx{\mytt\bsl listing\lcu}\ token is
- Xdefined as a \TeX\ macro for printing this manual; and in the present
- Xcontext it illustrates that the use of the phonetic control sequences
- Xin specifying the {\bb mung} exchange strings is not mandatory.)
- XThe second fields of the report (the actual count produced by
- X{\bb mung})
- Xis stripped out from the
- Xoutput by {\myit fcat\/}, and is summed by {\myit add\/}.
- X\L
- XThe overall structure of the {\bb mung\/} program is simple.
- XAfter checking and translating the command line,
- Xa transform is attempted on each file of the
- Xcommand line in turn: the file name is
- Xpassed to the {\bb mung()\/} subroutine, and {\myit main()\/}
- Xexpectantly awaits the return value. If the return is zero, the
- Xfile did not contain the source string, the file has not been
- Xaltered, and no reporting is done. If the return is positive, the
- Xreturn
- Xvalue is the number of converted strings in the file, also
- Xreported to \stout.
- X\L
- XNegative returns signal that some error occurred, and {\myit main()\/}
- Xmust now decide whether the error means potential file damage
- X(in which case to notify the user and exit), or less serious trouble
- X(print a warning and proceed with the next file). The {\bb mung()\/}
- Xsubroutine itself relies on ILIB functions and passes
- X{\bb ierflag\/} to {\myit main()\/}; but in one case it calls
- X{\myit realloc()\/} directly, referring the task of building the
- Xerror message after a {\myit realloc()\/} error, to \IT.
- X
- X\S{mung.c PROGRAM TEXT}
- X\listing{../iex/mung.c}
- X\eject
- SHAR_EOF
- $TOUCH -am 0607095490 iman/ierror.tex &&
- chmod 0644 iman/ierror.tex ||
- echo "restore of iman/ierror.tex failed"
- set `wc -c iman/ierror.tex`;Wc_c=$1
- if test "$Wc_c" != "14309"; then
- echo original size 14309, current size $Wc_c
- fi
- # ============= iman/iexamplist.tex ==============
- echo "x - extracting iman/iexamplist.tex (Text)"
- sed 's/^X//' << 'SHAR_EOF' > iman/iexamplist.tex &&
- X\def\name{TABLE 3}
- X
- X\S{Summary of Program Examples}
- X{
- X\settabs\+{mmmmmmmmm} &
- X manage stacks of /tmp files for stdout segments, report filenames &\cr
- X
- X\+{\bb add}&
- Xadd leading number of each line of input, print total
- X&\hfill IROUND\cr
- X
- X\+{\bb area}&
- Xarea code data base lookup
- X&\hfill ISEARCH\cr
- X
- X\+{\bb banner}&
- Xoutput command line strings in large letters
- X&\hfill IFROMBIT\cr
- X
- X\+{\bb behead}&
- Xin place, delete leading lines of files
- X&\hfill IEXPECT\cr
- X
- X\+{\bb char}&
- Xoutput space separated character lists
- X&\hfill IFONETIC\cr
- X
- X\+{\bb cnum}&
- Xcustom line numbering via command line options
- X&\hfill IOPT\cr
- X
- X\+{\bb cweed}&
- Xlist minimally spaced tokens of C text, garbage removed
- X&\hfill ISTRIPCOM\cr
- X
- X\+{\bb defilter}&
- Xreplace input file text of filter commands with their output
- X&\hfill IFONETIC\cr
- X
- X\+{\bb distrib}&
- Xcount strings in lines
- X&\hfill ICOUNT\cr
- X
- X\+{down}&
- Xtolower entire files, in place
- X&\hfill ILOWER\cr
- X
- X\+{\bb ego}&
- Xextract basename of file names
- X&\hfill IEGO\cr
- X
- X\+{egoext}&
- Xextract name.extension of file names
- X&\hfill IEGO\cr
- X
- X\+{ext}&
- Xextract extension substring of file names
- X&\hfill IEGO\cr
- X
- X\+{\bb excise}&
- Xdelete line(s) of files that contain a specified string
- X&\hfill ICUE\cr
- X
- X\+{\bb fcat}&
- Xprint fields from lines of input, concatenated by spaces
- X&\hfill ITOK\cr
- X
- X\+{fpath}&
- Xlist all files visible from \dol PATH or from given paths
- X&\hfill ITOK\cr
- X
- X\+{\bb group}&
- Xwrite alphanumerically sorted lines to \stout, in groups
- X&\hfill IFAMILY\cr
- X
- X\+{\bb inum}&
- Xinteractively specify custom line numbering sequence
- X&\hfill IINPUT\cr
- X
- X\+{\bb isdef}&
- Xfind token in list of definitions recognized by C compiler
- X&\hfill ICUE\cr
- X
- X\+{\bb lcat}&
- Xcat line {\myit N\/} or lines {\myit N\/} through {\myit N+M\/} of input to \stout
- X&\hfill ILIST\cr
- X
- X\+{leftrunc}&
- Xskipping left {\myit N\/} columns, output remaining columns of input
- X&\hfill IHASH\cr
- X
- X\+{\bb lhash}&
- Xoutput formatted sum of bytes of each line of input
- X&\hfill IHASH\cr
- X
- X\+{\bb mung}&
- Xtransform every {\myit string1\/} within files into {\myit string2\/}
- X&\hfill IERROR\cr
- X
- X\+{\bb ncat}&
- Xline number, append spooler string before each file
- X&\hfill ILINE\cr
- X
- X\+{\bb nest}&
- Xprint line-numbered list of delimiter pair contained in file
- X&\hfill INEST\cr
- X
- X\+{nestinfo}&
- Xprint nesting information for delimiter pair contained in file
- X&\hfill INEST\cr
- X
- X\+{now}&
- Xcurrent time anywhere around the world
- X&\hfill ISEARCH\cr
- X
- X\+{\bb nulcat}&
- Xwrite input to \stout, changing NUL bytes to `@'
- X&\hfill IDUMP\cr
- X
- X\+{\bb objed}&
- Xbinary file editor
- X&\hfill IWRITE\cr
- X
- X\+{path}&
- Xextract path (directory) component of file names
- X&\hfill IEGO\cr
- X
- X\+{\bb pathfiles}&
- Xprint instructions on using {\myit fpath, rpath, wpath, xpath\/}
- X&\hfill ITOK\cr
- X
- X\+{\bb q}&
- Xstack {\mytt /tmp} files for \stout\ segments, report filename
- X&\hfill INTRO\cr
- X
- X\+{\bb rename}&
- Xchange string {\myit pattern1\/} in filenames to {\myit pattern2\/}
- X&\hfill IMATCH\cr
- X
- X\+{\bb rewrap}&
- Xin place, re-list tokens of file
- X&\hfill IALNTOK\cr
- X
- X\+{\bb rot}&
- Xprint instructions on using {\myit rotl, rotol, rotor, rotr\/}
- X&\hfill IROTATE\cr
- X
- X\+{rotl}&
- Xrotate input text 90 degrees to the left (counterclockwise)
- X&\hfill IROTATE\cr
- X
- X\+{rotol}&
- Xrotate text 90 degrees to the left, and over (upside down)
- X&\hfill IROTATE\cr
- X
- X\+{rotor}&
- Xrotate text 90 degrees to the right, and over
- X&\hfill IROTATE\cr
- X
- X\+{rotr}&
- Xrotate input text 90 degrees to the right
- X&\hfill IROTATE\cr
- X
- X\+{rpath}&
- Xlist all readable files of \dol PATH or of given paths
- X&\hfill ITOK\cr
- X
- X\+{\bb scat}&
- Xreprint input from line containing {\myit string1\/}, stop at line of {\myit string2\/}
- X&\hfill ILIST\cr
- X
- X\+{\bb stamp}&
- Xprint four-digit stamp of current month/day
- X&\hfill IDATE\cr
- X
- X\+{\bb trunc}&
- Xreprint lines of input only until given column number N
- X&\hfill IHASH\cr
- X
- X\+{uhash}&
- Xoutput formatted sum of upcased bytes of each line of input
- X&\hfill IHASH\cr
- X
- X\+{\bb unlink}&
- Xbrute force file remove
- X&\hfill IMODE\cr
- X
- X\+{\bb untab}&
- Xfor each tab, substitute spaces until next {\myit tabstop\/}
- X&\hfill IREAD\cr
- X
- X\+{\bb up}&
- Xtoupper entire files, in place
- X&\hfill ILOWER\cr
- X
- X\+{\bb which}&
- Xlocate a file
- X&\hfill IWHICH\cr
- X
- X\+{wpath}&
- Xlist all writable files of \dol PATH or of given paths
- X&\hfill ITOK\cr
- X
- X\+{\bb xec}&
- Xexec a command
- X&\hfill IFONETIC\cr
- X
- X\+{xpath}&
- Xlist all executable files of \dol PATH or of given paths
- X&\hfill ITOK\cr
- X}
- X\eject
- SHAR_EOF
- $TOUCH -am 0601145590 iman/iexamplist.tex &&
- chmod 0644 iman/iexamplist.tex ||
- echo "restore of iman/iexamplist.tex failed"
- set `wc -c iman/iexamplist.tex`;Wc_c=$1
- if test "$Wc_c" != "4338"; then
- echo original size 4338, current size $Wc_c
- fi
- # ============= iman/iexpect.tex ==============
- echo "x - extracting iman/iexpect.tex (Text)"
- sed 's/^X//' << 'SHAR_EOF' > iman/iexpect.tex &&
- X% XREF iexpect inextl istartl
- X
- X\def\name{IEXPECT}
- X\def\IT{{\bb iexpect()}}
- X
- X\S{NAME}
- X\hangindent=.75in \hangafter=1
- X{\bb iexpect} --- confirm or deny that the first token in the nearest
- Xline that does not begin with {\myit skiptok\/}, is a match for the
- Xexpected {\myit word\/}
- X\smallskip
- X{\bb inextl} --- return location of first token in the line after the
- Xcurrent line
- X
- X{\bb istartl} --- find nearest line that starts with a given
- X{\myit word\/}
- X
- X\S{SYNOPSIS}
- X\settabs\+{\bb mdefine SHORTUPMO} &\cr
- X\+{\bb\#define IANYTOK}&\hfill{\bb0}\cr
- X\+{\bb\#define IALNTOK}&\hfill{\bb1}\cr
- X\+{\bb\#define ICTOK}&\hfill{\bb2}\cr
- X\L
- X{\obeylines \bb
- Xint
- Xiexpect (start, end, word, skiptok, toktype)
- Xchar *start;
- Xchar *end;
- Xchar *word;
- Xchar *skiptok;
- Xint toktype;
- X\L
- Xchar *
- Xinextl (start, end, skiptok)
- Xchar *start;
- Xchar *end;
- Xchar *skiptok;
- X\L
- Xchar *
- Xistartl (start, end, word)
- Xchar *start;
- Xchar *end;
- Xchar *word;
- X}
- X
- X\S{DESCRIPTION}
- XBoth \IT\ and {\bb istartl()} are
- Xused to match a chosen {\myit word\/} against the first token in
- Xsuccessive lines in an internal buffer.
- XDuring \IT, the search ends at the first token of the buffer
- Xwhether or not the token matches the expected
- X{\myit word\/}, except when the token matches {\myit skiptok\/}.
- XIn this case, the entire line that began with {\myit skiptok\/} is
- Xbypassed, and token-recognition continues from the next line.
- X\L
- XDuring {\bb istartl()}
- Xthe beginning of each successive line is examined for a
- Xmatch to {\myit word\/};
- Xif there are no tokens in the currently examined
- Xline or if the first token in the
- Xcurrent line does not match the specified {\myit word\/},
- Xthe line is skipped
- Xand the search resumes at the start of the next line.
- X\L
- X{\bb inextl()} simply advances a pointer
- Xpast the first {\myit newline\/},
- Xand then parks it at the next printing (non-white)
- Xcharacter. If this printing character leads a string that exactly
- Xmatches {\myit skiptok\/}, the pointer is again advanced past the line,
- Xand the process repeats in the next line, until a line is found that
- Xdoesn't begin with
- Xthe {\myit skiptok\/} substring.
- X\L
- XThe searched buffer begins at
- X{\myit start\/} and ends one byte before {\myit end\/}.
- XThe passed reference {\myit word\/}
- Xand {\myit skiptok\/}
- Xare both character strings each terminated by a NUL byte.
- XIf {\myit word\/} is {\myit (char~*)NULL\/}
- Xor if it is a zero-length string,
- X\IT\ does no processing and returns~0.
- X{\bb istartl()\/} on the other hand returns
- X{\myit (char~*)NULL\/} and reports the incident via {\myit ierror()\/}.
- XA {\myit (char~*)NULL\/} or a
- Xzero-length string for
- X{\myit skiptok\/} may be passed to \IT\ or to {\bb inextl()}
- Xin a normal manner.
- X\L
- XThe {\myit toktype\/} parameter passed to \IT\ specifies token-forming
- Xrules and character sets for tokens.
- XThe ILIB {\myit include file ''ilib.h''\/} defines high level
- Xconstants IANYTOK, IALNTOK, and ICTOK as possible values for
- X{\myit toktype\/}.
- XOther values default to IANYTOK.
- XDepending on the value chosen, \IT\ calls on one of the ILIB
- Xfunctions {\myit ianytok(), ialntok()\/}, or
- X{\myit ictok()\/} for constructing the token.
- X{\myit ianytok()\/} considers any successive
- Xprinting character a legitimate member
- Xof the token byte string.
- X{\myit ialntok()\/} creates multi-byte tokens from
- Xalphanumeric characters, or single-byte tokens from non-alphanumeric
- Xprinting characters.
- X{\myit ictok()\/} expands the alphanumeric character set used
- Xby
- X{\myit ialntok()\/} with the underscore \key{\und} and dollar
- X\key{\$} characters, and also recognizes C operators and
- Xcharacter constants as separate tokens.
- X\L
- XInteger values returned by \IT\ may be positive, negative, or zero.
- XA returned zero informs the caller that the buffer contained no
- Xtokens whatsoever (or that \IT\ has received an illegal {\myit word\/}
- Xparameter).
- XA positive return indicates that the first valid token was a match
- Xfor {\myit word\/}; the integer value is the
- Xoffset from {\myit start\/},
- Xof the {\myit newline\/} character at the end of the line
- Xin which the expected {\myit word\/} was found.
- XA negative return indicates that the first valid token did not match
- X{\myit word\/};
- Xthe absolute value of the return is the offset from {\myit start\/},
- Xof the {\myit newline\/} character at the end of the line
- Xin which the valid non-matching token was found.
- X\L
- X\IT\ is most useful for parsing past ``comment lines'' beginning
- Xwith a single-byte {\myit comment delimiter\/} and ending with
- X{\myit newline\/}, or for bypassing line-starting
- X``format specifications'' (for example the leading periods of
- X{\myit nroff\/}).
- XTo skip records with fixed {\myit header\/} keywords in various
- Xfixed format text data files, {\bb istartl()} is more convenient.
- X\L
- X{\bb istartl()} uses a simpler algorithm for matching tokens against
- Xthe specified {\myit word\/}. The byte count of {\myit word\/} is
- Xstored in a temporary variable {\myit length\/}.
- XThe parser is advanced to the first
- Xprinting character of the examined line; a comparison
- X(using the standard {\myit strncmp()\/} function)
- Xis performed at this point
- Xof {\myit word\/} against a {\myit length\/} number of successive
- Xbytes of the line.
- XThis implies that {\myit word\/} can be an arbitrary aggregate of
- Xnon-NUL ASCII bytes, potentially a cluster of words; but must begin
- Xwith a {\myit printing character\/}.
- XAlso, a line in the buffer will match {\myit word\/} even if
- X{\myit word\/} is a substring of a longer line-starting token:
- Xa line beginning with ``plaintiff'' will match the {\myit word\/}
- X``plain'', for example.
- X\L
- X{\bb istartl()} does not perform a final
- Xcomparison if the length of {\myit word\/} would mean
- Xcomparing past the end of the buffer.
- X{\bb istartl()} returns a pointer dereferencing the leading token of the
- Xfirst line that matched {\myit word\/}, or a pointer to NULL
- Xif no match was found.
- X\L
- XThe returned pointer from the {\bb inextl()} function
- Xsimply points to {\myit end\/} if a legal token
- X(leading a {\myit printing\/} string in
- Xthe next line) could not be found, but it will point
- Xto NULL if the line does not end with a {\myit newline\/}
- Xas {\myit end\/} is encountered.
- X
- X\S{SEE ALSO}
- X{\myit imatch, ialntok.}
- X
- X\S{behead PROGRAM EXAMPLE}
- XThe stark name of the {\bb behead} program aptly describes the
- Xradical and irreversable changes it inflicts on the file in its
- Xcommand line parameter list. {\bb behead} reads each file in turn,
- Xinto an internal buffer; advances a pointer past an integral number of
- Xbeginning text lines; then writes all text from the pointer until the
- Xend of the buffer, back to the file (on disk). The net effect is to
- Xdiscard of a number of leading text lines from each file.
- X\L
- XThe command name must be followed by a decimal
- X{\myit number\/} or a {\myit string\/},
- Xpreceding the list of files subjected to the operation. When a
- X{\myit number\/} is given, it is taken to be the number of lines
- Xthat should
- Xbe removed from the beginning of files. The assumed line delimiter
- Xis the {\myit newline\/} character. If the selected file has less
- Xlines than (or has an equal number of lines to)
- Xthe number of lines to be removed, the file is
- Xtruncated to zero length.
- X\L
- XIf the command name is followed by a
- X{\myit string\/} instead of a {\myit number\/},
- Xthis {\myit string\/}
- Xcorresponds to the {\myit word\/} parameter of a call to
- X{\bb istartl()} described above. The text of each file in turn,
- Xis searched to find
- Xthe first line that begins (following optional {\myit white spaces\/})
- Xwith an exact match to the specified {\myit string\/}. Lines of the
- Xexamined file that preceded the line in which the match was found,
- Xare removed. If lines of a file do not produce a match, the file
- Xis left intact, and the incident triggers a warning message
- Xprinted to \sterr.
- X\L
- XA minor drawback of the command line syntax is that a positive
- Xinteger cannot be taken as a request to delete lines ending at
- Xthe line that begins with the
- Xdigit string of the integer:
- X\smallskip
- X\I{\mytt behead 15 foo}
- X\smallskip
- Xremoves the first 15 lines of {\myit foo\/} instead of searching
- Xfor a line in {\myit foo\/} that begin with the bytes ``15''.
- XA similar drawback inherent in the {\bb istartl()} process is that
- Xa specified {\myit string\/} cannot begin with {\myit white space\/}.
- X
- X\S{behead.c PROGRAM TEXT}
- X\listing{../iex/behead.c}
- X\eject
- SHAR_EOF
- $TOUCH -am 0607103590 iman/iexpect.tex &&
- chmod 0644 iman/iexpect.tex ||
- echo "restore of iman/iexpect.tex failed"
- set `wc -c iman/iexpect.tex`;Wc_c=$1
- if test "$Wc_c" != "8261"; then
- echo original size 8261, current size $Wc_c
- fi
- echo "End of part 6, continue with part 7"
- exit 0
- --
- Istvan Mohos
- ...uunet!pyrdc!pyrnj!hhb!istvan
- RACAL-REDAC/HHB 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
- ======================================================================
-