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

  1. From: istvan@hhb.UUCP (Istvan Mohos)
  2. Newsgroups: alt.sources
  3. Subject: Subject: ILIB Unix Toolkit in C
  4. Message-ID: <555@hhb.UUCP>
  5. Date: 8 Jun 90 21:00:39 GMT
  6.  
  7.  
  8. ---- Cut Here and unpack ----
  9. #!/bin/sh
  10. # This is part 09 of a multipart archive
  11. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  12.  then TOUCH=touch
  13.  else TOUCH=true
  14. fi
  15. # ============= iman/iround.tex ==============
  16. echo "x - extracting iman/iround.tex (Text)"
  17. sed 's/^X//' << 'SHAR_EOF' > iman/iround.tex &&
  18. X% XREF iround
  19. X
  20. X\def\name{IROUND}
  21. X\def\IT{{\bb iround()}}
  22. X
  23. X\S{NAME}
  24. X{\bb iround} --- round to a given digit of a decimal fraction
  25. X
  26. X\S{SYNOPSIS}
  27. X{\obeylines \bb
  28. Xint
  29. Xiround (start, end, maxfrac)
  30. Xchar *start;
  31. Xchar *end;
  32. Xint maxfrac;
  33. X}
  34. X
  35. X\S{DESCRIPTION}
  36. XGiven arbitrary text beginning with a {\myit decimal number\/}
  37. Xin a buffer delimited by {\myit start\/} and {\myit end\/},
  38. X\IT\ limits the ``fraction'' part of the number to {\myit maxfrac\/}
  39. Xdigits, {\myit rounding\/} from the {\myit maxfrac+1\/}th digit.
  40. XIf {\myit maxfrac\/} is negative, the action of \IT\ consists of
  41. Xthe suppression of ``trailing 0'' digits of the fractional part.
  42. X\L
  43. XThe rounded number remains in the buffer and is terminated with a
  44. XNUL byte.  When rounding up to a string of nines (for example
  45. X\dx{99.995}\ )
  46. Xthe nines ``bubble up'' and the leftmost \key{1} makes
  47. Xthe string one byte longer.  In this case
  48. Xthe string is right-shifted one byte, over the digit that was used up
  49. Xduring the rounding.  If this last fractional digit was the last
  50. Xbyte in the buffer immediately next to {\myit end\/}, an extra NUL
  51. Xbyte will not fit in the buffer past the number;
  52. X\IT\ assumes in these cases that the byte at
  53. X{\myit end\/} is a NUL byte.
  54. X\L
  55. XIf {\myit start\/} is the NULL pointer,
  56. X\IT\ returns the negative value of
  57. X{\myit sys\_nerr\/} in the standart ILIB manner.  Otherwise,
  58. Xthe parsing of the number begins at {\myit start\/}, advancing a
  59. Xpointer past any leading {\myit white spaces\/}, a single
  60. Xoptional \key{+} or \key{-} sign, past any
  61. X{\myit white spaces\/} following
  62. X\key{+} or \key{-}, to the first decimal digit (or to the
  63. Xdecimal point if the number has no leading digits).
  64. XThe decimal point is found next, and any
  65. Xtrailing digits immediately following it.
  66. X\L
  67. XIf a number was
  68. Xnot found, or if the number does not contain a decimal point, rounding
  69. Xwould be meaningless: the buffer is left untouched, and \IT\
  70. Xreturns zero.  If the number does prove to be
  71. Xa decimal fraction, \IT\ processes
  72. Xit and returns the length of the rounded number string. (The
  73. Xlength is computed by
  74. Xsubtracting the address of {\myit start\/} from the address of
  75. Xthe nulled-out byte past the terminating fractional digit
  76. Xor from the address of the nulled-out decimal point).
  77. X
  78. X\S{add PROGRAM EXAMPLE}
  79. XThe {\bb add} program sums decimal numbers appearing at the beginning
  80. Xof successive lines of input, and outputs the total.  {\bb add}
  81. Xis a filter accepting input from \stin\ or from a file.  The
  82. Xleading numbers of input lines are processed by the {\myit atof()\/}
  83. Xfunction of the math library: the program links with {\myit libm.a\/}
  84. Xas evidenced by the compilation script.
  85. XThe computed total is printed into an internal buffer, the
  86. Xbuffer is then passed to \IT\ for final formatting before output.
  87. XThe default {\myit maxfrac\/} argument passed to \IT\ is zero; the user
  88. Xcan override this by supplying a different value to the {\myit -r\/}
  89. X(``round flag'') command line option.
  90. X\L
  91. XThe command line example
  92. X\smallskip
  93. X\I{\mytt ls -l | leftrunc 23 | add}
  94. X\smallskip
  95. Xpasses a ``long listing'' of the directory contents to the
  96. X{\bb leftrunc} ILIB example program to strip off the left 23 bytes.
  97. XThe remaining columns of each line are then fed to {\bb add}, which
  98. Xsums the ``size fields'' of the listing, and outputs the size of the
  99. Xdirectory contents in bytes.
  100. X
  101. X\S{add.c PROGRAM TEXT}
  102. X\listing{../iex/add.c}
  103. X\eject
  104. SHAR_EOF
  105. $TOUCH -am 0608101990 iman/iround.tex &&
  106. chmod 0644 iman/iround.tex ||
  107. echo "restore of iman/iround.tex failed"
  108. set `wc -c iman/iround.tex`;Wc_c=$1
  109. if test "$Wc_c" != "3360"; then
  110.     echo original size 3360, current size $Wc_c
  111. fi
  112. # ============= iman/isearch.tex ==============
  113. echo "x - extracting iman/isearch.tex (Text)"
  114. sed 's/^X//' << 'SHAR_EOF' > iman/isearch.tex &&
  115. X% XREF inumsearch isearch ixsearch
  116. X
  117. X\def\name{ISEARCH}
  118. X\def\IT{{\bb isearch()}}
  119. X\def\ALT{{\bb ixsearch()}}
  120. X
  121. X\S{NAME}
  122. X{\bb isearch} --- binary string search in list of character pointers
  123. X
  124. X{\bb ixsearch} --- binary token search in list of character pointers
  125. X
  126. X{\bb inumsearch} --- binary (numeric) search in list of character pointers
  127. X
  128. X\S{SYNOPSIS}
  129. X{\obeylines \bb
  130. Xint
  131. Xisearch (comparee, wordlist, listcount)
  132. Xchar *comparee;
  133. Xchar *wordlist[];
  134. Xint listcount;
  135. X\L
  136. Xint
  137. Xinumsearch (comparee, wordlist, listcount)
  138. Xchar *comparee;
  139. Xchar *wordlist[];
  140. Xint listcount;
  141. X\L
  142. Xint
  143. Xixsearch (comparee, wordlist, listcount)
  144. Xchar *comparee;
  145. Xchar *wordlist[];
  146. Xint listcount;
  147. X}
  148. X
  149. X\S{DESCRIPTION}
  150. XILIB's {\myit isort()\/} functions
  151. Xsort an internal array of null
  152. Xterminated strings, by sorting a {\myit list of pointers\/} instead, to
  153. Xalphabetically or alphanumerically dereference the strings
  154. Xin the internal buffer.  (A list of the appropriate pointers
  155. Xcan be created
  156. Xin turn by calling {\myit ilist()\/} or its variants.)
  157. X\IT, \ALT, or {\bb inumsearch} all
  158. Xexpect the type of sorted pointer list provided by
  159. X{\myit isort()\/} or {\myit inumsort()\/} as their {\myit wordlist\/}
  160. Xargument, and interpret {\myit listcount\/} as the count of the
  161. Xpointers in {\myit wordlist\/}.
  162. X\L
  163. XThe \IT\ functions then
  164. Xfind the {\myit wordlist\/} pointer that points to a string that is
  165. Xidentical to  the first argument {\myit comparee\/},
  166. Xand return the {\myit wordlist\/} index of this pointer
  167. X(zero through one less than {\myit listcount\/})
  168. Xor -1 if {\myit comparee\/} was not found.  The functions
  169. Xalso return -1 if
  170. X{\myit listcount\/} is less than one, but do not consider this an error.
  171. XThe status of {\myit wordlist\/} is not verified.
  172. X{\myit ierflag\/} is set and {\myit -sys\_nerr\/} is returned via
  173. X{\myit ierror()\/} if {\myit comparee\/} is the NULL pointer or
  174. Xhas no length.
  175. X\L
  176. X\IT\ uses {\myit strncmp()\/} for the comparisons, attempting to find
  177. Xa string in {\myit wordlist\/} that begins with a substring identical
  178. Xto {\myit comparee\/}.
  179. X\L
  180. X\ALT\ uses {\myit strcmp()\/} for
  181. Xthe comparisons.  This means that the {\myit wordlist\/} string must
  182. Xmatch {\myit comparee\/} exactly, longer
  183. Xstrings in  {\myit wordlist\/} that begin with the
  184. X{\myit comparee\/} substring are rejected.
  185. X\L
  186. X{\bb inumsearch()\/} uses the ILIB {\myit inumstrcmp()\/} for
  187. Xthe comparisons.
  188. XThe individual strings of {\myit wordlist\/}, and {\myit comparee\/}
  189. Xare matched against each other as complete strings,
  190. Xbut with decimal digit substrings
  191. Xcollapsed to integer values. The word \dx{test7}\ for example, will
  192. Xexactly match \dx{test007}.
  193. X
  194. X\S{SEE ALSO}
  195. X{\myit ilist, isort, inumstrcmp.}
  196. X
  197. X\S{area PROGRAM EXAMPLE}
  198. XSince the process overhead of
  199. Xbinary sort and search routines tends to
  200. Xdiminish as their effectiveness increases
  201. Xgeometrically with the expansion of the size of the data, \IT\ or
  202. X{\bb isort()} do not easily
  203. Xlend themselves to inclusion in short programs.  The {\bb area}
  204. Xprogram, outputting the appropriate area code for a town or state
  205. Xspecified on the command line, bypasses the need to print
  206. Xlenghty lists in this manual, by simply assuming that the
  207. Xdata base does in
  208. Xfact exist, under the normal ASCII file
  209. X{\myit \dol HOME/.area\/}.  The data
  210. Xis expected to consist of {\myit newline\/} terminated records
  211. Xwith fields {\myit TOWN\/} and {\myit AREACODE\/}, for example
  212. X\smallskip
  213. X\I{\mytt Fresno 209}
  214. X\I{\mytt Alaska 907}
  215. X\I{\mytt Manhattan 212}
  216. X\smallskip
  217. XThere must be at least one record in the file.
  218. XLines need not be sorted because {\bb area} does its own sort;
  219. Xhowever if the data grows large, time could be saved by sorting the
  220. Xdata file and removing the {\myit isort()\/} call from the program
  221. Xlisting.
  222. X\L
  223. X{\bb area} calls \IT\ to find the command-given
  224. Xgeographical location in the data base, and very simply, prints
  225. Xthe line to \sterr.  Similar utilities can be cloned,
  226. Xto retrieve {\myit zip codes\/},
  227. Xtelephone numbers, birth days, etc.,
  228. Xjust by adding
  229. Xaliases to the command name and providing alternate data files
  230. X{\myit \dol HOME/.zip, \dol HOME/.phone\/}, and so on.  The prototype clone
  231. X{\bb now} already {\myit \#include\/}d in the {\bb area} text, adds a
  232. Xpositive or negative offset (in hours) to
  233. Xthe current ``Greenwich Mean Time'', and prints the current time
  234. Xin various parts of the world.  If the {\myit \dol HOME/.now\/}
  235. Xdata base contained the record
  236. X\smallskip
  237. X\I{\mytt New York -4}
  238. X\smallskip
  239. Xthe ``{\mytt now New York}'' command would display the current New York
  240. Xtime, formatted as \dx{hh:mm:ss}.
  241. X
  242. X\S{area.c PROGRAM TEXT}
  243. X\listing{../iex/area.c}
  244. X\eject
  245. SHAR_EOF
  246. $TOUCH -am 0608102790 iman/isearch.tex &&
  247. chmod 0644 iman/isearch.tex ||
  248. echo "restore of iman/isearch.tex failed"
  249. set `wc -c iman/isearch.tex`;Wc_c=$1
  250. if test "$Wc_c" != "4548"; then
  251.     echo original size 4548, current size $Wc_c
  252. fi
  253. # ============= iman/isort.tex ==============
  254. echo "x - extracting iman/isort.tex (Text)"
  255. sed 's/^X//' << 'SHAR_EOF' > iman/isort.tex &&
  256. X% XREF isort inumsort
  257. X
  258. X\def\name{ISORT}
  259. X\def\IT{{\bb isort()}}
  260. X
  261. X\S{NAME}
  262. X{\bb isort} --- sort list of character pointers to alphabetic order
  263. X
  264. X{\bb inumsort} --- sort list of character pointers to alphanumeric order
  265. X
  266. X\S{SYNOPSIS}
  267. X{\obeylines \bb
  268. Xvoid
  269. Xisort (ptr, itemcount)
  270. Xchar *ptr[];
  271. Xint itemcount;
  272. X\L
  273. Xvoid
  274. Xinumsort (ptr, itemcount)
  275. Xchar *ptr[];
  276. Xint itemcount;
  277. X}
  278. X
  279. X\S{DESCRIPTION}
  280. XBoth \IT\ and {\bb inumsort()\/} perform a binary sort on a
  281. Xlist of character pointers pointing to null terminated strings
  282. X(such as produced from ``straight'' text  by the {\myit ilist()\/}
  283. Xfunctions).
  284. X\L
  285. XPrevious to the call to
  286. X\IT\ or {\bb inumsort()\/}, pointers of the array
  287. Xbeginning at  {\myit ptr\/}, are dereferencing various
  288. Xstrings in no particular order, successive pointers typically
  289. Xpointing to successive lines of the text to be sorted.
  290. XOn return from the call, the pointers will have been reorganized
  291. Xby \IT\ or {\bb inumsort()\/}, so
  292. Xthat the first pointer of the list ({\myit ptr[0]\/}) points to a
  293. Xline which
  294. Xalphabetically precedes all other lines of the text; the
  295. Xsecond pointer ({\myit ptr[1]\/}) points to the string with the next
  296. Xlowest value, and so on.
  297. X\L
  298. XThe {\bb inumsort()\/} function handles digit substrings embedded
  299. Xin text lines as decimal integers,
  300. Xsorting the pointer list to
  301. Xalphanumeric order rather than to alphabetic order.
  302. XLeading zeros of digit strings are ignored in the
  303. Xnumerical comparison; if the digit strings are otherwise identical
  304. Xthey are seen as a perfect match by {\bb inumsort()\/}.
  305. XIn a sorted list for example, either
  306. X``Cygnus N031'' or ``Cygnus N31'' may precede the other.
  307. X\L
  308. XBoth functions interpret
  309. X{\myit itemcount\/} as the number of pointers in the array (the
  310. Xnumber of lines to be sorted).  If
  311. X{\myit itemcount\/} is one or zero, no sorting is done.
  312. X
  313. X\S{SEE ALSO}
  314. X{\myit ilist, isearch, ifamily\/}.
  315. X
  316. X\S{PROGRAM EXAMPLE}
  317. XThe {\bb group} program listed following the description
  318. Xof {\myit ifamily()}
  319. Xuses {\bb inumsort} to order its lines of input.
  320. X\eject
  321. SHAR_EOF
  322. $TOUCH -am 0531091090 iman/isort.tex &&
  323. chmod 0644 iman/isort.tex ||
  324. echo "restore of iman/isort.tex failed"
  325. set `wc -c iman/isort.tex`;Wc_c=$1
  326. if test "$Wc_c" != "1998"; then
  327.     echo original size 1998, current size $Wc_c
  328. fi
  329. # ============= iman/istripcom.tex ==============
  330. echo "x - extracting iman/istripcom.tex (Text)"
  331. sed 's/^X//' << 'SHAR_EOF' > iman/istripcom.tex &&
  332. X% XREF istripcom istripstr istripdq istripsq
  333. X
  334. X\def\name{ISTRIPCOM}
  335. X\def\IT{{\bb istripcom()}}
  336. X
  337. X\S{NAME}
  338. X{\bb istripcom} --- ``white out'' comments in buffer with spaces
  339. X
  340. X{\bb istripstr} --- ``white out'' strings  in buffer with spaces
  341. X
  342. X{\bb istripdq} --- ``white out'' double quotes in buffer with spaces
  343. X
  344. X{\bb istripsq} --- ``white out'' single quotes in buffer with spaces
  345. X
  346. X\S{SYNOPSIS}
  347. X{\obeylines \bb
  348. Xint
  349. Xistripcom (start, end, lcom, rcom)
  350. Xchar *start;
  351. Xchar *end;
  352. Xchar *lcom;
  353. Xchar *rcom;
  354. X\L
  355. Xint
  356. Xistripstr (start, end, str)
  357. Xchar *start;
  358. Xchar *end;
  359. Xchar *str;
  360. X\L
  361. Xint
  362. Xistripdq (start, end)
  363. Xchar *start;
  364. Xchar *end;
  365. X\L
  366. Xint
  367. Xistripsq (start, end)
  368. Xchar *start;
  369. Xchar *end;
  370. X}
  371. X
  372. X\S{DESCRIPTION}
  373. XGiven a buffer at {\myit start\/} and ending
  374. Xone byte before {\myit end\/}, \IT\ converts {\myit comments\/}
  375. Xoccurring in the buffer ---
  376. Xdelimited by {\myit lcom\/} and {\myit rcom\/} ---
  377. Xto spaces.  {\bb istripstr()} converts
  378. Xoccurrences of {\myit str\/} to spaces.  {\bb istripdq()}
  379. Xconverts text surrounded by
  380. Xdouble quotes \key{"}, to spaces.  {\bb istripsq()}
  381. Xconverts text surrounded by single quotes \key{'}, to spaces.
  382. XAll four functions return the count of the erased strings.
  383. X{\myit ierflag\/} is set and negative {\myit sys\_nerr\/} is returned
  384. Xif {\myit lcom\/} or {\myit rcom\/} or {\myit str\/} have no length.
  385. X\L
  386. XThe \IT\ function also erases the comment delimiters
  387. Xthemselves, except
  388. X{\myit rcom\/} when it is a {\myit newline\/}.  \IT\
  389. Xconsiders it an error to specify
  390. X{\myit newline\/} \dx{\mytt"\bsl n"}\ for {\myit lcom\/}.
  391. XIf {\myit rcom\/} is not
  392. X\dx{\mytt"\bsl n"}, and if {\myit lcom\/} and {\myit rcom\/} differ,
  393. X\IT\ calls itself recursively to erase nested
  394. Xcomments (returning the count of all
  395. Xcomment delimiter pairs encountered); except that in the case of the
  396. XC comment delimiters \twokey{/*}\ and \twokey{*/}
  397. Xthe function is not recursive and ignores escaped delimiters or
  398. Xdelimiters within quotes (within character or string constants).
  399. X\L
  400. XIf more than one of these functions are to transform C text,
  401. Xthe recommended succession of calls
  402. Xis \IT, {\bb istripdq()}, {\bb istripsq()}.  Calling \IT\
  403. Xas the first function of the sequence
  404. Xensures that single or double quotes embedded in comment
  405. Xtext don't result in the ``runaway blanking'' of text beyond the
  406. Xclosing comment delimiter.  For example, if 
  407. X{\bb istripdq()} processed C text with the
  408. X\smallskip
  409. X\I{\mytt /* talking about the " character */}
  410. X\smallskip
  411. Xcomment embedded, it would start blanking characters at the
  412. Xdouble quote in the comment, and would overrun the closing
  413. Xcomment delimiter in its search for the closing quote.
  414. XCalling {\bb istripdq()} before
  415. X{\bb istripsq()} ensures that {\myit apostrophes\/}
  416. Xembedded in text strings don't result in similar damage, for
  417. Xexample when parsing
  418. X\smallskip
  419. X\I{\mytt "can't open file \%s\bsl n"}
  420. X\smallskip
  421. X{\bb istripdq()} and {\bb istripsq()} are both ``smart enough''
  422. Xto bypass escaped quotes:
  423. X{\bb istripdq()} does not start blanking in \dx{\mytt '"'}, and
  424. X{\bb istripsq()} does not stop blanking at the second tick of
  425. X\dx{\mytt'\bsl''}.
  426. X
  427. X\S{cweed PROGRAM EXAMPLE}
  428. XWhen comparing a changed version of
  429. Xsource code against the original, there are times when no amount of
  430. Xformatting or {\myit context-diff\/}ing seem to winnow out
  431. Xstylistic differences from changes that ``matter'' to the
  432. XC compiler.  The {\bb cweed} program strips out non-essential text and
  433. Xputs a temporary copy of the input to \stout\ that contains
  434. Xonly ``meaningful differences'' when
  435. Xcontrasted against similarly ``weeded'' output from another file.
  436. X\L
  437. XText is input from {\myit file\/} if a filename is given on the
  438. Xcommand line, otherwise the program filters \stin.
  439. XThe source is read to an internal buffer.  C comments and comment
  440. Xdelimiters are overwritten in the buffer with spaces.
  441. XTo resolve the stylistic differences between programs that append
  442. Xa left curly brace \key{\lcu} in line with
  443. Xa logical test, and programs
  444. Xthat put the
  445. Xleft curly brace in the next line below,
  446. X{\bb cweed} implements the unilateral solution of overwriting
  447. X{\myit newline\/} characters between left curly braces
  448. Xand the previous token with spaces in the buffer.
  449. X\L
  450. X{\bb cweed} then parses the buffer line by line,
  451. Xextracting and printing lexical C tokens.
  452. XIf successive tokens in a line are both alphanumeric
  453. X(the alphanumeric set in C also includes
  454. Xthe underscore and dollar
  455. Xcharacters), or if successive tokens are both non-alphanumeric,
  456. Xa space is printed as a separator.
  457. XOther combinations are output
  458. Xwithout separators.  Empty lines (not containing tokens) are
  459. Xskipped.
  460. XThe {\myit q\/} program listed in the INTRO section can be used to
  461. Xcompare similar files processed by {\bb cweed}:
  462. X\smallskip
  463. X\I{\mytt diff `q cweed file1`\ \ `q cweed file2`}
  464. X\smallskip
  465. Xcompares the lines produced from
  466. X{\myit file1\/} and {\myit file2\/}.
  467. XThis sequence proves quite successful in {\myit diff\/}ing
  468. XC source, and probably would deserve upgrading to
  469. Xa one-liner shell script ({\myit cdiff\/}):
  470. X\dx{\mytt /bin/diff\ `q\ cweed\ \$1`\ `q\ cweed\ \$2`}.
  471. XIn this case, the above command would become:
  472. X\smallskip
  473. X\I{\mytt cdiff file1 file2}
  474. X
  475. X\S{cweed.c PROGRAM TEXT}
  476. X\listing{../iex/cweed.c}
  477. X\eject
  478. SHAR_EOF
  479. $TOUCH -am 0608102990 iman/istripcom.tex &&
  480. chmod 0644 iman/istripcom.tex ||
  481. echo "restore of iman/istripcom.tex failed"
  482. set `wc -c iman/istripcom.tex`;Wc_c=$1
  483. if test "$Wc_c" != "5166"; then
  484.     echo original size 5166, current size $Wc_c
  485. fi
  486. # ============= iman/iswap.tex ==============
  487. echo "x - extracting iman/iswap.tex (Text)"
  488. sed 's/^X//' << 'SHAR_EOF' > iman/iswap.tex &&
  489. X% XREF iswap ixswap
  490. X
  491. X\def\name{ISWAP}
  492. X\def\IT{{\bb iswap()}}
  493. X\def\ALT{{\bb ixswap()}}
  494. X
  495. X\S{NAME}
  496. X{\bb iswap} --- change one string to another everywhere in a buffer
  497. X
  498. X{\bb ixswap} --- change alphanumeric token to another everywhere in a buffer
  499. X
  500. X\S{SYNOPSIS}
  501. X{\obeylines \bb
  502. Xint
  503. Xiswap (start, end, from, to)
  504. Xchar *start;
  505. Xchar *end;
  506. Xchar *from;
  507. Xchar *to;
  508. X\L
  509. Xint
  510. Xixswap (start, end, from, to)
  511. Xchar *start;
  512. Xchar *end;
  513. Xchar *from;
  514. Xchar *to;
  515. X}
  516. X
  517. X\S{DESCRIPTION}
  518. XBoth \IT\ and \ALT\ search the buffer from {\myit start\/} to
  519. X{\myit end\/} for non-overlapping occurrences of the {\myit from\/}
  520. Xstring.  Whenever a match is found, the {\myit to\/} string
  521. Xoverwrites the {\myit from\/} string (beginning at the leftmost byte of
  522. Xthe {\myit from\/} string), the parser is moved immediately past
  523. Xthe overlaid {\myit to\/} string; and the search continues from this
  524. Xpoint on.
  525. X\L
  526. XThe {\myit end\/} of the buffer is limiting
  527. Xonly with respect to searching, in that bytes at or beyond
  528. X{\myit end\/} will not be dereferenced during the pattern match.
  529. XA {\myit to\/} string may be longer than the {\myit from\/} string
  530. Xit is to replace, in which case bytes beyond the {\myit from\/}
  531. Xpattern in the buffer will get overwritten even if this means exceeding
  532. Xthe right boundary.
  533. XIt is the
  534. Xcaller's responsibility in such cases,
  535. Xto provide adequate buffer space past {\myit end\/}.
  536. X\L
  537. XThe difference between
  538. X\IT\ and \ALT\ is that \ALT\ limits {\myit from\/} strings to
  539. Xalphanumeric words or single printing characters (calling
  540. X{\myit ialntok()\/} for extracting tokens), and recognizes
  541. Xmatching {\myit from\/} patterns in the buffer only if
  542. Xthe buffer pattern is the same length word
  543. X(delimited by white spaces or by
  544. Xnon-alphanumeric characters) as the passed {\myit from\/} pattern is.
  545. XIn contrast the {\myit from\/} string passed to \IT\
  546. Xmay contain white spaces, and buffer matches are recognized even if
  547. Xprinting character-aggregates of the buffer
  548. Xembed the {\myit from\/} string.
  549. X\L
  550. XEither functions return the count of overlays, or
  551. Xcall {\myit ierror()\/} if
  552. Xthe source or target pattern is NULL or has no length.
  553. X
  554. X\eject
  555. SHAR_EOF
  556. $TOUCH -am 0531091590 iman/iswap.tex &&
  557. chmod 0644 iman/iswap.tex ||
  558. echo "restore of iman/iswap.tex failed"
  559. set `wc -c iman/iswap.tex`;Wc_c=$1
  560. if test "$Wc_c" != "2102"; then
  561.     echo original size 2102, current size $Wc_c
  562. fi
  563. # ============= iman/itok.tex ==============
  564. echo "x - extracting iman/itok.tex (Text)"
  565. sed 's/^X//' << 'SHAR_EOF' > iman/itok.tex &&
  566. X% XREF itok
  567. X
  568. X\def\name{ITOK}
  569. X\def\IT{{\bb itok()}}
  570. X
  571. X\S{NAME}
  572. X{\bb itok} --- dynamic tokenizer
  573. X
  574. X\S{SYNOPSIS}
  575. X\settabs\+{\bb mdefine INITOKRRR} &0000&\cr
  576. X\+{\bb\#define INITOKF}&\hfill{\bb 1}&\kern 2em{\mytt/* setup forward parsing */}\cr
  577. X\+{\bb\#define INITOKR}&\hfill{\bb --1}&\kern 2em{\mytt/* setup reverse parsing */}\cr
  578. X\+{\bb\#define ITOKF  }&\hfill{\bb 2}&\kern 2em{\mytt/* forward parse */}\cr
  579. X\+{\bb\#define ITOKR  }&\hfill{\bb --2}&\kern 2em{\mytt/* reverse parse */}\cr
  580. X\L
  581. X{\obeylines \bb
  582. Xint
  583. Xitok (context, start, end, result)
  584. Xint context;
  585. Xchar *start;
  586. Xchar *end;
  587. Xchar **result;
  588. X}
  589. X
  590. X\S{DESCRIPTION}
  591. XIn many ways the true ``Rube Goldberg'' of ILIB, the opacity and
  592. Xless-than-intuitive behavior
  593. Xof \IT\ are only partially offset by the plain syntax
  594. Xfor calling this function in a loop.
  595. X\IT\ differentiates between four types of calls, decoding
  596. Xthe type at every call
  597. Xfrom the {\myit context\/} value passed as the first argument.
  598. X\L
  599. XThe {\myit INITOKF\/} value of {\myit context\/}
  600. Xinstructs \IT\ to initialize its state machine
  601. Xand get ready for retrieving tokens {\myit F\/}orward (that is,
  602. Xleft-to-right) in the buffer passed in along
  603. X{\myit INITOKF\/}
  604. Xvia its
  605. X{\myit start, end\/} boundaries.
  606. XIf the {\myit end\/} pointer is NULL, \IT\ finds the buffer end on
  607. Xits own, by looking ahead until the terminal NUL byte.
  608. XIn either case, \IT\ saves the
  609. Xbuffer boundaries, ignores the {\myit result\/} parameter,
  610. Xand moves its internal text marker to the beginning of
  611. Xthe buffer (to {\myit start\/}).  \IT\ does not find a token during
  612. Xthis call, and returns the byte size of the buffer.
  613. X\L
  614. XSimilarly, {\myit INITOKR\/} instructs \IT\ to
  615. Xget ready for retrieving tokens in {\myit R\/}everse;
  616. Xbackward from the byte before {\myit end\/}, proceeding toward
  617. X{\myit start\/}.  At such a call, \IT\ saves the
  618. Xbuffer boundaries, and moves its internal text marker to the
  619. Xrightmost available byte of the buffer.
  620. XAgain no token is found, and the size of the buffer is returned.
  621. X\L
  622. XAt a call with {\myit context\/} set to {\myit ITOKF\/}, \IT\
  623. Xfinds the next token in the buffer (from the text marker, skipping
  624. Xfirst any delimiter bytes that can not be a part of the token),
  625. Xand then advances its text marker to point to the byte immediately
  626. Xto the right of the last byte of the new token.
  627. XSince \IT\ has
  628. Xsaved the buffer boundaries from an earlier initializing call, the
  629. X{\myit start, end\/} parameters are now reused and point to the
  630. Xfirst byte and to the first ``off limit'' byte of a
  631. X{\myit string of delimiters\/}.  Each byte of this string
  632. X(throughout the full ASCII range --- including NUL)
  633. Xis used for a possible delimiter, allowing \IT\ to recognize
  634. Xthe beginning and the
  635. Xend of the currently read token.
  636. XThat is, successive bytes of the buffer that do not match any of the
  637. Xdelimiter characters, are identified as a single token.
  638. XThe caller may take the shortcut of passing the valid {\myit start\/}
  639. Xof the delimiter string, and passing the NULL pointer as
  640. X{\myit end\/}, in which case \IT\ will assume that the
  641. Xdelimiters form a null terminated string, and will not include the
  642. Xfinal NUL in the character set of the delimiters.
  643. X\L
  644. XEven though \IT\ moves
  645. Xits text marker to the first delimiter byte to the right of the newly
  646. Xfound token in preparation for the next call, \IT\ sets {\myit result\/}
  647. Xto point to the beginning (first byte) of the recognized token,
  648. Xand returns the length (text marker minus the beginning)
  649. Xof the token.  {\myit result\/} should be a {\myit (char *)\/} passed
  650. Xby address.
  651. X\L
  652. XIf {\myit context\/} is set to {\myit ITOKR\/}, \IT\
  653. Xfinds the next token in the buffer to the 
  654. X{\myit left\/} of the text marker,
  655. Xand then advances its text marker to point to the byte immediately
  656. X{\myit before the first\/} byte of the new token, in preparation for
  657. Xthe next tokenizing call.
  658. XAgain \IT\ uses individual characters of the delimiter string bounded by
  659. X{\myit start, end\/} to extract the token from amidst
  660. Xthe ``chaff'' of delimiters.
  661. X\IT\ then sets {\myit result\/}
  662. Xto point to the beginning (still the leftmost byte) of the recognized
  663. Xtoken, and returns the length of the token.
  664. X\L
  665. X\IT\ is flexible, and operates without disturbing the buffer text
  666. Xor the delimiter string in any way.
  667. XThe parsing direction or the composition of the delimiter
  668. Xstring may be changed as often as every call. 
  669. XIf the {\myit start\/} boundary is reached during reverse parsing,
  670. Xor if the byte before {\myit end\/} is reached during forward
  671. Xparsing, parsing stops whether the boundary byte
  672. Xwas a delimiter or a non-delimiter.  If the byte
  673. Xwas a non-delimiter, the returned size includes the last byte.
  674. XIf no token could be isolated during a call,
  675. X\IT\ sets {\myit result\/} to NULL.
  676. X
  677. X\S{pathfiles PROGRAM EXAMPLE}
  678. XThe {\bb pathfiles} program lists the discreet directories of the
  679. Xuser's {\myit PATH\/} variable, one at a time, to a temporary file;
  680. Xand then prints the full path of those listed files whose access mode
  681. Xsatisfies the user's requirements.  The user specifies the
  682. Xrequired access mode by invoking {\bb pathfiles} by one of its
  683. X{\myit alias\/} names
  684. X{\bb fpath} (requiring only that the {\myit F\/}ile is present),
  685. X{\bb rpath} (requiring that a given file be {\myit R\/}eadable),
  686. X{\bb wpath} (requiring that a given file be {\myit W\/}ritable), and
  687. X{\bb xpath} (requiring that a given file be e{\myit X\/}ecutable).
  688. XThe original name of the executable program, {\bb pathfiles\/},
  689. Xserves to trigger printing the ``usage'' message to \stout.
  690. X\L
  691. XThe directory list of \dol{\myit PATH\/} can be bypassed by
  692. Xgiving an alternate list of directories on the command line:
  693. X\smallskip
  694. X\I{\mytt wpath /bin /etc /usr/local .}
  695. X\smallskip
  696. XThe above command produces the full pathname of those
  697. Xfiles in the four specified directories
  698. Xthat are writable by the user.
  699. X
  700. X\S{pathfiles.c PROGRAM TEXT}
  701. X\listing{../iex/pathfiles.c}
  702. X
  703. X\S{fcat PROGRAM EXAMPLE}
  704. XA more interesting but very densely coded example is the {\bb fcat}
  705. Xprogram, evaluating input a line at a time, and printing selected
  706. Xfields of the input to \stout.  {\bb fcat} produces results similar to
  707. Xthe System~V {\myit cut\/} command, but with a simplified
  708. Xcommand line syntax. {\bb fcat} is a filter, reading either
  709. X\stin\ or a file given as the optional last command line parameter.
  710. XThe mandatory
  711. X{\myit fieldmask\/}
  712. Xargument following the command on the command line
  713. Xis a word made of the character set
  714. X\dx{123456789abcdefg}\ exclusively.  Each byte of this character set
  715. Xrepresents the index of successive tokens in the lines of input,
  716. Xcounting from left to right, from one to sixteen.
  717. X\key{2} for example stands for
  718. Xthe second token of a line, \key{f} stands for the fifteenth.
  719. X\L
  720. XThe {\myit fieldmask\/} may contain a valid mask character
  721. Xmore than once, and in any order.  When the input line is scanned,
  722. X{\bb fcat} sets up separate pointers to the first sixteen tokens of
  723. Xthe line (if the line contains that many tokens), and then
  724. Xoutputs a space-separated list of the appropriate tokens in the
  725. Xorder dictated by the fieldmask characters.  The token list is
  726. Xterminated by a {\myit newline\/} character; the process then
  727. Xrepeats with the next line of input.  If the line has fewer tokens
  728. Xthan the index specified by a mask byte, the process simply skips
  729. Xthe oversize mask byte for the current line.  Tokenless input lines
  730. Xproduce a single {\myit newline\/}.
  731. X\L
  732. XThe {\bb fcat} process reinitializes the \IT\ tokenizer
  733. Xat every input line, and constructs its token lists by repeated
  734. Xoperational calls to \IT.  Nominally the
  735. XASCII SPACE and TAB
  736. Xcharacters are passed as token delimiters; the NL ({\myit newline\/})
  737. Xterminators of the input are automatically eliminated
  738. Xas a side-effect of using {\myit gets()\/} instead of {\myit fgets()\/}
  739. X(however dangerous it may be to bypass the buffer overrun test
  740. Xavailable to {\myit fgets()\/} clients only).
  741. XAn alternate set of
  742. Xcharacters can be specified with the {\myit --d\/} command
  743. Xline option.  After any operational
  744. Xcalls to \IT, {\bb fcat} null-terminates
  745. Xthe newly recognized token in the line buffer,
  746. Xchanging the original SPACE or TAB delimiter byte to NUL.
  747. XAt the next call \IT\ is expected to find the beginning of the
  748. Xfollowing token by skipping any delimiter bytes, but instead,
  749. X\IT\ finds
  750. Xthat its internal marker is now pointing to a non-delimiter value (NUL);
  751. Xand would happily report a new token beginning at this point.
  752. XBecause of this, {\bb fcat} also includes NUL
  753. Xin the delimiter character set.
  754. X\L
  755. XThe ``solo minus'' option reverses the direction of the
  756. Xfield numbers, making field~1 the last field of a line.  To \IT's
  757. Xcredit, the reversal is implemented by just passing it
  758. Xthe REVERSE flag instead of FORWARD.
  759. XThe reversed field mask is useful when the field-count of
  760. Xprocessed text lines is variable.  For example, leaf nodes of paths
  761. Xproduced by {\myit find\/} could be made the leading token with the
  762. Xfollowing command:
  763. X\smallskip
  764. X\I{\mytt find\ \ .\ -print\ |\ fcat\ 1gfedcba98765432\ -\ -d/}
  765. X\smallskip
  766. XIn the command,
  767. Xthe output of {\myit find\/} is redirected to {\bb fcat}, providing
  768. Xinput lines of full pathnames whose components are separated by
  769. X\key{/}.  The delimiter list of the command is therefore a single
  770. Xslash character.  The solo minus option reverses field numbering to
  771. Xstart from the end, so the first character \key{1} of the fieldmask
  772. Xspecifies that the last field of each line is to be output first.
  773. XThe remaining bytes of the mask are in a straight decremental order,
  774. Xforcing the reprint of all other fields of the input in their
  775. Xoriginal sequence.
  776. X
  777. X\S{fcat.c PROGRAM TEXT}
  778. X\listing{../iex/fcat.c}
  779. X\eject
  780. SHAR_EOF
  781. $TOUCH -am 0608102390 iman/itok.tex &&
  782. chmod 0644 iman/itok.tex ||
  783. echo "restore of iman/itok.tex failed"
  784. set `wc -c iman/itok.tex`;Wc_c=$1
  785. if test "$Wc_c" != "9555"; then
  786.     echo original size 9555, current size $Wc_c
  787. fi
  788. # ============= iman/iuniq.tex ==============
  789. echo "x - extracting iman/iuniq.tex (Text)"
  790. sed 's/^X//' << 'SHAR_EOF' > iman/iuniq.tex &&
  791. X% XREF iuniq
  792. X
  793. X\def\name{IUNIQ}
  794. X\def\IT{{\bb iuniq()}}
  795. X
  796. X\S{NAME}
  797. X{\bb iuniq} --- return TRUE if parameter is passed for the first time
  798. X
  799. X\S{SYNOPSIS}
  800. X{\obeylines \bb
  801. Xint
  802. Xiuniq (item)
  803. Xint item;
  804. X}
  805. X
  806. X\S{DESCRIPTION}
  807. X\IT\ is a dynamic function, expecting a setup call, a number of
  808. Xoperational calls, and a terminating call.
  809. X\L
  810. XFrom an operational call \IT\ returns TRUE if it has not
  811. Xyet seen the current value of {\myit item\/} at a previous call
  812. Xwithin the life of its state machine.
  813. X\IT\ returns FALSE otherwise.
  814. X(If the caller needs to count how many times a parameter
  815. Xhas been passed, he should use {\myit icount()\/} instead.)
  816. X\L
  817. XThe setup call should pass a value that is one more than the
  818. Xlargest {\myit item\/} that may
  819. Xbe encountered during an operational call.  This naturally corresponds
  820. Xto defining an array by its size, and indexing into it by lesser values.
  821. XThe smallest {\myit item\/} value of an operational call is 0.
  822. XAs an example, the caller using a hundred-element
  823. Xarray of items would initialize \IT\ with an {\myit item\/} value
  824. Xof 100, and
  825. Xcall \IT\ with values between 0 and 99 during normal operation.
  826. X\L
  827. XTo reset
  828. Xthe state machine, and to free dynamically allocated memory,
  829. Xa negative number is passed during the terminal call.
  830. X
  831. X\eject
  832. SHAR_EOF
  833. $TOUCH -am 0509104190 iman/iuniq.tex &&
  834. chmod 0644 iman/iuniq.tex ||
  835. echo "restore of iman/iuniq.tex failed"
  836. set `wc -c iman/iuniq.tex`;Wc_c=$1
  837. if test "$Wc_c" != "1256"; then
  838.     echo original size 1256, current size $Wc_c
  839. fi
  840. # ============= iman/iwhich.tex ==============
  841. echo "x - extracting iman/iwhich.tex (Text)"
  842. sed 's/^X//' << 'SHAR_EOF' > iman/iwhich.tex &&
  843. X% XREF iwhich
  844. X
  845. X\def\name{IWHICH}
  846. X\def\IT{{\bb iwhich()}}
  847. X
  848. X\S{NAME}
  849. X{\bb iwhich} --- locate a file
  850. X
  851. X\S{SYNOPSIS}
  852. X{\obeylines \bb
  853. Xchar *
  854. Xiwhich (item, perm)
  855. Xchar *item;
  856. Xint perm;
  857. X}
  858. X
  859. X\S{DESCRIPTION}
  860. X\IT\ searches the directory components of the caller's {\myit PATH\/}
  861. Xenvironment variable for acces to the file passed as {\myit item\/},
  862. Xand returns the full pathname of the first file that has
  863. Xpermissions coinciding with
  864. X{\myit perm\/}.
  865. XIf the specified {\myit item\/} forms a {\myit path\/} (i.e. contains
  866. Xone or more \key{/} characters), {\myit PATH\/} is not searched;
  867. Xinstead
  868. X\IT\ verifies that the literal {\myit item\/}  string is a file
  869. Xwith access mode equal or better than {\myit perm\/}.
  870. X\L
  871. XStandard values of {\myit perm\/} are defined in {\myit stdio.h\/}
  872. Xunder System~V, and are defined in {\myit ilib.h\/} for running
  873. Xunder the Berkeley versions:
  874. X\smallskip
  875. X\I{{\mytt F\_OK    0}  file exists}
  876. X\I{{\mytt X\_OK    1}  executable by caller}
  877. X\I{{\mytt W\_OK    2}  writable by caller}
  878. X\I{{\mytt R\_OK    4}  readable by caller}
  879. X\smallskip
  880. X
  881. XIf the file does not exist, or if the the permission of the file
  882. Xdoes not meet the value specified by {\myit perm\/}, \IT\
  883. Xreturns the NULL pointer.
  884. X\IT\ calls {\myit ierror()\/} to set {\myit ierflag\/} and to
  885. Xinstall the appropriate error message in {\myit ierbuf\/} if
  886. Xthe NULL pointer is passed as {\myit item\/}, or if {\myit item\/}
  887. Xhas no length.
  888. X
  889. X\S{which PROGRAM EXAMPLE}
  890. XThis program emulates the standard Berkeley command of the same name,
  891. Xbut unlike the Berkeley version, it does not concern itself with
  892. Xidentifying additional command aliases implemented by the
  893. XBerkeley {\myit alias\/} mechanism.  Perhaps because of this neglect,
  894. Xthe ILIB version is significantly faster than its BSD counterpart.
  895. X{\bb which} also implements a number of options that may be of use:
  896. Xfollowing a {\myit --m\/} flag on the command line an additional
  897. X\key{f},
  898. X\key{r}, or
  899. X\key{w}\ character specifies that the mere presence of a file,
  900. Xor the read or write permission of the file is being tested for,
  901. Xrather than the default ``execute'' permission.  The null option
  902. X(the \key{-} sign by itself) on the command line indicates that
  903. Xinstead of evaluating files listed on the command line, file names
  904. Xwill be provided interactively, in a loop.
  905. X
  906. X\S{which.c PROGRAM TEXT}
  907. X\listing{../iex/which.c}
  908. X\eject
  909. SHAR_EOF
  910. $TOUCH -am 0608103790 iman/iwhich.tex &&
  911. chmod 0644 iman/iwhich.tex ||
  912. echo "restore of iman/iwhich.tex failed"
  913. set `wc -c iman/iwhich.tex`;Wc_c=$1
  914. if test "$Wc_c" != "2328"; then
  915.     echo original size 2328, current size $Wc_c
  916. fi
  917. # ============= iman/iwrite.tex ==============
  918. echo "x - extracting iman/iwrite.tex (Text)"
  919. sed 's/^X//' << 'SHAR_EOF' > iman/iwrite.tex &&
  920. X% XREF iwrite iwritopn
  921. X
  922. X\def\name{IWRITE}
  923. X\def\IT{{\bb iwrite()}}
  924. X\def\ALT{{\bb iwritopn()}}
  925. X
  926. X\S{NAME}
  927. X{\bb iwrite} --- open file, write buffer to file, close file
  928. X
  929. X{\bb iwritopn} --- open file, write buffer to file, leave file open
  930. X
  931. X\S{SYNOPSIS}
  932. X{\obeylines \bb
  933. Xint
  934. Xiwrite (fname, start, end)
  935. Xchar *fname;
  936. Xchar *start;
  937. Xchar *end;
  938. X\L
  939. Xint
  940. Xiwritopn (fname, start, end)
  941. Xchar *fname;
  942. Xchar *start;
  943. Xchar *end;
  944. X}
  945. X
  946. X\S{DESCRIPTION}
  947. X
  948. X\IT\ opens the file specified by {\myit fname\/},
  949. Xand writes the buffer delimited by {\myit start\/} and {\myit end\/}
  950. Xto the file.  \IT\ then closes the file, and returns the number of
  951. Xbytes written.
  952. XThe file is opened for {\myit write()\/}
  953. Xusing the symbolic {\myit flag\/} constants
  954. X{\myit O\_WRONLY \pip\ O\_CREAT \pip\ O\_TRUNC\/};
  955. Xretaining the file access permissions of an existing file, or
  956. Xsetting \dx{0644}\ for a new file.
  957. X\L
  958. XIn the special case if {\myit start\/} is the NULL pointer,
  959. X\IT\ retrieves the status of {\myit fname\/} and ignores the passed
  960. Xbuffer, returning:
  961. X\smallskip
  962. X\I{-1 if the system does not allow writing to {\myit fname\/},}
  963. X
  964. X\I{0 if file {\myit fname\/} could be written to, but does not exist,}
  965. X
  966. X\I{1 if file {\myit fname\/} exists, and could be written to.}
  967. X\L
  968. X\ALT\ operates similarly to \IT,but does not implement
  969. Xthe the special {\myit fstat()\/} call.
  970. X\ALT\ opens {\myit fname\/},
  971. Xand writes the buffer delimited by {\myit start\/} and {\myit end\/}
  972. Xto the file.  At this point, differently from \IT,
  973. Xthe file is left open, and the
  974. X{\myit (int) file descriptor\/} of the open file is returned.
  975. X\L
  976. XExcept for the special call to \IT, invalid {\myit fname\/} or
  977. Xinvalid buffer delimiters
  978. Xtrigger error reporting via {\myit ierror()\/},
  979. Xand produce the {\myit -sys\_nerr\/} return value.
  980. X
  981. X\S{objed PROGRAM EXAMPLE}
  982. X
  983. XMany C programmers face the occasional need to modify binary files
  984. Xdirectly.  Binary files are either data files that contain byte
  985. Xvalues outside of the ASCII character set, or {\myit object\/}
  986. Xfiles containing executable machine code.  A number of standard Unix
  987. Xtools and editors are capable of displaying and altering binary files
  988. Xdirectly (for example {\myit adb\/} or {\myit emacs\/}), but even
  989. Xthe best tools support binary editing as a capability of secondary
  990. Ximportance only, leaving the mechanics of binary editing
  991. X``user-unfriendly'' and painful.
  992. X\L
  993. XThe {\bb objed} ({\bb obj}ect {\bb ed}itor) program is a
  994. X``software sandwich'': the top layer is a
  995. Xa transparent binary-to-ASCII conversion process, the bottom layer is
  996. Xa transparent, ASCII-to-binary conversion process, with the user's
  997. Xfavorite text editor wedged in between.  Because the user does not
  998. Xhave to learn the particulars of a new editor, editing binary files
  999. Xunder {\bb objed} should not yield unpleasant surprises.
  1000. XThe default command line syntax
  1001. X\smallskip
  1002. X\I{\mytt objed file}
  1003. X\smallskip
  1004. Xreads the binary file into an internal buffer with {\myit iread()\/},
  1005. Xthen converts chunks of 24 bytes into {\myit newline\/}-terminated
  1006. XASCII text lines, in a temporary file in {\mytt /tmp}.  The default
  1007. Xeditor {\myit vi\/} is called next, and the user edits the temporary
  1008. XASCII file in a conventional manner.  When {\myit vi\/} terminates,
  1009. Xthe temporary file is reconverted back to binary, and rewritten over
  1010. Xthe original binary file with a single call to \IT.
  1011. XA different editor can be specified with the {\mytt -e} command line flag:
  1012. X\smallskip
  1013. X\I{\mytt objed -e emacs file}
  1014. X\smallskip
  1015. Xor instead of the name of an editor, any Unix command can be given,
  1016. Xwith embedded \key{\$} characters as
  1017. X{\myit place holders\/} for ``file'':
  1018. X\smallskip
  1019. X\I{\mytt objed -e 'cat -n \dol\ \pip\ lp' file}
  1020. X\L
  1021. XIf the edit command does not modify the temporary ASCII copy of the
  1022. Xfile, {\bb objed} will not attempt to recreate the (identical) binary
  1023. Xversion; but simply deletes the temporary copy when
  1024. Xterminating the process.  If the ASCII copy is changed during editing
  1025. Xbut the binary file cannot be written to (for example when editing
  1026. Xthe image of a directory), {\bb objed} terminates
  1027. Xwith an error message, leaving
  1028. Xthe temporary file in {\mytt /tmp}.
  1029. X\L
  1030. XIn order to allow visual pattern discrimination and string recognition
  1031. Xwhen editing the ASCII copy, the original binary data is translated
  1032. Xunder four very simple rules:
  1033. X\L
  1034. XEach line at the beginning of the edit session will contain the
  1035. XASCII translation of the same number of bytes of the original file
  1036. X(here referred to as the {\myit modulo byte count\/}),
  1037. Xexcept the last line which may contain the translation of
  1038. Xa smaller number of the remaining original bytes.
  1039. XThe translated
  1040. XASCII text does not contain a counter to keep track of the addresses
  1041. Xof the original bytes; but as long as the lines of the temporary file
  1042. Xare kept intact, the address of the first byte in each line can be
  1043. Xderived from the formula
  1044. X\smallskip
  1045. X\I{line\_number\_minus\_one * modulo\_byte\_count}
  1046. X\smallskip
  1047. XThe default modulo byte count is 24, but can be
  1048. Xoverridden by specifying a different value along with the {\mytt-b}
  1049. Xcommand line option.
  1050. X\L
  1051. XEach original byte value outside the ASCII printing range is
  1052. Xtranslated as a two-digit, upper case hexadecimal number
  1053. Xbetween 00 and FF({\myit hex\/}),
  1054. Xseparated from the printing character
  1055. Xto its right by a single blank space.
  1056. X(The ASCII printing character set
  1057. Xcomprises all ASCII characters that make
  1058. Xa mark on the paper; ranging between
  1059. Xdecimal values 33 \key{!} and 126 \key{\til} inclusive.)
  1060. X\L
  1061. XEach string in the original file
  1062. Xformed by consecutive, printing ASCII bytes with
  1063. Xstring length of three or longer, and within an imaginary original
  1064. Xline of modulo byte count length,
  1065. Xis printed as the string
  1066. Xitself; and is separated from its right hand neighbor by a blank
  1067. Xspace.
  1068. X\L
  1069. XEach printing ASCII byte that cannot fit into a string described
  1070. Xabove (either because it is not a part of a long enough
  1071. Xprinting ASCII string or because it is broken off from a preceding or
  1072. Xsuccessive line) is translated as its own printing image; and is
  1073. Xseparated from its neighbor to the right by two blank spaces.
  1074. X\L
  1075. XIf the solo minus flag \key{-} is present on the command line,
  1076. X{\bb objed} produces a more homogeneous, less {\myit freeform\/}
  1077. Xtranslation,
  1078. Xby converting even the printing ASCII bytes of the original file
  1079. Xto two-digit, hexadecimal, space-separated numbers.
  1080. X\L
  1081. XMethods of reconverting data from the temporary file are even simpler.
  1082. XAny distinct (separated from the next printing byte)
  1083. Xtwo-digit uppercase hexadecimal number will
  1084. Xbe changed back into a binary byte, while all other printing characters
  1085. Xwill be rewritten as themselves.  The reconversion is insensitive to
  1086. Xthe modulo byte count
  1087. Xoperative during the construction of the temporary file,
  1088. Xhowever a single edited
  1089. Xline should not expand beyond 16 times of the
  1090. Xmodulo byte count.  More data can be added by inserting any number
  1091. Xof new text lines.
  1092. XThe reconversion is also insensitive to any non-printing
  1093. Xcharacters, ignoring all spacing and {\myit control characters\/}
  1094. X--- except as token delimiters.
  1095. XThe total size of the data can shrink or grow arbitrarily.
  1096. X\L
  1097. X{\bb objed}'s use of the \IT\ function again addresses the concern
  1098. Xthat piece-by-piece restoration of the binary file may prove
  1099. Xdisastrous in case of an interrupt, or on system failures
  1100. X(crashes, disk full, etc.).  Under these circumstances,
  1101. Xpiece-by-piece restoration would be
  1102. Xlikely to truncate the file, or update it only partially. {\bb objed}
  1103. Xrestores the edited file in an internal buffer, and writes
  1104. Xthe final data with a single call to \IT.
  1105. X
  1106. X\S{objed.c PROGRAM TEXT}
  1107. X\listing{../iex/objed.c}
  1108. X\eject
  1109. SHAR_EOF
  1110. $TOUCH -am 0608095290 iman/iwrite.tex &&
  1111. chmod 0644 iman/iwrite.tex ||
  1112. echo "restore of iman/iwrite.tex failed"
  1113. set `wc -c iman/iwrite.tex`;Wc_c=$1
  1114. if test "$Wc_c" != "7540"; then
  1115.     echo original size 7540, current size $Wc_c
  1116. fi
  1117. # ============= iman/man.tex ==============
  1118. echo "x - extracting iman/man.tex (Text)"
  1119. sed 's/^X//' << 'SHAR_EOF' > iman/man.tex &&
  1120. X\font\myit=cmti9
  1121. X\font\mytt=cmtt9
  1122. X\font\myletr=cmssq8
  1123. X\font\bb=cmssbx10
  1124. X\font\smallcaps=cmcsc10
  1125. X
  1126. X\hsize 5.2in
  1127. X\vsize 7.6in
  1128. X\raggedbottom
  1129. X\parskip 0pt
  1130. X\parindent 0pt
  1131. X\myletr
  1132. X
  1133. X\def\stio{{\myit stdio\/}}
  1134. X\def\stin{{\myit stdin\/}}
  1135. X\def\stout{{\myit stdout\/}}
  1136. X\def\sterr{{\myit stderr\/}}
  1137. X\def\deg{{\kern -.2em\rm\char23}}
  1138. X\def\mydots{$\ldots$}
  1139. X\def\hole{\kern1pt\vrule height6pt width4pt depth2pt\kern1pt}
  1140. X
  1141. X% fill in line with dots or horizontal line, to last token
  1142. X\def\dotf{\leaders\hbox to .12in{\hss{\myletr.}\hss}\hfill}
  1143. X\def\linef{ \leaders\hrule\hfill\ }
  1144. X
  1145. X% to enclose a horizontal upper-case string in a rectangle
  1146. X\def\dx#1{\kern -.15em\setbox0=\hbox{\thinspace{#1}\thinspace}
  1147. X\dimen0=\ht0 \advance\dimen0 by 1.5pt          % 1.5 pt higher than text
  1148. X\dimen1=\dimen0 \advance\dimen1 by -.3pt       % underside of top line
  1149. X\dimen3=\dp0 \advance\dimen3 by 1.8pt          % 1.8 pt lower than text
  1150. X\dimen4=\dimen3 \advance\dimen4 by -.3pt       % topside of bottom line
  1151. X\vrule height \dimen0 depth \dimen3 width .3pt  % left vertical
  1152. X\vrule height \dimen0 depth -\dimen1 width \wd0 % top horizontal
  1153. X\vrule width -\wd0                              % go back to left
  1154. X\vrule height -\dimen4 depth \dimen3 width \wd0 % bottom horizontal
  1155. X\vrule width -\wd0                              % go back to left
  1156. X\box0                                           % install text
  1157. X\vrule height \dimen0 depth \dimen3 width .3pt  % right vertical
  1158. X}
  1159. X% to enclose a single \tt key in 11x11 (more or less) square, with
  1160. X% small space automatically appended to right of box
  1161. X%
  1162. X\def\key#1{\setbox0=\hbox to 10.4pt{\hfill{\mytt#1}\hfill}
  1163. X\dimen0=2ex \dimen1=\dimen0 \advance\dimen1 by -.3pt
  1164. X\dimen3=.5ex \dimen4=\dimen3 \advance\dimen4 by -.3pt
  1165. X\dimen5=\wd0
  1166. X\vrule height \dimen0 depth \dimen3 width .3pt     % left vertical
  1167. X\vrule height \dimen0 depth -\dimen1 width \dimen5 % top horiz
  1168. X\vrule width -\dimen5                              % backup to left
  1169. X\box0                                              % install text
  1170. X\vrule width -\dimen5                              % backup to left
  1171. X\vrule height -\dimen4 depth \dimen3 width \dimen5 % bottom horiz
  1172. X\vrule height \dimen0 depth \dimen3 width .3pt     % right vertical
  1173. X\thinspace
  1174. X}
  1175. X% to enclose two \tt keys (control sequences, etc.) in a rectangle
  1176. X\def\twokey#1{\setbox0=\hbox to 16pt {\hfill{\mytt#1}\hfill}
  1177. X\dimen0=2ex \dimen1=\dimen0 \advance\dimen1 by -.3pt
  1178. X\dimen3=.5ex \dimen4=\dimen3 \advance\dimen4 by -.3pt
  1179. X\dimen5=\wd0
  1180. X\vrule height \dimen0 depth \dimen3 width .3pt     % left vertical
  1181. X\vrule height \dimen0 depth -\dimen1 width \dimen5 % top horiz
  1182. X\vrule width -\dimen5                              % backup to left
  1183. X\box0                                              % install text
  1184. X\vrule width -\dimen5                              % backup to left
  1185. X\vrule height -\dimen4 depth \dimen3 width \dimen5 % bottom horiz
  1186. X\vrule height \dimen0 depth \dimen3 width .3pt     % right vertical
  1187. X\thinspace
  1188. X}
  1189. X\def\bsl{{\char92}}   % \
  1190. X\def\und{{\char95}}   % _
  1191. X\def\pip{{\mytt\char124}}  % |
  1192. X\def\lcu{{\char123}}  % {
  1193. X\def\rcu{{\char125}}  % }
  1194. X\def\lsq{{\char91}}   % [
  1195. X\def\rsq{{\char93}}   % ]
  1196. X\def\les{{\char60}}   % <
  1197. X\def\gre{{\char62}}   % >
  1198. X\def\cir{{\char94}}   % ^
  1199. X\def\car{{\char94}}   % ^
  1200. X\def\til{{\char126}}  % ~
  1201. X\def\dol{{\mytt\char36}}   % $
  1202. X\def\ats{{\char64}}   % @
  1203. X
  1204. X\headline={{\myletr\name\hfil\mansection\hfil\name}}
  1205. X\footline={\ifodd\pageno\rightfoot\else\leftfoot\fi}
  1206. X\def\leftfoot{\rlap{\myletr\folio}\hfil{{\myletr\vers\ --- \date}}\hfil}
  1207. X\def\rightfoot{\hfil{{\myletr\vers\ --- \date}}\hfil\llap{\myletr\folio}}
  1208. X\def\S#1{\leftline{}\par\leftskip=-20pt{\bb#1}\smallskip\leftskip=0pt}
  1209. X\def\SU#1{\par\leftskip=-20pt{\bb#1}\smallskip\leftskip=0pt}
  1210. X\def\L{\par\kern 7pt\par}
  1211. X\def\I#1{\leftskip=20pt{#1}\par\leftskip=0pt}
  1212. X
  1213. X% Verbatim macros from Appendix D (pages 381, 391) of The TeXbook
  1214. X% but senza line numbering, and tabstopwidth set to four.
  1215. X% Redefined Q to produce \longrightarrow at left margin of \listing
  1216. X%
  1217. X\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}
  1218. X\def\setupverbatim{\mytt
  1219. X  \def\par{\leavevmode\egroup\box0\endgraf}
  1220. X  \obeylines \uncatcodespecials \obeyspaces
  1221. X  \catcode`\`=\active \catcode`\^^I=\active
  1222. X  \catcode`Q=\active
  1223. X  \everypar{\startbox}}
  1224. X\newdimen\w \setbox0=\hbox{\mytt\space} \w=4\wd0 % width of tab
  1225. X\def\startbox{\setbox0=\hbox\bgroup}
  1226. X{\catcode`\^^I=\active
  1227. X  \gdef^^I{\leavevmode\egroup
  1228. X    \dimen0=\wd0          % the width so far, or since the previous tab
  1229. X    \divide\dimen0 by\w
  1230. X    \multiply\dimen0 by\w % compute previous multiple of \w
  1231. X    \advance\dimen0 by\w  % advance to next multiple of \w
  1232. X    \wd0=\dimen0 \box0 \startbox}}
  1233. X\def\listing#1{\par\begingroup\setupverbatim\input#1 \endgroup}
  1234. X{\obeyspaces\global\let =\ } % let active space become control space
  1235. X{\catcode`\`=\active \gdef`{\relax\lq}}
  1236. X{\catcode`Q=\active \gdefQ{\ \kern -30pt$\longrightarrow$\kern 14pt}}
  1237. SHAR_EOF
  1238. $TOUCH -am 0608125990 iman/man.tex &&
  1239. chmod 0644 iman/man.tex ||
  1240. echo "restore of iman/man.tex failed"
  1241. set `wc -c iman/man.tex`;Wc_c=$1
  1242. if test "$Wc_c" != "4877"; then
  1243.     echo original size 4877, current size $Wc_c
  1244. fi
  1245. # ============= iman/single.tex ==============
  1246. echo "x - extracting iman/single.tex (Text)"
  1247. sed 's/^X//' << 'SHAR_EOF' > iman/single.tex &&
  1248. X\input man
  1249. X\def\date{June, 1990}
  1250. X\def\vers{Version 1.0}
  1251. X\def\mansection{ILIB (3i)}
  1252. X
  1253. X\input ihash
  1254. X
  1255. X\bye
  1256. SHAR_EOF
  1257. $TOUCH -am 0608125890 iman/single.tex &&
  1258. chmod 0644 iman/single.tex ||
  1259. echo "restore of iman/single.tex failed"
  1260. set `wc -c iman/single.tex`;Wc_c=$1
  1261. if test "$Wc_c" != "103"; then
  1262.     echo original size 103, current size $Wc_c
  1263. fi
  1264. # ============= iman/stanquote.new ==============
  1265. echo "x - extracting iman/stanquote.new (Text)"
  1266. sed 's/^X//' << 'SHAR_EOF' > iman/stanquote.new &&
  1267. XThe sad truth is that there is a frustrating absence of crisp axioms from
  1268. Xwhich you can build a logically consistent corpus of computer know-how.
  1269. XIndeed, it is hard to find so much as a single simple sentence that you can
  1270. Xswear to on your mother's white Corniche without first appending a list of
  1271. Xcaveats and qualifications.
  1272. X
  1273. X                  Stan Kelly-Bootle, UNIX REVIEW VOL.5 NO.2
  1274. SHAR_EOF
  1275. $TOUCH -am 0504125590 iman/stanquote.new &&
  1276. chmod 0644 iman/stanquote.new ||
  1277. echo "restore of iman/stanquote.new failed"
  1278. set `wc -c iman/stanquote.new`;Wc_c=$1
  1279. if test "$Wc_c" != "386"; then
  1280.     echo original size 386, current size $Wc_c
  1281. fi
  1282. # ============= iman/stanquote.old ==============
  1283. echo "x - extracting iman/stanquote.old (Text)"
  1284. sed 's/^X//' << 'SHAR_EOF' > iman/stanquote.old &&
  1285. XThe sad truth is that there is a frustrating absence
  1286. Xof crisp axioms from which you can build a logically
  1287. Xconsistent corpus of computer know-how.
  1288. XIndeed, it is hard to find so much as a single
  1289. Xsimple sentence that you can swear to
  1290. Xon your mother's white Corniche without first
  1291. Xappending a list of caveats and qualifications.
  1292. X
  1293. X                  Stan Kelly-Bootle, UNIX REVIEW VOL.5 NO.2
  1294. SHAR_EOF
  1295. $TOUCH -am 0504125690 iman/stanquote.old &&
  1296. chmod 0644 iman/stanquote.old ||
  1297. echo "restore of iman/stanquote.old failed"
  1298. set `wc -c iman/stanquote.old`;Wc_c=$1
  1299. if test "$Wc_c" != "386"; then
  1300.     echo original size 386, current size $Wc_c
  1301. fi
  1302. exit 0
  1303. -- 
  1304.         Istvan Mohos
  1305.         ...uunet!pyrdc!pyrnj!hhb!istvan
  1306.         RACAL-REDAC/HHB 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
  1307. ======================================================================
  1308.