home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1435 < prev    next >
Internet Message Format  |  1990-12-28  |  55KB

  1. From: istvan@hhb.UUCP (Istvan Mohos)
  2. Newsgroups: alt.sources
  3. Subject: Subject: ILIB Unix Toolkit in C
  4. Message-ID: <551@hhb.UUCP>
  5. Date: 8 Jun 90 20:55:13 GMT
  6.  
  7.  
  8. ---- Cut Here and unpack ----
  9. #!/bin/sh
  10. # This is part 05 of a multipart archive
  11. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  12.  then TOUCH=touch
  13.  else TOUCH=true
  14. fi
  15. # ============= iex/untab.c ==============
  16. echo "x - extracting iex/untab.c (Text)"
  17. sed 's/^X//' << 'SHAR_EOF' > iex/untab.c &&
  18. X#ifdef NEVER
  19. X/bin/cc -O -DIMANFMT -I../i $0 ../i/ilib.a -o $BIN/untab
  20. Xexit 0
  21. X#endif
  22. X
  23. X/* for each tab, substitute spaces until next tabstop,
  24. X   delete trailing blanks
  25. X*/
  26. X#include "ilib.h"
  27. X#define  SPACE 32
  28. X
  29. Xmain (argc, argv)
  30. Xint argc;
  31. Xchar *argv[];
  32. X{
  33. X
  34. X    char **file;
  35. X    int tstop;
  36. X    int tcount;
  37. X
  38. X    if (argc < 3 || (tstop = atoi (argv[1])) < 1)
  39. X        fprintf(stderr, "Usage: %s tabstopwidth files\n%s", argv[0],
  40. X        "Spacefill each tab to next tabstop, delete trailing blanks\n"),
  41. X        exit(1);
  42. X
  43. X    for (file = &argv[2]; !NULCHARP (*file); file++) {
  44. X        tcount = untab(tstop, *file);
  45. X        if (idamage (tcount))
  46. X            fprintf (stderr, "%s %s\n%s", ierbuf, *file,
  47. X            "file damage probable ... aborting\n\n"), exit (1);
  48. X        if (tcount < 0)
  49. X            fprintf (stderr, "%s %s\n", ierbuf, *file);
  50. X        else if (tcount)
  51. X            printf("%s - %d\n", *file, tcount);
  52. X    }
  53. X
  54. X    exit(0);
  55. X}
  56. X
  57. Xint
  58. Xuntab (tstop, file)
  59. Xint tstop;
  60. Xchar *file;
  61. X{
  62. X    FILE *fopen(), *fp;
  63. X    char *realloc();
  64. X    char linebuf[BUFSIZ];
  65. X    char *lineptr, *endline;
  66. X    char *buffer, *bufptr, *tmp;
  67. X    int insiz, newsiz;
  68. X    int tcount = 0;
  69. X    int togo, lpos, fill;
  70. X
  71. X    /* read file into buffer --- no file damage on error */
  72. XQ   if ((insiz = iread(file, &buffer)) < 0)
  73. X        return (ierflag);
  74. X
  75. X    /* count number of tabs */
  76. X    for (bufptr = buffer + insiz; --bufptr >= buffer;)
  77. X        if (*bufptr == '\t')
  78. X            ++tcount;
  79. X
  80. X    /* assuming maximum expansion of each tab, resize buffer */
  81. X    newsiz = insiz + tcount * (tstop - 1);
  82. X    if (newsiz != insiz) {
  83. X        tmp = buffer;
  84. X        if ((buffer = realloc (tmp, (unsigned)newsiz)) == NULL) {
  85. X            free (tmp);
  86. X            return (ierror ("while requesting expansion space"));
  87. X        }
  88. X    }
  89. X
  90. X    /* reread file line-by-line, paste changes into buffer */
  91. X    if ((fp = fopen (file, "r")) == NULL)
  92. X        return (ierror ("while rereading line-by-line"));
  93. X
  94. X    for (bufptr = buffer; !NULCHARP (fgets (linebuf, BUFSIZ, fp));) {
  95. X
  96. X        /* eliminate trailing white space in linebuf */
  97. X        endline = linebuf + strlen (linebuf) - 1;
  98. X        while (WHITE (*endline))
  99. X            --endline;
  100. X
  101. X        /* expand tabs: if tstop == 4, lpos can be 0,1,2,3; tabs become
  102. X           4,3,2,1 spaces respectively: tstop == lpos + togo
  103. X        */
  104. X        lpos = 0;
  105. X        for (lineptr = linebuf; lineptr <= endline; lineptr++) {
  106. X            if (*lineptr == '\t') {
  107. X                togo = tstop - lpos;
  108. X                for (DOUNCOUN (togo, fill); *bufptr++ = SPACE);
  109. X                lpos = 0;
  110. X            }
  111. X            else {
  112. X                *bufptr++ = *lineptr;
  113. X                if (++lpos == tstop)
  114. X                    lpos = 0;
  115. X            }
  116. X        }
  117. X        *bufptr++ = '\n';
  118. X    }
  119. X
  120. X    fclose (fp);
  121. X
  122. X    /* replace file with buffer contents --- error may destroy file */
  123. XQ   if (iwrite (file, buffer, bufptr) < bufptr-buffer) {
  124. X        free (buffer);
  125. X        return (ierflag);
  126. X    }
  127. X
  128. X    free(buffer);
  129. X    return (tcount);
  130. X}
  131. SHAR_EOF
  132. $TOUCH -am 0605075390 iex/untab.c &&
  133. chmod 0755 iex/untab.c ||
  134. echo "restore of iex/untab.c failed"
  135. set `wc -c iex/untab.c`;Wc_c=$1
  136. if test "$Wc_c" != "2579"; then
  137.     echo original size 2579, current size $Wc_c
  138. fi
  139. # ============= iex/up.c ==============
  140. echo "x - extracting iex/up.c (Text)"
  141. sed 's/^X//' << 'SHAR_EOF' > iex/up.c &&
  142. X#ifdef NEVER
  143. X/bin/cc -O -DIMANFMT -I../i $0 ../i/ilib.a -o $BIN/up
  144. X(/bin/rm -f $BIN/down)
  145. Xln $BIN/up $BIN/down
  146. Xexit 0
  147. X#endif
  148. X
  149. X/* toupper/tolower entire files, in place */
  150. X#include "ilib.h"
  151. X#define DOWN 312
  152. X
  153. Xmain (argc, argv)
  154. Xint argc;
  155. Xchar *argv[];
  156. X{
  157. X    char   *fbuf, *fend;
  158. X    char   **file = &argv[1];
  159. X    int    fsiz;
  160. X    int    down = (ihasharg (argv[0], '/') == DOWN);
  161. XQ   static int (*cmd[])() = {iupper, ilower};
  162. X
  163. X    if (argc < 2 )
  164. X        fprintf(stderr, "Usage: up|down files\n"), exit(0);
  165. X
  166. X    for (; !NULCHARP (*file); file++, free (fbuf)) {
  167. X        if ((fsiz = iread (*file, &fbuf)) < 0)
  168. X            fprintf (stderr, "%s\n", ierbuf), exit (1);
  169. X        fend = fbuf + fsiz;
  170. XQ       (*cmd[down])(fbuf, fend);
  171. X        if (iwrite (*file, fbuf, fend) != fsiz)
  172. X            fprintf (stderr, "%s\n", ierbuf), exit (1);
  173. X    }
  174. X    exit(0);
  175. X}
  176. SHAR_EOF
  177. $TOUCH -am 0605075390 iex/up.c &&
  178. chmod 0755 iex/up.c ||
  179. echo "restore of iex/up.c failed"
  180. set `wc -c iex/up.c`;Wc_c=$1
  181. if test "$Wc_c" != "780"; then
  182.     echo original size 780, current size $Wc_c
  183. fi
  184. # ============= iex/which.c ==============
  185. echo "x - extracting iex/which.c (Text)"
  186. sed 's/^X//' << 'SHAR_EOF' > iex/which.c &&
  187. X#ifdef NEVER
  188. X/bin/cc -O -DIMANFMT -I../i $0 ../i/ilib.a -o $BIN/which
  189. Xexit 0
  190. X#endif
  191. X
  192. X/* tell if a file is readable/writable/executable/present in $PATH */
  193. X#include "ilib.h"
  194. X
  195. Xmain (argc, argv)
  196. Xchar *argv[];
  197. Xint argc;
  198. X{
  199. X    char buf[IONEK];        /* interactive input buffer */
  200. X    char *tokret;
  201. X    char **opt = &argv[1];  /* command line options */
  202. X    int interactive = 0;
  203. X    int access = X_OK;      /* default permission */
  204. X    int optchar;
  205. X
  206. X    if (argc < 2)
  207. Xopterr:
  208. X        fprintf(stderr,
  209. X"\nUsage: %s [-m r|w|f]  -|file...\n%s%s%s%s%s%s\n", argv[0],
  210. X"\tFind full path of each 'file' if it is contained in $PATH and is:\n",
  211. X"\t-m r  readable by user executing the command\n",
  212. X"\t-m w  writeable by user executing the command\n",
  213. X"\t-m f  present (irregardless of its permissions)\n",
  214. X"\t      executable (no mode option specified on the command line)\n",
  215. X"\t-     acquire file names interactively\n"), exit(0);
  216. X
  217. X    while ((optchar = iopt (&opt)))
  218. X        switch (optchar) {
  219. X            case 'm':
  220. X                if (**opt == 'r')
  221. X                    access = R_OK;
  222. X                else if (**opt == 'w')
  223. X                    access = W_OK;
  224. X                else
  225. X                    access = F_OK;
  226. X                break;
  227. X            case '-':
  228. X                interactive = 1;
  229. X                break;
  230. X            default:
  231. X                goto opterr;
  232. X        }
  233. X
  234. X    if (interactive)
  235. X        while (gets (buf) != NULL)
  236. XQ           if ((tokret = iwhich (buf, access)) != NULL)
  237. X                puts (tokret);
  238. X            else
  239. X                strcat (buf, " not found"), puts (buf);
  240. X    else
  241. X        for (; !NULCHARP (*opt); opt++)
  242. XQ           if ((tokret = iwhich (*opt, access)) != NULL)
  243. X                puts (tokret);
  244. X            else
  245. X                printf ("%s not found\n", *opt);
  246. X    exit(0);
  247. X}
  248. SHAR_EOF
  249. $TOUCH -am 0605075390 iex/which.c &&
  250. chmod 0755 iex/which.c ||
  251. echo "restore of iex/which.c failed"
  252. set `wc -c iex/which.c`;Wc_c=$1
  253. if test "$Wc_c" != "1516"; then
  254.     echo original size 1516, current size $Wc_c
  255. fi
  256. # ============= iex/xec.c ==============
  257. echo "x - extracting iex/xec.c (Text)"
  258. sed 's/^X//' << 'SHAR_EOF' > iex/xec.c &&
  259. X#ifdef NEVER
  260. X/bin/cc -O -DIMANFMT -I../i $0 ../i/ilib.a -o $BIN/xec
  261. Xexit 0
  262. X#endif
  263. X
  264. X/* exec a command */
  265. X#include "ilib.h"
  266. X
  267. Xmain (argc, argv)
  268. Xint argc;
  269. Xchar *argv[];
  270. X{
  271. X    char **arg = argv + 1;
  272. X
  273. X    if (argc < 2)
  274. X        fprintf (stderr, "Usage: %s command [arg ...]\n%s%s\n", argv[0],
  275. X"\tconvert phonetic sequences to real characters in <arg> list of\n",
  276. X"\<command>, then 'exec' <command> with the converted <arg> list.\n"),
  277. X        exit (1);
  278. X
  279. X    for (++arg; !NULCHARP (*arg); arg++)
  280. XQ       ifonetic (*arg);
  281. XQ   execvp (argv[1], argv+1);
  282. X
  283. X    /* exec failed; use ierror to get system error message */
  284. X    ierror ("");
  285. X    fprintf(stderr, "%sduring execvp of '%s'\n", ierbuf, argv[1]);
  286. X    exit (1);
  287. X}
  288. SHAR_EOF
  289. $TOUCH -am 0605075390 iex/xec.c &&
  290. chmod 0755 iex/xec.c ||
  291. echo "restore of iex/xec.c failed"
  292. set `wc -c iex/xec.c`;Wc_c=$1
  293. if test "$Wc_c" != "672"; then
  294.     echo original size 672, current size $Wc_c
  295. fi
  296. # ============= iex/iexmake ==============
  297. echo "x - extracting iex/iexmake (Text)"
  298. sed 's/^X//' << 'SHAR_EOF' > iex/iexmake &&
  299. X#
  300. Xforeach file (*.c)
  301. X./$file
  302. Xend
  303. SHAR_EOF
  304. $TOUCH -am 0529183990 iex/iexmake &&
  305. chmod 0755 iex/iexmake ||
  306. echo "restore of iex/iexmake failed"
  307. set `wc -c iex/iexmake`;Wc_c=$1
  308. if test "$Wc_c" != "33"; then
  309.     echo original size 33, current size $Wc_c
  310. fi
  311. # ============= iman/driver.tex ==============
  312. if test ! -d 'iman'; then
  313.     echo "x - creating directory iman"
  314.     mkdir 'iman'
  315. fi
  316. echo "x - extracting iman/driver.tex (Text)"
  317. sed 's/^X//' << 'SHAR_EOF' > iman/driver.tex &&
  318. X\input man
  319. X\def\date{June, 1990}
  320. X\def\vers{Version 1.0}
  321. X\def\mansection{ILIB (3i)}
  322. X
  323. X\count0=-1
  324. X\input ifunlines
  325. X\input ifunclist
  326. X\input iexamplist
  327. X
  328. X\count0=1
  329. X\input i           % may 10
  330. X\input ialntok     % may 10
  331. X\input ibcmp       %
  332. X\input iblank      %
  333. X\input ibreakl     %
  334. X\input icopy       %
  335. X\input icount      %
  336. X\input icue        %
  337. X\input idate       %
  338. X\input idump       %
  339. X\input iego        %
  340. X\input ierror      %
  341. X\input iexpect     %
  342. X\input ifamily     %
  343. X\input ifilter     %
  344. X\input ifonetic    %
  345. X\input ifrombit    % may 24
  346. X\input ihash       %
  347. X\input ihms        %
  348. X\input iinput      %
  349. X\input iline       %
  350. X\input ilist       % may 10
  351. X\input ilower      %
  352. X\input imatch      %
  353. X\input imode       %
  354. X\input inest       %
  355. X\input ioctal      %
  356. X\input iopt        %
  357. X\input iread       %
  358. X\input irotate     %
  359. X\input iround      %
  360. X\input isearch     %
  361. X\input isort       %
  362. X\input istripcom   %
  363. X\input iswap       %
  364. X\input itok        % may 11
  365. X\input iuniq       %
  366. X\input iwhich      %
  367. X\input iwrite      %
  368. X
  369. X\bye
  370. SHAR_EOF
  371. $TOUCH -am 0608095290 iman/driver.tex &&
  372. chmod 0644 iman/driver.tex ||
  373. echo "restore of iman/driver.tex failed"
  374. set `wc -c iman/driver.tex`;Wc_c=$1
  375. if test "$Wc_c" != "1018"; then
  376.     echo original size 1018, current size $Wc_c
  377. fi
  378. # ============= iman/i.tex ==============
  379. echo "x - extracting iman/i.tex (Text)"
  380. sed 's/^X//' << 'SHAR_EOF' > iman/i.tex &&
  381. X% XREF ilib
  382. X
  383. X\def\name{INTRO}
  384. X\def\IT{{\bb ilib.a}}
  385. X
  386. X\S{INTRODUCTION}
  387. XProgrammers with some years of experience realize that the
  388. Xexcellent mechanism, the very robustness of ``standard I/O''
  389. Xcreates its own programming {\myit gravity well\/} that is
  390. Xdifficult to defy, and nearly impossible to escape.
  391. XTwo pillars of \stio\ are the ``{\myit null terminated strings\/}''
  392. Xand the terminal discipline of ``{\myit line buffering\/}''.
  393. X\L
  394. XThe idea of null terminated strings
  395. Xenables the system to delimit character sequences
  396. Xbetween their start address in memory and the first zero byte
  397. Xencountered when reading the contents of byte addresses incrementally
  398. Xfrom the start address.  An unavoidable side effect of using
  399. Xnull terminated strings is the appearance of a ``blind spot'' in
  400. Xrecognizing the zero byte (ASCII NUL).  Even the ubiquitous
  401. X{\myit vi\/} editor---able to manipulate every ASCII
  402. Xvalue between 1 and 127---can only report the
  403. Xnumber of encountered NUL bytes on its {\myit ex\/} command line.
  404. X\L
  405. XLine buffering allows
  406. Xediting a command or a line of input before transmitting the text
  407. Xto a process; and encourages Unix tools to keep process size small
  408. Xby managing only a single line of potentially huge amounts of
  409. Xdata at any given time.  The drawback of line buffering is
  410. Xthe tools' reduced ability to process line-terminating {\myit newline\/}
  411. Xcharacters (ASCII LF) and the total inability to handle text split
  412. Xbetween adjacent lines.  A related problem is the preponderance of
  413. Xtools structured as a {\myit filter\/}, reading input from the terminal
  414. X(instead of directly from a file), and writing output to the terminal
  415. X(instead of directly to a file).  This of course would create an
  416. Xunholy mess on the interactive terminal screen, and could never work
  417. Xsave for the {\myit redirection\/} mechanism which ``fools the system''
  418. Xinto accepting a {\myit file\/} as ``terminal input'' and another
  419. X{\myit file\/} as
  420. X``output from the terminal'', and keeps the screen uncluttered.
  421. XWhat is not so obvious is that using the same file for both input and
  422. Xoutput would garbage the text of that file the same way concurrent
  423. Xscreen I/O would trash the screen, and is disallowed by the system.
  424. X\L
  425. XIn a typical situation,
  426. Xshould one wish to transform the text in twelve
  427. Xdistinct files according to the same rules using the 
  428. X{\myit sed\/} text editor, the limitations inherent in the
  429. X{\myit filter\/} structure necessitate that twelve new files be
  430. Xcreated first to contain the respective transformed copies of the
  431. Xoriginal files.  The new files are then made to displace the
  432. Xoriginal files in twelve separate processes!
  433. XInterestingly, such un-automated tedium raises eyebrows of beginning
  434. XUnix users only.  The wise already know why things {\bb have to be}
  435. Xthe way they are, and don't use {\myit sed\/} to edit twelve files
  436. Xat once.
  437. X\L
  438. XThe author (who enjoys taking an opposing point of view) compiled
  439. Xthis collection of C routines as an aid in combatting the yoke
  440. Xof \stio.  Just as mathematicians overload the ``senseless'' meaning
  441. Xof {\myit irrational\/} to describe
  442. Xnumbers that can not be expressed as a {\myit ratio\/} of integers,
  443. XILIB functions are perceived to be {\myit irrational\/} because
  444. Xthey oppose the
  445. X{\myit rationale\/} supporting the standard C library and \stio.
  446. XHence the {\bb i} as the name of the library and as the leading
  447. Xcharacter of each of the function names.
  448. X\L
  449. XFrom an implementational perspective,
  450. Xthe \IT\ archive is simply an extension to
  451. Xthe standard library's string function
  452. Xset, favoring data manipulation within
  453. Xlarge internal character lists in order to facilitate
  454. Xin-place, direct file transformation.
  455. XThe majority of functions archived in \IT\ directly alter text in
  456. Xinternal ``buffers'' passed from the calling function.  The
  457. Xcaller passes the lowest address of the buffer as the pointer
  458. X{\myit start\/}, and the address of the byte
  459. Ximmediately beyond the highest address of the buffer as the
  460. Xpointer {\myit end\/}.
  461. XThe implicit buffer size (the difference of the two addresses)
  462. Xallows \IT\
  463. Xfunctions to ignore or bypass notions of ``null terminated strings''
  464. Xand handle ASCII values 0~through~127 in an equal manner.
  465. XString size restrictions also disappear (or expand rather, to the
  466. Xcount expressed by the system's largest positive {\myit int\/}).
  467. X\L
  468. XAll ILIB functions with {\myit start, end\/} parameters test against
  469. X{\myit (char *)NULL\/} passed for {\myit start\/}, and report an
  470. Xerror through ILIB's error function {\myit ierror()\/}.
  471. XZero-length buffers may be passed without penalty; however the
  472. Xcalled function is not obliged to process an empty buffer,
  473. Xbeyond recognizing that the buffer is empty and returning zero or
  474. XNULL.
  475. XCallers that do not know the precise size of the buffer
  476. Xmay pass {\myit (char *)NULL\/} as {\myit end\/}, or
  477. Xmay first call the \IT\ function
  478. X{\myit inull~(start)\/}.
  479. XEither of these methods results in an attempt to find the
  480. Xend of the buffer by reading it until the first zero byte.
  481. XObviously, in these cases the buffer data will not include
  482. XNUL bytes.
  483. X\L
  484. XBecause \IT\ functions perceive individual files as single strings,
  485. Xprograms written with them can attempt
  486. Xto escape stream-oriented Unix I/O and transform
  487. Xfiles in-place instead.  Most programs listed
  488. Xin this manual directly alter file contents.
  489. XTechnical concerns of direct file transformation are detailed
  490. Xin the description of the {\myit mung\/} example
  491. Xlisted along with the
  492. Xmanual pages of the {\myit ierror()\/} function.
  493. X\L
  494. XAll function names archived under \IT\ begin with {\myit i\/}.
  495. XRelated functionalities are collectively discussed in a
  496. Xchapter titled by the name of the main function variant.
  497. XChapters are in alphabetical order of title.
  498. XSome functions, in spite of being behaviorally or
  499. Xstructurally non-orthogonal to typical
  500. X\IT\ constituents, gained a firm foothold in \IT\ because of their
  501. Xusefulness.  In selecting functions for inclusion, practicality
  502. Xwas more of a concern than ILIB's ``purity''.
  503. XThe functions
  504. X{\myit iego()\/}, {\myit ihash()\/},
  505. X{\myit imonth()\/}, {\myit iinput()\/} and {\myit iwhich()\/}
  506. Xfor example,
  507. Xparse environment variables delimited by null bytes, or
  508. Xother strings whose length and range of byte values is implicit in
  509. Xthe standard data they contain.
  510. XThese functions operate on null terminated strings.
  511. XSome \IT\ functions such as {\myit icount()\/}, {\myit igroup()\/},
  512. X{\myit ihms()\/}, {\myit iopt()\/}, {\myit itok()\/},
  513. X{\myit iuniq()\/} are ``dynamic'': they
  514. Xmaintain primitive internal
  515. Xstate machines.  Such functions expect an initializing call, a
  516. Xnumber of subsequent operational calls, and in most cases,
  517. Xa single terminal call.  To utilize
  518. Xparallel instances of concurrent state machines (for example two
  519. X{\myit icount()\/} machines for counting two
  520. Xseparate sets of data simultaneously), clones of the function
  521. Xwith changed function names
  522. X(from {\myit icount() to icounta()\/})
  523. Xshould be added to \IT.
  524. X
  525. X\S{MAKING ILIB}
  526. XTo create \IT, the Unix {\myit make}
  527. Xcommand should be executed in the directory containing the C source
  528. Xfor the individual functions.  This directory
  529. Xis named {\myit i\/} in various example programs of this manual.
  530. XThe directory also contains the file dependency list used by
  531. X{\myit make\/}, in {\myit makefile\/}.  In the BSD environment,
  532. Xtype {\myit make\/} on the
  533. Xcommand line to compile the ILIB source and to archive
  534. Xthe individual {\myit .o\/} files as \IT.
  535. XWhen compiling under System~V, the command line should contain
  536. X\smallskip
  537. X\I{\mytt make -DREALUNIX}
  538. X\smallskip
  539. Xto guide the preprocessor to
  540. Xthe appropriate {\myit include files\/}, and to allow the
  541. Xcompile-time resolution of minor incompatibilities between the
  542. Xtwo systems.
  543. X\L
  544. X\IT\ is a Unix library; no provisions were made for porting to other
  545. Xoperating systems.
  546. XIn particular, the use of the ASCII character set is assumed, precluding
  547. Xoperation with EBCDIC or other character arrangements.
  548. XSystem calls are used in a transparent manner
  549. Xbetween the System~V and Berkeley versions; some system calls
  550. Xmay not port to other operating systems.
  551. X
  552. X\S{COMPILING WITH ILIB}
  553. XTo access functions in the library, the compiler should link with
  554. X\IT.  User code should instruct the preprocessor to
  555. X{\myit\#include~''ilib.h''\/}, containing
  556. Xfunction declarations and constant definitions.  The error routine
  557. X{\myit ierror()\/} through which \IT\ functions report failures, also
  558. Xdefines storage
  559. Xfor the global {\myit ierbuf\/} string, and the
  560. Xinteger {\myit ierflag\/}.
  561. X\L
  562. XSimilarly to when making
  563. XILIB, any user code (even the example programs)
  564. Xcompiled under System~V should define
  565. X{\myit REALUNIX\/}
  566. Xat compile time, to guide the preprocessor to
  567. Xthe appropriate {\myit include files\/}.
  568. X
  569. X\S{FORMAT OF THE MANUAL}
  570. XThis manual began as {\myit man pages\/} formatted as input for the
  571. XUnix {\myit troff~-man\/} command.  In spite of being renown and a
  572. Xstandard, both the {\myit troff\/} program and the {\myit man\/}
  573. Xformatting macros proved to be inflexible and generally an
  574. Xencumbrance, hindering the visual precision of the descriptions,
  575. Xand producing second-rate output.
  576. X({\myit The soapbox, please...\/})
  577. XThe perseverance of old standards is an unfortunate phenomenon;
  578. Xrevolutionary, new tools find it impossible to take foothold
  579. Xbecause of the fear of not being backward compatible with the
  580. X``lowest common denominator'' represented by the
  581. Xpedestrian forerunners.
  582. X\L
  583. XThe manual has been re-written under \TeX.  The general format of
  584. Xthe Unix {\myit man pages\/} was retained.  Technical phrases,
  585. Xfile names, function names, shell commands embedded in the manual
  586. Xtext are in {\myit italics\/}.
  587. XThe name of the currently described manual entry is
  588. Xin {\bb bold}.  Distinct command lines and program segments are in
  589. X{\mytt typewriter font}.
  590. XReferences to single key strokes and sometimes to
  591. Xcharacter combinations are clarified by
  592. Xsurrounding the character or the string with a \dx{rectangular border}.
  593. X
  594. X\S{EXAMPLE PROGRAMS}
  595. XIn an attempt to shield readers from
  596. Xincomplete, malformed and mis-printed example text, this manual
  597. Xwaives a degree of visual uniformity and topical cohesion,
  598. Xin favor of listing complete, standalone (and hopefully useful)
  599. XC programs.  The entire text of each example program is assumed to
  600. Xreside in a single file.  Since a full reproduction of program
  601. Xtext may still
  602. Xleave out crucial compiling and linking information, but a
  603. Xseparate {\myit Makefile\/}
  604. Xfor each example program would further segment the
  605. Xmanual besides being an overkill, the simple expedient of
  606. Xprepending example programs with their own compilation script
  607. Xis utilized throughout this manual.  It is assumed that the
  608. X{\myit .c\/} file containing the text would be made executable;
  609. Xand by typing the name of the file the user would execute
  610. Xthe command script in order to compile and install the object.
  611. X\L
  612. XThe command structure of most example programs has been kept
  613. Xsimple, but extendible.  The goal was to provide small and
  614. Xuncomplicated tools, and to encourage the user to upgrade the
  615. Xexample text by adding more command line options or developing
  616. Xalternate functionalities.
  617. X\L
  618. XThe command scripts listed in the manual assume compilation in the
  619. XBerkeley environment.
  620. XUnder System~V 
  621. Xthe {\myit -DREALUNIX\/} definition should be inserted into
  622. Xeach compilation script.  If the text of the example programs is
  623. Xon-line, the entire set could be changed with a single
  624. X{\myit mung\/} command ({\myit mung\/} should be made first).
  625. XThe compiler will look for ILIB include files
  626. X(principally for {\myit ilib.h\/}) in {\myit ../i\/}
  627. Xand will attempt to link with {\myit ../i/ilib.a\/}.
  628. X\L
  629. XExample programs are in typewriter font.  The text is
  630. Xnot known to contain undocumented,
  631. Xembedded non-printing characters, except
  632. Xambient white space.  Programs of {\myit filter\/} structure
  633. X(reading from \stin\ or from a file, and writing to \stout)
  634. Xwith no mandatory command line arguments
  635. Xwill wait for input if the command name is the only word on the
  636. Xcommand line.  All other
  637. Xprograms print a ``usage'' message to
  638. X\stout\ and terminate without error if the program name
  639. Xis given solo.  The ``on-error'' syntax dump
  640. Xprovides an immediate and obvious means of reviewing command
  641. Xline particulars, with no chance of causing accidental damage
  642. Xto files.  In the absence of such review the user can infer the
  643. Xfilter structure, and there is no potential for file damage.
  644. X\L
  645. XLines of program
  646. Xlistings that contain calls to the illustrated ILIB functions
  647. Xor that are essential in
  648. Xthe context of the example are prepended with an arrow.
  649. XIn order that the manual may directly include ``live'' program
  650. Xlistings (using \TeX's {\mytt\bsl\myit input\/} construct),
  651. Xthe arrows seen in the manual were
  652. Xdirectly installed in the live text of the example program,
  653. Xeach as a capital letter \key{Q}
  654. Xin the leftmost column of a program line.  The {\myit ilib.h\/}
  655. Xinclude file makes a small concession to the manual format, with the
  656. Xpreprocessor statements:
  657. X\smallskip
  658. X\I{\mytt\#ifdef\ \ IMANFMT}
  659. X
  660. X\I{\mytt\#define\ Q}
  661. X
  662. X\I{\mytt\#endif}
  663. X\smallskip
  664. XEach example program utilizes the construct by
  665. Xdefining {\myit IMANFMT\/} in its
  666. Xcompilation script, making leading \key{Q} tokens in the
  667. XC code transparent to the compiler.  At the same time
  668. Xthe examples avoid using the capital \key{Q} for variable names,
  669. Xdefinitions or in text strings, since any occurrence of \key{Q}
  670. Xin the program listings would get converted to arrows by the
  671. Xmacros that control the format of the manual.
  672. X
  673. X\S{CROSS REFERENCE OF PROGRAM EXAMPLES}
  674. XThe first column of {\bb Table~3.} gives the names of
  675. Xcomplete programs used in this manual as
  676. Xexamples.  Alternate names ({\myit aliases\/}) of a program are
  677. Xprinted in plain font, true names of programs are in boldface.
  678. XThe last column  of each line shows the
  679. Xmanual entry that describes and lists the text of the
  680. Xexample program.
  681. X
  682. X\S{AN EXAMPLE EXAMPLE PROGRAM}
  683. XThe following listing
  684. Xillustrates the compile script merged with the C code, and the use of
  685. Xthe preprocessor's {\myit \#include\/} construct for prepending the
  686. X{\myit ilib.h\/} file to the program text.
  687. XThe example program's name is {\bb q}, and its
  688. Xpurpose is the automatic channeling (queuing) of data redirected from
  689. X\stout, to temporary files.
  690. XOn the command line, {\bb q} simply precedes the full command
  691. Xwhose output is to be collected in a temporary file, for example:
  692. X\smallskip
  693. X\I{\mytt q sort -n unsorted\_file}
  694. X\smallskip
  695. XIn this invokation, {\bb q} {\myit exec\/}s the {\myit sort\/} command,
  696. Xcollects the output in a file, and prints the name of the sorted
  697. Xfile to \stout:
  698. X\smallskip
  699. X\I{\mytt /tmp/qtmp01478}
  700. X\L
  701. XThe file is created in the {\myit /tmp\/} directory.  The file name
  702. Xbegins with {\myit qtmp\/}, followed by the {\myit user~ID\/}
  703. X(right justified and zero filled to four bytes).  The last digit
  704. Xof the name
  705. Xrepresents a counter counting down from 9 to 0 then restarting back at
  706. X9: the program assumes that a user never needs more than ten
  707. Xconcurrently active temporary files.  The loop provides a self-limiting
  708. Xmechanism, automatically
  709. Xoverriding the oldest of the user's ten temporary files
  710. Xwith the new temporary data.  To explicitly clear {\myit /tmp\/}
  711. Xof these temporary files, the command name {\bb q} is used without
  712. Xtrailing arguments (making this the only example
  713. Xthat produces results with a solo token on its command line).
  714. X\L
  715. XUsing {\bb q} is most convenient for collecting data written to
  716. X\stout, for further transformation by a non-filter command.
  717. XThe Unix {\myit diff\/} is an example of a non-filter command.
  718. XTo {\myit diff\/} two unsorted lists, the normal sequence
  719. Xof commands would be:
  720. X\smallskip
  721. X\I{\mytt sort list1 > sorted\_list1}
  722. X\I{\mytt sort list2 > sorted\_list2}
  723. X\I{\mytt diff sorted\_list1 sorted\_list2}
  724. X\L
  725. XThis sequence can be
  726. Xsimplified by queuing up the intermediate
  727. X{\myit sort\/} outputs directly (quotes in the
  728. Xfollowing command are {\myit back quotes\/}):
  729. X\smallskip
  730. X\I{\mytt diff \ `q sort list1` \ `q sort list2`}
  731. X\L
  732. XMore complex command strings are the norm when using {\bb q}.
  733. XIf the token string {\bb q} is to execute contains \key{\pip}
  734. X(pipe) or \key{\les} \key{\gre} (redirection)
  735. Xtokens, the command should be enclosed in quotes, otherwise
  736. Xthe shell will only pass the command fragment on the left side
  737. Xof the pipe/redirection to {\bb q}:
  738. X\smallskip
  739. X\I{\mytt diff \ `q "grep '\car T' list1 | sort"` \ \ `q sort list2`}
  740. X\smallskip
  741. XIn this altered version of the above example, the first temporary file
  742. Xwill contain the sorted list of only those lines of {\myit list1\/}
  743. Xthat began with capital T.
  744. X\L
  745. XIn the program listing
  746. Xthe first four lines comprise the prepended script.
  747. XWhen executing this script, the first line will appear to the shell
  748. Xto be a comment.  The second line is the shell command for compiling
  749. Xthe C code.  The third line ends the script.
  750. XBecasuse {\myit NEVER\/} is intentionally left undefined, the
  751. Xpreprocessor skips the second and third lines, and the compiler
  752. Xnever sees the shell commands.
  753. X\L
  754. XAdditionally,
  755. Xthe compile-script contains the {\myit -DIMANFMT\/} definition that
  756. Xwill render capital \key{Q} tokens of the program transparent to the
  757. Xcompiler, while producing an arrow ($\longrightarrow$) in the listing
  758. Xof the program.  The script also contains the {\myit -I../i\/} path
  759. Xthat lets the preprocessor find {\myit ilib.h\/} in its (assumed)
  760. Xdirectory {\myit ../i\/} given relative to the current
  761. Xdirectory containing the executable {\bb q.c}.
  762. XThe {\bb q.c} program calls the {\myit ifonetic()\/} function
  763. Xfrom {\bb ilib.a} in order to resolve ``phonetic control sequences''
  764. X(described under the {\myit ifonetic()\/} manual entry).
  765. XTo do this, the program has to link with {\bb ilib.a}, whose full path
  766. X{\myit ../i/ilib.a\/} is also a part of the script,
  767. X\L
  768. XThe first task of the {\bb q} process is to produce a name
  769. Xtemplate containing the target path {\myit /tmp\/}, the
  770. Xconstant string {\myit qtmp\/} and the user's {\myit uid\/},
  771. Xending with an extra {\myit counter\/} byte whose value can vary
  772. Xbetween the ASCII '0' and '9'.  If there were no command 
  773. Xline arguments, {\bb q} removes any existing files that match the
  774. Xtemplate.  Otherwise, if {\myit /tmp\/} does not yet contain all
  775. Xten template variants, the new file created will end with the highest
  776. Xunused counter byte.  If all ten file name variants already exist,
  777. Xthe ``oldest'' (least recently modified) is recycled, losing its
  778. Xprevious data.  All command line arguments that followed {\bb q}
  779. Xare then concatenated into a space-separated list of tokens, and
  780. Xthe {\myit system()\/} command executes the new string, redirecting
  781. Xits \stout\ output to the selected {\myit qtmp\/} file.  The
  782. Xfull pathname of the {\myit qtmp\/} file is echoed to {\bb q}'s
  783. X\stout.
  784. X
  785. X\S{q.c PROGRAM TEXT}
  786. X\listing{../iex/q.c}
  787. X\eject
  788. SHAR_EOF
  789. $TOUCH -am 0601084990 iman/i.tex &&
  790. chmod 0644 iman/i.tex ||
  791. echo "restore of iman/i.tex failed"
  792. set `wc -c iman/i.tex`;Wc_c=$1
  793. if test "$Wc_c" != "18670"; then
  794.     echo original size 18670, current size $Wc_c
  795. fi
  796. # ============= iman/ialntok.tex ==============
  797. echo "x - extracting iman/ialntok.tex (Text)"
  798. sed 's/^X//' << 'SHAR_EOF' > iman/ialntok.tex &&
  799. X% XREF ialntok ianytok ictok
  800. X
  801. X\def\name{IALNTOK}
  802. X\def\IT{{\bb ialntok()}}
  803. X
  804. X\S{NAME}
  805. X{\bb ialntok} --- copy first alphanumeric token into word buffer
  806. X
  807. X{\bb ianytok} --- copy first token of source into word buffer
  808. X
  809. X{\bb ictok} --- copy first C token of source into word buffer
  810. X
  811. X\S{SYNOPSIS}
  812. X{\obeylines \bb
  813. Xchar *
  814. Xialntok (start, end, wbuf)
  815. Xchar *start;
  816. Xchar *end;
  817. Xchar *wbuf;
  818. X\L
  819. Xchar *
  820. Xianytok (start, end, wbuf)
  821. Xchar *start;
  822. Xchar *end;
  823. Xchar *wbuf;
  824. X\L
  825. Xchar *
  826. Xictok (start, end, wbuf)
  827. Xchar *start;
  828. Xchar *end;
  829. Xchar *wbuf;
  830. X}
  831. X
  832. X\S{DESCRIPTION}
  833. XPrograms operating on text streams inevitably
  834. Xorganize bytes into groups of
  835. Xprinting characters or {\myit tokens\/}.  Text is then handled
  836. Xas successive tokens separated by non-printing
  837. X{\myit white space\/} characters,
  838. Xor made distinct by other token-forming rules.  The \IT\ functions
  839. Xrecognize and isolate the ``next token'' from {\myit start\/}.
  840. X\L
  841. XA pointer is advanced from {\myit start\/} to the first printing
  842. Xcharacter in the stream.  This is the beginning of the token.  A
  843. Xsecond pointer is advanced to the byte just past the token.  The
  844. Xthree functions use different character sets for mapping
  845. Xprinting characters as part of the recognized token.
  846. X\L
  847. XEither of the functions return the address of
  848. Xthe byte just past the token in the original stream.
  849. X(This address may be {\myit end\/}, if no trailing spaces followed
  850. Xa single token in the stream.)  To get a ``next token''
  851. X(to strip out a sequence of tokens from a stream), the caller
  852. Xneed merely to assign the returned address as the new {\myit start\/}
  853. Xpoint.
  854. X\L
  855. XThe text stream containing the token is not disturbed during parsing;
  856. Xthe token is
  857. Xcopied into a small buffer supplied by the caller via the pointer
  858. X{\myit wbuf\/}, and is null terminated in {\myit wbuf\/}.
  859. XThe caller passes a
  860. X{\myit wbuf\/} of
  861. Xsufficient size to hold the maximum expected token plus the
  862. Xfinal NUL byte; for 
  863. X{\bb ictok()} a minimum of {\myit IHALFK\/} (512 bytes) is
  864. Xrecommended.
  865. X\L
  866. X{\bb ianytok()} considers any printing character a legitimate member of
  867. Xthe token byte string.  The token ends when the next byte is a space,
  868. Xa NUL byte, a ``control character'' (including {\myit newline, tab,\/}
  869. Xetc.), or the end of the buffer
  870. X(pointed to by {\myit end\/}).  Thus, the token may contain punctuation
  871. Xmarks, hyphenation, math symbols and special printing characters.
  872. X\L
  873. X\IT\ creates multi-byte tokens from alphanumeric characters only, using
  874. Xthe 26 (upper or lower case) characters of the alphabet plus the
  875. Xdigits 0~--~9.
  876. XThe token ends when the next byte is a space, a non-alphanumeric
  877. Xcharacter,
  878. Xa NUL byte, a ``control character'', or the end of the buffer
  879. X(pointed to by {\myit end\/}).
  880. XIf a printing character which is recognized as the beginning
  881. Xof a token is itself not alphanumeric, this character is interpreted
  882. Xas a single-byte token terminating with the next byte.
  883. X\L
  884. X{\bb ictok()} is similar to \IT, except that
  885. X{\bb ictok()} in the C tradition, moves
  886. Xunderscore\key{\und} and dollar\key{\$} characters
  887. Xinto the alphanumeric set from which
  888. Xto build multi-byte aggregate tokens.  Furthermore,
  889. Xthe token-forming rules under
  890. X{\bb ictok()} permit multi-byte tokens formed of adjacent
  891. Xnon-alphanumeric printing characters, if the token thus created is a
  892. Xvalid token in the C language.  The following
  893. Xnon-alphanumeric aggregates are recognized:
  894. X\L
  895. X{\obeylines
  896. XCharacter constants
  897. X\smallskip
  898. X{\mytt\dx{\bsl <CR>}\ \twokey{\bsl "}\ \twokey{\bsl '}\ \dx{\bsl <octal>}\ \twokey{\bsl \bsl}\ \twokey{\bsl b}\ \twokey{\bsl f}\ \twokey{\bsl n}\ \twokey{\bsl r}\ \twokey{\bsl t}\ \twokey{\bsl v}}
  899. X\L
  900. XC operators
  901. X\smallskip
  902. X{\mytt\twokey{!=}\ \twokey{\%=}\ \twokey{\&\&}\ \twokey{\&=}\ \twokey{*=}\ \twokey{++}\ \twokey{+=}\ \twokey{--}\ \twokey{-=}\ \twokey{->}\ \twokey{/=}\ \twokey{<<}\ \dx{<<=}\ \twokey{<=}
  903. X\smallskip
  904. X\twokey{==}\ \twokey{>=}\ \twokey{>>}\ \twokey{>>=}\ \twokey{\cir =}\ \twokey{|=}\ \twokey{||}}
  905. X\L
  906. XArchaic operators
  907. X\smallskip
  908. X{\mytt\twokey{=*}\ \twokey{=+}\ \twokey{=-}}
  909. X\L
  910. XDecimal point as a part of decimal digit strings, comment delimiters
  911. X\smallskip
  912. X{\mytt \dx{\lsq<digits>\rsq.\lsq<digits>\rsq}\ \twokey{/*}\ \twokey{*/}}
  913. X\smallskip
  914. X}
  915. X\L
  916. XAdditionally, strings that begin with a \key{"}\ or \key{'}\
  917. Xcharacter, force
  918. X{\bb ictok()} to include all following bytes of the string as part of
  919. Xthe currently evaluated token, up to and including the next
  920. Xnot-escaped \key{"}\ or \key{'}\ byte, respectively.
  921. XIf a matching quote character is not found by the 511th byte, parsing
  922. Xstops, and ``{\myit runaway double quote\/}'' or
  923. X``{\myit runaway single quote\/}'' is written into {\myit wbuf\/}
  924. Xinstead.  Parsing can then continue from the 512th byte, or the
  925. Xcurrent 512-byte stretch of the buffer can be reexamined to
  926. Xanalyze the failure.
  927. X\L
  928. X{\bb ictok()} makes no special arrangements for preprocessor syntax:
  929. X{\myit \#include\/} for example, is seen as two separate tokens
  930. X\key{\#}\ and \dx{\mytt include}.
  931. X\L
  932. XIf no token has been found on encountering {\myit end\/}, a NULL pointer
  933. Xis returned as a sentinel.  In this case, {\myit wbuf\/} is left
  934. Xintact, potentially still
  935. Xcontaining the token found during a previous call.
  936. XNULL is also returned
  937. X(immediately after a call to {\myit ierror()\/})
  938. Xif {\myit start\/} points to NULL.
  939. X
  940. X\S{SEE ALSO}
  941. X{\myit itok, iexpect\/}.
  942. X
  943. X\S{rewrap EXAMPLE PROGRAM}
  944. XThe {\bb rewrap} program is a simple text formatter, producing output
  945. Xsimilar to
  946. Xthe Unix {\myit fold\/} or {\myit fmt\/} commands, but reorganizing
  947. Xand changing the
  948. Xoriginal file directly instead of filtering input to \stout.
  949. X{\bb rewrap} demonstrates a method of in-place file transformation
  950. Xusing a temporary target file instead of internal buffers.
  951. XThe source is read
  952. Xline-by-line; its tokens are extracted using
  953. X{\bb anytok()} and are queued in an intermediate buffer,
  954. Xseparated from the previous token by a space (two spaces if the
  955. Xprevious token ended with a period).  When the addition of
  956. Xthe next token would bring the buffer length over
  957. Xthe command-given limit, {\bb rewrap} appends the
  958. Xbuffer text to the temporary file created in
  959. X{\myit /tmp\/}, then restarts the queue with the token that would have
  960. Xcaused the buffer overflow.
  961. X\L
  962. XThus, the original words are re-listed so that all new
  963. Xlines contain the maximum number of complete words; and no
  964. Xline exceeds the specified line width.
  965. XBlank lines of the original text
  966. X(lines not containing tokens)
  967. Xsignal a new paragraph: the blank line causes an immediate flush of
  968. Xthe queue, and the output of a linefeed.
  969. XAt the end of the tokenizing process, the original file is removed,
  970. Xand the target file is moved into its place.
  971. XThe {\bb rewrap} algorithm preserves the indentation
  972. X(from the left margin) of the old text.
  973. XAs an example, the file {\myit quote\/}, containing
  974. X\L
  975. X\I{\listing{stanquote.old}}
  976. X\L
  977. Xcould be re-formatted as 76-column lines with the command:
  978. X\L
  979. X\I{\mytt rewrap 76 quote}
  980. X\medskip
  981. X\I{\listing{stanquote.new}}
  982. X\L
  983. XInstead of using {\myit fopen()\/} to gain access to the source and
  984. Xtarget files, {\bb rewrap} calls {\myit freopen()\/}, reusing the
  985. Xotherwise idle file pointers \stin\ and \stout.
  986. XApart from a better use of
  987. Xresources, this would permit the use of the more convenient
  988. X{\myit gets(), puts()\/} calls instead of
  989. X{\myit fgets(), fputs()\/}, although {\bb rewrap}
  990. Xstill calls {\myit fgets()\/} because the second parameter
  991. X(the maximum allowed line size) of this
  992. Xfunction is a built-in
  993. Xsafeguard against buffer overflow.  Because the \stout\ stream is
  994. Xautomatically buffered by the operating system (not written until
  995. Xit accummulates {\myit BUFSIZ\/} bytes)
  996. X{\bb rewrap} must explicitly flush \stout\ to
  997. Xcomplete partial output to the temporary file.
  998. X
  999. X\S{rewrap.c PROGRAM TEXT}
  1000. X\listing{../iex/rewrap.c}
  1001. X\eject
  1002. SHAR_EOF
  1003. $TOUCH -am 0531155190 iman/ialntok.tex &&
  1004. chmod 0644 iman/ialntok.tex ||
  1005. echo "restore of iman/ialntok.tex failed"
  1006. set `wc -c iman/ialntok.tex`;Wc_c=$1
  1007. if test "$Wc_c" != "7693"; then
  1008.     echo original size 7693, current size $Wc_c
  1009. fi
  1010. # ============= iman/ibcmp.tex ==============
  1011. echo "x - extracting iman/ibcmp.tex (Text)"
  1012. sed 's/^X//' << 'SHAR_EOF' > iman/ibcmp.tex &&
  1013. X% XREF ibcmp ibcopy ilast
  1014. X
  1015. X\def\name{IBCMP}
  1016. X\def\IT{{\bb ibcmp()}}
  1017. X
  1018. X\S{NAME}
  1019. X{\bb ibcmp} --- compare two byte strings
  1020. X
  1021. X{\bb ibcopy} --- copy bytes from one place to another
  1022. X
  1023. X{\bb ilast} --- find last occurrence of character in a string
  1024. X
  1025. X\S{SYNOPSIS}
  1026. X{\obeylines \bb
  1027. Xint
  1028. Xibcmp (s1, s2, bytes)
  1029. Xchar *s1;
  1030. Xchar *s2;
  1031. Xint bytes;
  1032. X\L
  1033. Xvoid
  1034. Xibcopy (tobuf, frombuf, bytes)
  1035. Xchar *tobuf;
  1036. Xchar *frombuf;
  1037. Xint bytes;
  1038. X\L
  1039. Xchar *
  1040. Xilast (ptr, c)
  1041. Xchar *ptr;
  1042. Xchar c;
  1043. X}
  1044. X
  1045. X\S{DESCRIPTION}
  1046. XFrom the caller's point of view,
  1047. Xonly the names are different between System~V's {\myit memcmp()\/}
  1048. Xand the Berkeley {\myit bcmp()\/} functions.  Both compare a number
  1049. Xof bytes beginning at {\myit s1\/} against the same number of bytes
  1050. Xbeginning at {\myit s2\/}, and return the difference of the byte
  1051. Xvalues at the first byte mismatch (subtracting the
  1052. X{\myit s2\/} byte from the {\myit s1\/} byte).
  1053. X{\bb ibcmp()} is a {\myit macro\/} defined in {\myit ilib.h\/},
  1054. Xmapping to {\myit memcmp()\/} or
  1055. X{\myit bcmp()\/} depending on the system under which ILIB
  1056. Xwas compiled.
  1057. X\L
  1058. XThe
  1059. XSystem~V {\myit memcpy()\/} function and the
  1060. XBerkeley {\myit bcopy()\/} function both copy a number of
  1061. Xbytes from one buffer to another.  In spite the
  1062. Xidentical goal, the two functions are named differently,
  1063. Xreturn different {\myit types\/}, and use source and target
  1064. Xparameters in opposite order.
  1065. X{\myit memcpy()\/} and {\myit bcopy()\/}
  1066. Xare both standard library functions.
  1067. XOptimized ``to the hilt'', they can easily run ten (or more)
  1068. Xtimes faster than implementations
  1069. Xcopying bytes in a {\myit for loop\/}
  1070. Xin {\myit user space\/}.
  1071. X{\bb ibcopy()} is a {\myit macro\/} defined in {\myit ilib.h\/},
  1072. Xmapping to {\myit memcpy()\/} if ILIB has been compiled with the
  1073. X{\myit REALUNIX\/} flag, or to BSD's {\myit bcopy()\/} otherwise.
  1074. X{\bb ibcopy()} retains {\myit memcpy\/}'s
  1075. Xtarget--source parameter order also employed by the
  1076. Xstandard string functions {\myit strcat(), strcpy(),\/} etc..
  1077. XThere are no errors.
  1078. X\L
  1079. X{\bb ilast()} is a true function,
  1080. Xbypassing the {\myit rindex()\/} versus {\myit strrchr()\/}
  1081. Xincompatibility between Unix variants,
  1082. X{\bb ilast()}
  1083. Xfinds the last occurrence of some character ``{\myit c\/}'' in the
  1084. Xnull-terminated buffer pointed to by {\myit ptr\/}, and
  1085. Xreturns a pointer to it or a pointer to NULL on failure.
  1086. XNULL is returned and {\myit ierflag\/} is set if the passed-in
  1087. X{\myit ptr\/} is itself the NULL pointer.
  1088. X\eject
  1089. SHAR_EOF
  1090. $TOUCH -am 0601085990 iman/ibcmp.tex &&
  1091. chmod 0644 iman/ibcmp.tex ||
  1092. echo "restore of iman/ibcmp.tex failed"
  1093. set `wc -c iman/ibcmp.tex`;Wc_c=$1
  1094. if test "$Wc_c" != "2388"; then
  1095.     echo original size 2388, current size $Wc_c
  1096. fi
  1097. # ============= iman/iblank.tex ==============
  1098. echo "x - extracting iman/iblank.tex (Text)"
  1099. sed 's/^X//' << 'SHAR_EOF' > iman/iblank.tex &&
  1100. X% XREF iblank itran
  1101. X
  1102. X\def\name{IBLANK}
  1103. X\def\IT{{\bb iblank()}}
  1104. X
  1105. X\S{NAME}
  1106. X{\bb iblank} --- change all bytes to spaces
  1107. X
  1108. X{\bb itran} --- change one character to another everywhere in buffer
  1109. X
  1110. X\S{SYNOPSIS}
  1111. X{\obeylines \bb
  1112. Xvoid
  1113. Xiblank (start, end)
  1114. Xchar *start;
  1115. Xchar *end;
  1116. X\L
  1117. Xint
  1118. Xitran (start, end, fromc, toc)
  1119. Xchar *start;
  1120. Xchar *end;
  1121. Xchar fromc;
  1122. Xchar toc;
  1123. X}
  1124. X
  1125. X\S{DESCRIPTION}
  1126. X\IT\ clears an internal buffer beginning at {\myit start\/} and
  1127. Xending one byte before {\myit end\/}, by changing each byte in the
  1128. Xbuffer to the {\myit space\/} character (ASCII 32).  The function is
  1129. Xemployed to ``white out'' comment fields in text,
  1130. Xso subsequent parsing would encounter meaningful tokens only.
  1131. XThe user's text is typically pre-scanned
  1132. Xto locate comments (perhaps using the
  1133. X{\myit inest()\/} function); the {\myit start\/} and {\myit end\/}
  1134. Xaddress of each comment are then passed to \IT.
  1135. X\L
  1136. XThe more selective {\bb itran()} function searches the passed buffer
  1137. Xfor {\myit fromc\/} characters; converting each
  1138. X{\myit fromc\/} value to {\myit toc\/}.
  1139. X{\bb itran()} returns the count of converted characters.
  1140. X\L
  1141. X\IT\ does not report errors.
  1142. X{\bb itran()} calls {\myit ierror()\/} if {\myit (char *)NULL\/} is
  1143. Xpassed as {\myit start\/}.
  1144. X\L
  1145. X\S{SEE ALSO}
  1146. XThe {\myit iswapstr()\/} or
  1147. X{\myit iswapw()\/} functions provide a means for transforming all
  1148. Xoccurrences of a single, multi-byte source token to a target token,
  1149. Xglobally
  1150. Xwithin the passed buffer.  The {\myit idump()\/} function can be
  1151. Xused to print an image of the internal buffer to \stout.
  1152. X\eject
  1153. SHAR_EOF
  1154. $TOUCH -am 0601092690 iman/iblank.tex &&
  1155. chmod 0644 iman/iblank.tex ||
  1156. echo "restore of iman/iblank.tex failed"
  1157. set `wc -c iman/iblank.tex`;Wc_c=$1
  1158. if test "$Wc_c" != "1535"; then
  1159.     echo original size 1535, current size $Wc_c
  1160. fi
  1161. # ============= iman/ibreakl.tex ==============
  1162. echo "x - extracting iman/ibreakl.tex (Text)"
  1163. sed 's/^X//' << 'SHAR_EOF' > iman/ibreakl.tex &&
  1164. X% XREF ibreakl
  1165. X
  1166. X\def\name{IBREAKL}
  1167. X\def\IT{{\bb ibreakl()}}
  1168. X
  1169. X\S{NAME}
  1170. X{\bb ibreakl} --- break long lines into shorter ones
  1171. X
  1172. X\S{SYNOPSIS}
  1173. X{\obeylines \bb
  1174. Xint
  1175. Xibreakl (start, end, tobuf, header, ender, breakc, maxc, all)
  1176. Xchar *start;
  1177. Xchar *end;
  1178. Xchar *tobuf;
  1179. Xchar *header;
  1180. Xchar *ender;
  1181. Xchar *breakc;
  1182. Xint maxc;
  1183. Xint all;
  1184. X}
  1185. X
  1186. X\S{DESCRIPTION}
  1187. XThe \IT\ function serves as a
  1188. Xline manager of long lines that must be broken at
  1189. Xsome token boundaries, into shorter lines.
  1190. X\IT\ has the dubious distinction of featuring the longest
  1191. Xparameter list among the ILIB functions, as a
  1192. Xdirect result of the extraordinary computational complexity of even the
  1193. Xsimplest formatting requests.
  1194. X\L
  1195. XAn example source string that required re-formatting could be a
  1196. XBASIC {\myit data statement\/} automatically generated by a
  1197. Xprogram writer process:
  1198. X\L
  1199. X{\obeylines\mytt\leftskip=20pt
  1200. XDATA\ "this\ is\ string1",\ "this\ is\ string2",\ "this\ is\ string3",\ "this\ is\ st
  1201. Xring4",\ "this\ is\ string5",\ "this\ is\ string6",\ "this\ is\ string7",\ "this\ is
  1202. X\ string8",\ "this\ is\ string9",\ "this\ is\ string10",\ "this\ is\ string11",\ "th
  1203. Xis\ is\ string12"
  1204. X}
  1205. X\L
  1206. XHaving collected the necessary components of the statement,
  1207. Xthe program writer would need to {\myit output\/} the statement in a
  1208. Xvisually clear format:
  1209. X\L
  1210. X{\obeylines\mytt\leftskip=20pt
  1211. XDATA\ "this\ is\ string1",\ "this\ is\ string2",\ "this\ is\ string3",
  1212. X\ \ \ \ \ "this\ is\ string4",\ "this\ is\ string5",\ "this\ is\ string6",
  1213. X\ \ \ \ \ "this\ is\ string7",\ "this\ is\ string8",\ "this\ is\ string9",
  1214. X\ \ \ \ \ "this\ is\ string10",\ "this\ is\ string11",\ "this\ is\ string12"
  1215. X}
  1216. X\L
  1217. XA glance at the output suggests that the original string
  1218. Xwas broken up into lines by {\myit newline\/} characters placed
  1219. Ximmediately past {\myit commas\/}
  1220. Xonce the current target line was relatively full;
  1221. Xand that extra {\myit white space\/} (apparently four {\myit space\/}
  1222. Xcharacters) got inserted at the head of each new line to offset the
  1223. X``DATA'' token from the data strings.
  1224. X\L
  1225. XIn the \IT\ parameter list, {\myit start\/} and {\myit end\/}
  1226. Xdefine the limits of the buffer containing the source string.
  1227. XTypically to ILIB, {\myit end\/} is set to one byte {\bb past} the
  1228. Xlast byte of the source string.
  1229. XThe next parameter {\myit tobuf\/} is a pointer to the destination
  1230. Xstorage allocated or defined by the process that calls \IT,
  1231. Xthe buffer where \IT\ is to place the re-formatted result.
  1232. XThe caller must guarantee that {\myit tobuf\/} is of sufficient size
  1233. Xto contain the processed, enlarged target string, plus a terminating
  1234. XNUL byte.
  1235. X\L
  1236. X{\myit header\/} points to a string that \IT\ should prepend at
  1237. Xeach new line before adding more segments of the source string to
  1238. Xthe line.  In the example above, the {\myit header\/} string
  1239. Xcontained four {\myit space\/} characters.  Similarly,
  1240. Xthe string pointed to by {\myit ender\/}
  1241. Xis to be appended to each new line; in the above example {\myit ender\/}
  1242. Xconsisted of a single {\myit newline\/} character.
  1243. XBoth {\myit header\/} or {\myit ender\/} may be passed as
  1244. X{\myit (char~*) NULL\/}, suppressing prepended or trailing strings.
  1245. X\L
  1246. XThe {\myit breakc\/} pointer points to a string of un-ordered
  1247. Xcharacters comprising a
  1248. Xset of delimiters: when parsing the source string, a
  1249. X{\myit break point\/} is recognized immediately following
  1250. Xa character of the source string that matches any single character of
  1251. Xthe delimiter set.
  1252. XA {\myit break point\/} marks a spot at which the source line
  1253. Xcan be split.  In the above example, the {\myit breakc\/} string
  1254. Xcontained a single {\myit comma\/} character.
  1255. X\L
  1256. X{\myit maxc\/} is the maximum permissible
  1257. Xbyte count of any newly made line, including {\myit newline\/}
  1258. Xor other non-printing characters that may already be present in the
  1259. Xsource string, and also including the newly prepended {\myit header\/}
  1260. Xand appended {\myit ender\/} strings.
  1261. X\L
  1262. XIf the last parameter
  1263. X{\myit all\/} is TRUE (non-zero), the {\myit header\/}
  1264. Xstring is prepended to each line of the result,
  1265. Xeven the first; and
  1266. X{\myit ender\/} is appended to each line of the result, even the last.
  1267. XOtherwise,
  1268. X{\myit header\/} is not prepended to the initial line of the result,
  1269. Xand
  1270. X{\myit ender\/} is not appended to the final line of the result.
  1271. X\L
  1272. XAtypically to ILIB, the {\myit header, ender, breakc\/} strings passed
  1273. Xto \IT\ are
  1274. Xassumed to be null terminated, normal C strings;
  1275. Xthe piecing-together operations utilize standard string functions
  1276. X{\myit strcat(), strcmp()\/}, and the like.  There seemed to be
  1277. Xvery little utility in coding this function to accept arbitrary
  1278. Xstrings potentially containing embedded NUL bytes.
  1279. X
  1280. X\S{RETURN VALUES}
  1281. XThe {\myit int\/} returned from \IT\ is the byte length of the
  1282. Xprocessed, final string in {\myit tobuf\/}, not including the
  1283. Xterminal NUL byte.  Error returns of
  1284. Xnegative {\myit sys\_nerr\/} indicate either
  1285. X\smallskip
  1286. X{\parindent=40pt
  1287. X\item{$\bullet$}
  1288. Xthat the sum of the lengths of {\myit header\/}
  1289. Xand {\myit ender\/}
  1290. Xis greater than the maximum specified line length {\myit maxc\/},
  1291. X\smallskip
  1292. X\item{$\bullet$}
  1293. Xor that \IT\ could not find a {\myit break point\/} within
  1294. Xthe evaluated source substring (such that the length of the current
  1295. Xtarget line,
  1296. Xwith {\myit header\/} and {\myit ender\/} included if appropriate,
  1297. Xdidn't exceed {\myit maxc\/} bytes)
  1298. Xat which the source string could have been broken.  In this case,
  1299. X{\myit tobuf\/} may already contain partial results.
  1300. X\smallskip
  1301. X}
  1302. X\eject
  1303. SHAR_EOF
  1304. $TOUCH -am 0509104090 iman/ibreakl.tex &&
  1305. chmod 0644 iman/ibreakl.tex ||
  1306. echo "restore of iman/ibreakl.tex failed"
  1307. set `wc -c iman/ibreakl.tex`;Wc_c=$1
  1308. if test "$Wc_c" != "5408"; then
  1309.     echo original size 5408, current size $Wc_c
  1310. fi
  1311. # ============= iman/icopy.tex ==============
  1312. echo "x - extracting iman/icopy.tex (Text)"
  1313. sed 's/^X//' << 'SHAR_EOF' > iman/icopy.tex &&
  1314. X% XREF icopy
  1315. X
  1316. X\def\name{ICOPY}
  1317. X\def\IT{{\bb icopy()}}
  1318. X
  1319. X\S{NAME}
  1320. X{\bb icopy} --- copy buffer into dynamically allocated memory
  1321. X
  1322. X\S{SYNOPSIS}
  1323. X{\obeylines \bb
  1324. Xchar *
  1325. Xicopy (start, end)
  1326. Xchar *start;
  1327. Xchar *end;
  1328. X}
  1329. X
  1330. X\S{DESCRIPTION}
  1331. X\IT\ is used to create a duplicate of an
  1332. Xinternal buffer by
  1333. Xdynamically allocating space for the new buffer, and then calling
  1334. X{\myit ibcopy()\/} to copy the source bytes.
  1335. XThe source buffer begins at {\myit start\/}, and ends
  1336. Xwith the byte before {\myit end\/}.
  1337. XA new buffer one
  1338. Xbyte greater than the size of the passed buffer,
  1339. Xis allocated by \IT;
  1340. Xthe source is copied into the new buffer, and
  1341. Xthe extra byte at the end of the new buffer is set to NUL.
  1342. X\IT\ returns a pointer to the allocated memory.
  1343. XIf the NULL pointer is passed as {\myit start\/} or if
  1344. X{\myit malloc()\/} fails, \IT\ calls {\myit ierror()\/} and
  1345. Xreturns {\myit (char~*) NULL\/}.
  1346. X\eject
  1347. SHAR_EOF
  1348. $TOUCH -am 0601094490 iman/icopy.tex &&
  1349. chmod 0644 iman/icopy.tex ||
  1350. echo "restore of iman/icopy.tex failed"
  1351. set `wc -c iman/icopy.tex`;Wc_c=$1
  1352. if test "$Wc_c" != "881"; then
  1353.     echo original size 881, current size $Wc_c
  1354. fi
  1355. # ============= iman/icount.tex ==============
  1356. echo "x - extracting iman/icount.tex (Text)"
  1357. sed 's/^X//' << 'SHAR_EOF' > iman/icount.tex &&
  1358. X% XREF icount
  1359. X
  1360. X\def\name{ICOUNT}
  1361. X\def\IT{{\bb icount()}}
  1362. X
  1363. X\S{NAME}
  1364. X{\bb icount} --- count how many times a specific parameter was passed
  1365. X
  1366. X\S{SYNOPSIS}
  1367. X{\obeylines \bb
  1368. Xint
  1369. Xicount (type)
  1370. Xint type;
  1371. X}
  1372. X
  1373. X\S{DESCRIPTION}
  1374. X\IT\ is a dynamic function, expecting a setup call, zero or more
  1375. Xoperational calls, and a resetting final call.
  1376. XFor a simple example of a program that may use \IT,
  1377. Ximagine a routine for a robot arm programmed
  1378. Xto lift single pieces of fruit out of a basket, and having
  1379. Xrecognized the type of the fruit,
  1380. Xkeep separate counts of the apples, the oranges and the bananas.
  1381. XThe program could just increment
  1382. Xthree distinct variables when counting the fruit; but
  1383. Xif the number of types counted in parallel
  1384. Xwas large, or if the types varied from time to time,
  1385. Xa discreet subroutine would
  1386. Xbe defined to allocate and manage the array space
  1387. Xof the counters. \IT\ is such a subroutine.
  1388. X\L
  1389. XThe first call to \IT\ passes the number of array elements
  1390. Xthat \IT\ should allocate to store the count of
  1391. Xthe separate types during the following operational calls.
  1392. XIn the above example, three types
  1393. X(apples, oranges, bananas) would be counted, set up with
  1394. Xthe initializing call:
  1395. X\smallskip
  1396. X\I{\mytt icount (3);}
  1397. X\L
  1398. XThis first call returns zero unless the number of
  1399. X{\myit type\/}s requested was zero, or the array allocation failed.
  1400. XEither exception would call {\myit ierror()\/} and return negative,
  1401. Xleaving \IT\ ready for another initializing call.
  1402. X\L
  1403. XAt the end of each operational call, \IT\ returns
  1404. Xthe tally of previous calls in which the {\myit type\/} of the
  1405. Xcurrent call was passed.  In the fruit example, the robot program
  1406. Xwould
  1407. X\smallskip
  1408. X{\mytt
  1409. X\I{\#define APPLE \ 0}
  1410. X\I{\#define BANANA 1}
  1411. X\I{\#define ORANGE 2}
  1412. X}
  1413. X\smallskip
  1414. Xand on encountering some ``orange orange banana apple orange apple apple
  1415. Xorange'' sequence, would call \IT\ eight times.  The values
  1416. Xreturned from these calls are shown after each call as comments:
  1417. X\smallskip
  1418. X{\mytt
  1419. X\I{icount (ORANGE); /* 0 */}
  1420. X\I{icount (ORANGE); /* 1 */}
  1421. X\I{icount (BANANA); /* 0 */}
  1422. X\I{icount (APPLE); \ /* 0 */}
  1423. X\I{icount (ORANGE); /* 2 */}
  1424. X\I{icount (APPLE); \ /* 1 */}
  1425. X\I{icount (APPLE); \ /* 2 */}
  1426. X\I{icount (ORANGE); /* 3 */}
  1427. X}
  1428. X\L
  1429. XThe range of legitimate {\myit type\/}
  1430. Xvalues for operational calls is from zero through
  1431. Xone less than the array
  1432. Xsize specified in the initializing call, directly corresponding to
  1433. Xindices into the allocated array.  Out-of-bound operational
  1434. Xparameters trigger
  1435. Xa negative return (via {\myit ierror()\/}) but do not affect
  1436. X\IT\ internal states.
  1437. XIn the fruit example, the call
  1438. X\smallskip
  1439. X{\mytt
  1440. X\I{\#define PASSIONFRUIT 3}
  1441. X\I{icount (PASSIONFRUIT);}
  1442. X}
  1443. X\smallskip
  1444. Xwould return the negative {\myit sys\_nerr\/}, but more APPLEs,
  1445. XBANANAs and ORANGEs could be counted immediately afterwards.
  1446. X\L
  1447. XThe terminating call passes a negative number, to reset
  1448. Xthe \IT\ state machine and to free dynamically allocated memory.
  1449. X
  1450. X\S{SEE ALSO}
  1451. X{\myit ierror, iuniq\/}.
  1452. X
  1453. X\S{distrib EXAMPLE PROGRAM}
  1454. XThe {\bb distrib\/} program is an aid in
  1455. Xanalyzing text distribution characteristics of selected strings, words,
  1456. Xor characters.  Each parameter following {\bb distrib\/}
  1457. Xon the command line is an object on which statistical information is
  1458. Xsought.  The program counts and
  1459. Xreports how many times each object occurred in the input.  Text
  1460. Xis supplied to {\bb distrib\/} interactively, or by input redirection.
  1461. XThough the report is produced only after ``end of file'',
  1462. Xthe program reads a line at a time, so patterns spanning lines
  1463. Xcannot be discerned.  For a given pattern, each byte
  1464. Xof the examined line is a starting point for a possible
  1465. Xmatch: in the string ``rococo'' the pattern ``oco'' is found twice.
  1466. X\L
  1467. XGiven an input file {\myit pi\/} containing the first hundred decimal
  1468. Xdigits of \char5, the following  {\bb distrib} command would produce
  1469. Xa distribution of digits:
  1470. X\smallskip
  1471. X\I{\mytt distrib 0 1 2 3 4 5 6 7 8 9 \les \ pi}
  1472. X\medskip
  1473. X{\mytt \obeylines
  1474. X\ \ \ \ 0: 8
  1475. X\ \ \ \ 1: 8
  1476. X\ \ \ \ 2: 12
  1477. X\ \ \ \ 3: 12
  1478. X\ \ \ \ 4: 10
  1479. X\ \ \ \ 5: 8
  1480. X\ \ \ \ 6: 9
  1481. X\ \ \ \ 7: 8
  1482. X\ \ \ \ 8: 12
  1483. X\ \ \ \ 9: 13
  1484. X}
  1485. X\L
  1486. XAnother example checks that the input contains the same number of
  1487. Xleft and right curly braces, using phonetic control sequences
  1488. X(described under {\myit ifonetic()\/}) to
  1489. Xavoid the need to quote:
  1490. X\smallskip
  1491. X\I{\mytt distrib Xlcu Xrcu \les \ distrib.c}
  1492. X\L
  1493. XA third command produces an ``alphabetic character distribution list''
  1494. Xordered by increasing frequency of characters,
  1495. Xof {\myit /usr/dict/words\/} (the back-quotes execute the
  1496. X{\myit char\/} program that expands AZ and az to the full alphabet):
  1497. X\smallskip
  1498. X\I{\mytt (distrib `char AZ az` \les \ /usr/dict/words) \pip\ sort -n +1}
  1499. X\L
  1500. XFor each line of input the {\bb distrib} algorithm recomputes
  1501. Xthe string lenght of a search pattern specified, and attempts
  1502. Xto match the pattern at successive bytes of the input.
  1503. XThe line is then reexamined to find matches to the next search
  1504. Xpattern, then the next, until a search list is exhausted.
  1505. XA more efficient implementation of {\bb distrib}
  1506. Xcould --- at the expense of some
  1507. Xcode complexity --- dynamically allocate an array for storing the
  1508. Xlength of the patterns instead of repeatedly
  1509. Xcomputing them.
  1510. X
  1511. X\S{distrib.c PROGRAM TEXT}
  1512. X\listing{../iex/distrib.c}
  1513. X\eject
  1514. SHAR_EOF
  1515. $TOUCH -am 0601133090 iman/icount.tex &&
  1516. chmod 0644 iman/icount.tex ||
  1517. echo "restore of iman/icount.tex failed"
  1518. set `wc -c iman/icount.tex`;Wc_c=$1
  1519. if test "$Wc_c" != "5214"; then
  1520.     echo original size 5214, current size $Wc_c
  1521. fi
  1522. echo "End of part 5, continue with part 6"
  1523. exit 0
  1524. -- 
  1525.         Istvan Mohos
  1526.         ...uunet!pyrdc!pyrnj!hhb!istvan
  1527.         RACAL-REDAC/HHB 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
  1528. ======================================================================
  1529.