home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / lout / part02 < prev    next >
Encoding:
Text File  |  1993-05-31  |  82.8 KB  |  1,803 lines

  1. Newsgroups: comp.sources.misc
  2. From: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  3. Subject: v37i100:  lout - Lout document formatting system, v2, Part02/30
  4. Message-ID: <1993May31.035107.20569@sparky.imd.sterling.com>
  5. X-Md4-Signature: edfb395e615535178cc9a332b52b54ef
  6. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Mon, 31 May 1993 03:51:07 GMT
  9. Approved: kent@sparky.imd.sterling.com
  10.  
  11. Submitted-by: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  12. Posting-number: Volume 37, Issue 100
  13. Archive-name: lout/part02
  14. Environment: UNIX
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  lout/doc/tr.lout/ch3.25 lout/externs
  21. # Wrapped by kent@sparky on Sun May 30 19:43:53 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 2 (of 30)."'
  25. if test -f 'lout/doc/tr.lout/ch3.25' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch3.25'\"
  27. else
  28.   echo shar: Extracting \"'lout/doc/tr.lout/ch3.25'\" \(1014 characters\)
  29.   sed "s/^X//" >'lout/doc/tr.lout/ch3.25' <<'END_OF_FILE'
  30. X@Section
  31. X   @Tag { prependgraphic }
  32. X   @Title { "@PrependGraphic and @SysPrependGraphic" }
  33. X@Begin
  34. X@PP
  35. Xprependgraphic.sym @Index { @@PrependGraphic symbol }
  36. Xsysprependgraphic.sym @Index { @@SysPrependGraphic symbol }
  37. Xpostscript.prependgraphic @SubIndex { used by @@PrependGraphic }
  38. XThese symbols tell Lout to include the contents of a file in the
  39. Xpreamble of its output.  For Basser Lout this means that the file must
  40. Xcontain PostScript (and ideally it would begin and end with the
  41. X@Code "%%BeginResource" and @Code "%%EndResource" comments of
  42. XDSC 3.0).  For example,
  43. X@ID @Code {
  44. X"@SysPrependGraphic { \"fig_prepend\" }"
  45. X}
  46. Xappears at the start of the Fig package; the file @Code fig_prepend
  47. Xcontains a number of PostScript definitions used by Fig for drawing
  48. Xdiagrams.  It saves a lot of space to include them just once at the
  49. Xstart like this, rather than with every diagram.  @@PrependGraphic and
  50. X@@SysPrependGraphic search for the file in the same places as @@Include and
  51. X@@SysInclude respectively.
  52. X@End @Section
  53. END_OF_FILE
  54.   if test 1014 -ne `wc -c <'lout/doc/tr.lout/ch3.25'`; then
  55.     echo shar: \"'lout/doc/tr.lout/ch3.25'\" unpacked with wrong size!
  56.   fi
  57.   # end of 'lout/doc/tr.lout/ch3.25'
  58. fi
  59. if test -f 'lout/externs' -a "${1}" != "-c" ; then 
  60.   echo shar: Will not clobber existing file \"'lout/externs'\"
  61. else
  62.   echo shar: Extracting \"'lout/externs'\" \(79673 characters\)
  63.   sed "s/^X//" >'lout/externs' <<'END_OF_FILE'
  64. X/*@externs:External Declarations@*********************************************/
  65. X/*                                                                           */
  66. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.03)       */
  67. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  68. X/*                                                                           */
  69. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  70. X/*  Basser Department of Computer Science                                    */
  71. X/*  The University of Sydney 2006                                            */
  72. X/*  AUSTRALIA                                                                */
  73. X/*                                                                           */
  74. X/*  This program is free software; you can redistribute it and/or modify     */
  75. X/*  it under the terms of the GNU General Public License as published by     */
  76. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  77. X/*  any later version.                                                       */
  78. X/*                                                                           */
  79. X/*  This program is distributed in the hope that it will be useful,          */
  80. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  81. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  82. X/*  GNU General Public License for more details.                             */
  83. X/*                                                                           */
  84. X/*  You should have received a copy of the GNU General Public License        */
  85. X/*  along with this program; if not, write to the Free Software              */
  86. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  87. X/*                                                                           */
  88. X/*  FILE:         externs                                                    */
  89. X/*  MODULE:       External Declarations                                      */
  90. X/*                                                                           */
  91. X/*****************************************************************************/
  92. X#include <stdio.h>
  93. X#include <string.h>
  94. X
  95. X/*****************************************************************************/
  96. X/*                                                                           */
  97. X/*  Include, font and database directories, and the DEBUG_ON and ASSERT_ON   */
  98. X/*  flags (defined by -D options on the cc command line in the makefile).    */
  99. X/*                                                                           */
  100. X/*  LATIN               Non-zero means compile for ISO-LATIN-1 char set.     */
  101. X/*  INCL_DIR            The system directory where @Include files are kept   */
  102. X/*  FONT_DIR            The system directory where .AFM font files are kept  */
  103. X/*  DATA_DIR            The system directory where database files are kept   */
  104. X/*  DEBUG_ON            Non-zero means compile debug code (lout -d)          */
  105. X/*  ASSERT_ON           Non-zero means test assertions                       */
  106. X/*                                                                           */
  107. X/*  #define  LATIN      0                                                    */
  108. X/*  #define  INCL_DIR   "/usr/local/lib/lout/include"                        */
  109. X/*  #define  FONT_DIR   "/usr/local/lib/lout/font"                           */
  110. X/*  #define  DATA_DIR   "/usr/local/lib/lout/data"                           */
  111. X/*  #define  DEBUG_ON   0                                                    */
  112. X/*  #define  ASSERT_ON  1                                                    */
  113. X/*                                                                           */
  114. X/*****************************************************************************/
  115. X
  116. X
  117. X/*****************************************************************************/
  118. X/*                                                                           */
  119. X/*  File naming conventions and version                                      */
  120. X/*                                                                           */
  121. X/*  LOUT_VERSION        Version information                                  */
  122. X/*  CROSS_DB            The default name of the cross reference database     */
  123. X/*  INDEX_SUFFIX        The suffix of database index files                   */
  124. X/*  NEW_INDEX_SUFFIX    The additional suffix of new database index files    */
  125. X/*  DATA_SUFFIX         The suffix of database data files                    */
  126. X/*  NEW_DATA_SUFFIX     The additional suffix of new database data files     */
  127. X/*  HYPH_FILENAME       The default name of the unpacked hyphenation file    */
  128. X/*  HYPH_SUFFIX         The suffix of the packed hyphenation file            */
  129. X/*                                                                           */
  130. X/*****************************************************************************/
  131. X
  132. X#define    LOUT_VERSION        "Basser Lout Version 2.03 (April 1993)"
  133. X#define    CROSS_DB        "lout"
  134. X#define    INDEX_SUFFIX        ".li"
  135. X#define    NEW_INDEX_SUFFIX    "x"
  136. X#define    DATA_SUFFIX        ".ld"
  137. X#define    NEW_DATA_SUFFIX        "x"
  138. X#define    HYPH_FILENAME        "lout.hyph"
  139. X#define    HYPH_SUFFIX        ".packed"
  140. X
  141. X/*****************************************************************************/
  142. X/*                                                                           */
  143. X/*  Significant Limits (other insignificant ones appear in other files)      */
  144. X/*                                                                           */
  145. X/*  MAX_LEN             The maximum value storable in type LENGTH            */
  146. X/*                                                                           */
  147. X/*  MAX_FILES           1 + the maximum number of files.  This cannot        */
  148. X/*                      exceed 256 without changing type FILE_NUM; and       */
  149. X/*                      it cannot exceed 255 without increasing MAX_WORD     */
  150. X/*                      (a WORD is used to hold an array indexed by filenum  */
  151. X/*                      in file z10.c).                                      */
  152. X/*                                                                           */
  153. X/*  MAX_LINE            1 + the maximum length of an input line, in files    */
  154. X/*                      of all types.  This cannot exceed 256, at least in   */
  155. X/*                      source files, unless the col_num field of FILE_POS   */
  156. X/*                      is enlarged beyond its present 1 byte unsigned       */
  157. X/*                                                                           */
  158. X/*  MAX_WORD            1 + the maximum length of a word storable in an      */
  159. X/*                      object record, which includes all file path names    */
  160. X/*                      too.  It is reasonable to make this MAX_LINE, since  */
  161. X/*                      a word longer than MAX_LINE cannot be read in        */
  162. X/*                                                                           */
  163. X/*  MAX_OBJECT_REC      1 + the maximum size of an object record, measured   */
  164. X/*                      in ALIGNs.  The value chosen should exceed           */
  165. X/*                      ceiling( (wr + MAX_WORD - 4) / sizeof(ALIGN) )       */
  166. X/*                      where wr = sizeof(struct word_rec), so that words of */
  167. X/*                      length MAX_WORD-1 can be stored in an object record  */
  168. X/*                                                                           */
  169. X/*  MAX_FONT            1 + the maximum number of sized fonts.  This can be  */
  170. X/*                      increased easily since font metric memory is         */
  171. X/*                      obtained as required from malloc().                  */
  172. X/*                                                                           */
  173. X/*  MAX_LEX_STACK       The maximum depth of @Includes and @Databases.       */
  174. X/*                      This can be increased easily if desired.             */
  175. X/*                                                                           */
  176. X/*****************************************************************************/
  177. X
  178. X#define    MAX_LEN            32767
  179. X#define    MAX_FILES        255
  180. X#define MAX_LINE            256
  181. X#define MAX_WORD            256
  182. X#define    MAX_OBJECT_REC        73
  183. X#define MAX_FONT        100
  184. X#define    MAX_LEX_STACK         5
  185. X
  186. X/*****************************************************************************/
  187. X/*                                                                           */
  188. X/*  Miscellaneous Macros                                                     */
  189. X/*                                                                           */
  190. X/*****************************************************************************/
  191. X
  192. X#define    BOOLEAN        unsigned    /* changed from: short unsigned      */
  193. X#define    FALSE        0
  194. X#define    TRUE        1
  195. X#define    bool(x)        (x ? "TRUE" : "FALSE")
  196. X#define    CHILD        0
  197. X#define    PARENT        1
  198. X#define    COL        0
  199. X#define    ROW        1
  200. X#define    dimen(x)    (x == COL ? "COL" : "ROW" )
  201. X#define    nil        ( (OBJECT) NULL )
  202. X#define    null        ( (FILE *) NULL )
  203. X
  204. X#define max(a, b)    ((a) < (b) ? (b) : (a))
  205. X#define min(a, b)    ((a) < (b) ? (a) : (b))
  206. X#define    ceiling(a, b)    ( ((a) - 1)/(b) + 1 )    /* ceiling(a/b)              */
  207. X#define is_odd(x)    ( (x) & 1 )        /* TRUE if x is odd number   */
  208. X
  209. X
  210. X/*****************************************************************************/
  211. X/*                                                                           */
  212. X/*  ALIGN - the most restrictive memory alignment type.                      */
  213. X/*                                                                           */
  214. X/*****************************************************************************/
  215. X
  216. Xtypedef int ALIGN;
  217. X
  218. X
  219. X/*****************************************************************************/
  220. X/*                                                                           */
  221. X/*  LENGTH - a distance measured in integral multiples of the basic unit.    */
  222. X/*                                                                           */
  223. X/*****************************************************************************/
  224. X
  225. Xtypedef short int LENGTH;
  226. X
  227. X
  228. X/*****************************************************************************/
  229. X/*                                                                           */
  230. X/*  FONT_NUM - internal name for a font                                      */
  231. X/*                                                                           */
  232. X/*****************************************************************************/
  233. X
  234. Xtypedef unsigned char FONT_NUM;
  235. X
  236. X
  237. X/*****************************************************************************/
  238. X/*                                                                           */
  239. X/*  GAP - what separates one object from another                             */
  240. X/*                                                                           */
  241. X/*****************************************************************************/
  242. X
  243. Xtypedef struct
  244. X{ unsigned char    ospare;            /* left for other things in STYLE    */
  245. X  BOOLEAN    omark    : 1;        /* TRUE if this gap is marked        */
  246. X  BOOLEAN    ojoin    : 1;        /* TRUE if joins exist across gap    */
  247. X  unsigned    ounits    : 3;        /* units of measurement: fixed, etc  */
  248. X  unsigned    omode    : 3;        /* spacing mode: edge-to-edge, etc   */
  249. X  LENGTH    owidth;            /* width of the gap                  */
  250. X} GAP;
  251. X
  252. X#define    mark(x)        (x).omark
  253. X#define    join(x)        (x).ojoin
  254. X#define    units(x)    (x).ounits
  255. X#define    mode(x)        (x).omode
  256. X#define    width(x)    (x).owidth
  257. X
  258. X#define SetGap(x, xmark, xjoin, xunits, xmode, xwidth)            \
  259. X( mark(x) = xmark, join(x) = xjoin, units(x) = xunits,            \
  260. X  mode(x) = xmode, width(x) = xwidth                    \
  261. X)
  262. X
  263. X#define GapCopy(x, y)                            \
  264. X( mark(x) = mark(y), join(x) = join(y), units(x) = units(y),        \
  265. X  mode(x) = mode(y), width(x) = width(y)                \
  266. X)
  267. X
  268. X#define ClearGap(x)    SetGap(x, FALSE, TRUE, FIXED_UNIT, NO_MODE, 0)
  269. X
  270. X
  271. X/*****************************************************************************/
  272. X/*                                                                           */
  273. X/*  STYLE - information about how to break text, etc.                        */
  274. X/*                                                                           */
  275. X/*****************************************************************************/
  276. X
  277. Xtypedef struct
  278. X{ GAP        oline_gap;        /* separation between lines          */
  279. X  union {
  280. X    GAP        ospace_gap;        /* separation indiced by white space */
  281. X    struct {
  282. X      unsigned    ohyph_style    : 2;    /* hyphenation off or on             */
  283. X      unsigned    ofill_style    : 2;    /* fill lines with text off/on       */
  284. X      unsigned    odisplay_style : 3;    /* display lines adjusted, ragged... */
  285. X    } oss;
  286. X  } osu;
  287. X} STYLE;
  288. X
  289. X#define    line_gap(x)    (x).oline_gap
  290. X#define    space_gap(x)    (x).osu.ospace_gap
  291. X#define    font(x)        (x).oline_gap.ospare
  292. X#define    hyph_style(x)    (x).osu.oss.ohyph_style
  293. X#define    fill_style(x)    (x).osu.oss.ofill_style
  294. X#define    display_style(x)(x).osu.oss.odisplay_style
  295. X
  296. X#define StyleCopy(x, y)                            \
  297. X( GapCopy( line_gap(x), line_gap(y) ),                    \
  298. X  font(x) = font(y),                            \
  299. X  hyph_style(x) = hyph_style(y),                    \
  300. X  fill_style(x) = fill_style(y),                    \
  301. X  display_style(x) = display_style(y),                    \
  302. X  GapCopy( space_gap(x), space_gap(y) )                    \
  303. X)
  304. X
  305. X
  306. X/*****************************************************************************/
  307. X/*                                                                           */
  308. X/*  CONSTRAINT - a size constraint                                           */
  309. X/*                                                                           */
  310. X/*****************************************************************************/
  311. X
  312. Xtypedef struct
  313. X{ LENGTH  obc;
  314. X  LENGTH  obfc;
  315. X  LENGTH  ofc;
  316. X  LENGTH  osparec;
  317. X} CONSTRAINT;
  318. X
  319. X#define    bc(x)        (x).obc
  320. X#define    bfc(x)        (x).obfc
  321. X#define    fc(x)        (x).ofc
  322. X#define    sparec(x)    (x).osparec
  323. X#define    constrained(x)    (bc(x)!=MAX_LEN || bfc(x)!=MAX_LEN || fc(x)!=MAX_LEN)
  324. X
  325. X#define    SetConstraint(c,x,y,z)    (bc(c) = (x),   bfc(c) = (y),    fc(c) = (z))
  326. X#define    CopyConstraint(x, y)    (bc(x) = bc(y), bfc(x) = bfc(y), fc(x) = fc(y))
  327. X#define FitsConstraint(b, f, c)    (b <= bc(c)  && b + f <= bfc(c) && f <= fc(c))
  328. X
  329. X#define    ig_fnum(x)    bc(constraint(x))
  330. X#define    ig_xtrans(x)    bfc(constraint(x))
  331. X#define    ig_ytrans(x)    fc(constraint(x))
  332. X
  333. X/*****************************************************************************/
  334. X/*                                                                           */
  335. X/*  FILE_NUM - the internal representation of a file                         */
  336. X/*  FILE_POS - a position in the set of input files                          */
  337. X/*                                                                           */
  338. X/*****************************************************************************/
  339. X
  340. Xtypedef unsigned char    FILE_NUM;
  341. X#define    NO_FILE        0
  342. X
  343. Xtypedef    struct
  344. X{ FILE_NUM    ofile_num;        /* no. of file this record is from   */
  345. X  unsigned char    ocol_num;        /* column number this is related to  */
  346. X  LENGTH    oline_num;        /* the line number of this record    */
  347. X} FILE_POS;
  348. X
  349. X#define    file_num(x)    (x).ofile_num
  350. X#define    col_num(x)    (x).ocol_num
  351. X#define    line_num(x)    (x).oline_num
  352. X
  353. X#define FposCopy(x, y)                            \
  354. X( file_num(x) = file_num(y),                        \
  355. X  line_num(x) = line_num(y),                        \
  356. X  col_num(x)  = col_num(y)                        \
  357. X)
  358. X
  359. X/*@::declaration of OBJECT@***************************************************/
  360. X/*                                                                           */
  361. X/*  OBJECT - pointer to an arbitrary object (parse tree, symbol table, ...)  */
  362. X/*                                                                           */
  363. X/*****************************************************************************/
  364. X
  365. X#define LIST struct { union rec *opred, *osucc; }
  366. X
  367. Xtypedef union rec
  368. X{
  369. X  struct word_type        /* all fields of WORD, both token and object */
  370. X  {  LIST    olist[2];
  371. X     union
  372. X     {    struct word_as_token
  373. X    {    unsigned char    otype;
  374. X        unsigned char    ohspace;
  375. X        unsigned char    ovspace;
  376. X        unsigned char    orec_size;
  377. X    } oi1;
  378. X
  379. X    struct word_as_object
  380. X    {    unsigned char    otype;
  381. X        BOOLEAN        ogall_rec    : 1;
  382. X        BOOLEAN        obroken      : 1;
  383. X        BOOLEAN        othreaded    : 1;
  384. X        BOOLEAN        oexternal    : 1;
  385. X        BOOLEAN        oblocked     : 1;
  386. X        BOOLEAN        obackward    : 1;
  387. X        BOOLEAN        otrigger_externs   : 1;
  388. X        BOOLEAN            omust_expand : 1;
  389. X        FONT_NUM    oword_font;
  390. X        unsigned char    orec_size;
  391. X    } oi2;
  392. X     } ou1;
  393. X     union
  394. X     {    FILE_POS    ofpos;
  395. X    int        oword_save_mark;
  396. X     } ou5;
  397. X     union
  398. X     {  LENGTH    oback[2];
  399. X    FILE    *ofilep;
  400. X    /* union rec *ogall_sym; */
  401. X     } ou3;
  402. X     union
  403. X     {    LENGTH    ofwd[2];
  404. X    int    ogall_pos;
  405. X     } ou4;
  406. X     unsigned char ostring[4];
  407. X  } os1;
  408. X
  409. X  struct closure_type        /* CLOSURE, both as token and object */
  410. X  {  LIST    olist[2];
  411. X     union
  412. X     {    struct closure_as_token
  413. X    {    unsigned char    otype;
  414. X        unsigned char    ohspace;
  415. X        unsigned char    ovspace;
  416. X        unsigned char    oprecedence;
  417. X    } oi1;
  418. X
  419. X    struct closure_as_object
  420. X    {    unsigned char    otype;
  421. X        BOOLEAN        ogall_rec    : 1;
  422. X        BOOLEAN        obroken      : 1;
  423. X        BOOLEAN        othreaded    : 1;
  424. X        BOOLEAN        oexternal    : 1;
  425. X        BOOLEAN        oblocked     : 1;
  426. X        BOOLEAN        obackward    : 1;
  427. X        BOOLEAN        otrigger_externs   : 1;
  428. X        BOOLEAN            omust_expand : 1;
  429. X        unsigned short    ocross_type;
  430. X    } oi2;
  431. X     } ou1;
  432. X     FILE_POS    ofpos;
  433. X     LENGTH    oback[2];
  434. X     LENGTH    ofwd[2];
  435. X     union
  436. X     {    STYLE        osave_style;
  437. X    CONSTRAINT    oconstraint;
  438. X     } ou2;
  439. X     union rec *oactual;
  440. X     union
  441. X     { union rec *owhereto;
  442. X       LENGTH    osave_mark;
  443. X     } ou3;
  444. X     union rec *oready_galls;
  445. X  } os2;
  446. X  
  447. X  struct object_type        /* the general OBJECT */
  448. X  {  LIST    olist[2];
  449. X     union
  450. X     {
  451. X    struct
  452. X    {    unsigned char    otype;
  453. X        BOOLEAN        ogall_rec    : 1;
  454. X        BOOLEAN        obroken      : 1;
  455. X        BOOLEAN        othreaded    : 1;
  456. X        BOOLEAN        oexternal    : 1;
  457. X        BOOLEAN        oblocked     : 1;
  458. X        BOOLEAN        obackward    : 1;
  459. X        BOOLEAN        otrigger_externs   : 1;
  460. X        BOOLEAN            omust_expand : 1;
  461. X        unsigned short    ocross_type;
  462. X    } oi2;
  463. X     } ou1;
  464. X     FILE_POS    ofpos;
  465. X     LENGTH    oback[2];
  466. X     LENGTH    ofwd[2];
  467. X     union
  468. X     {    STYLE        osave_style;
  469. X    CONSTRAINT    oconstraint;
  470. X     } ou2;
  471. X  } os3;
  472. X
  473. X  struct link_type        /* LINK */
  474. X  {  LIST        olist[2];
  475. X     unsigned char    otype;
  476. X     unsigned char    onumber;
  477. X     unsigned char    odb_targ;
  478. X  } os4;
  479. X  
  480. X  struct gapobj_type        /* GAP_OBJ */
  481. X  {  LIST        olist[2];
  482. X     unsigned char    otype;
  483. X     unsigned char    ohspace;
  484. X     unsigned char    ovspace;
  485. X     unsigned char    oprecedence;
  486. X     FILE_POS        ofpos;
  487. X     GAP        ogap;
  488. X     int        osave_badness;        /* optimum paragraph breaker */
  489. X     LENGTH        osave_space;        /* optimum paragraph breaker */
  490. X     LENGTH        osave_actual_gap;    /* optimum paragraph breaker */
  491. X     union rec      *osave_prev;        /* optimum paragraph breaker */
  492. X  } os5;
  493. X
  494. X  struct symbol_type
  495. X  {  LIST    olist[2];
  496. X     unsigned char otype;
  497. X     BOOLEAN    ohas_lpar            : 1;
  498. X     BOOLEAN    ohas_rpar            : 1;
  499. X     BOOLEAN    oright_assoc         : 1;
  500. X     BOOLEAN    ois_target           : 1;
  501. X     BOOLEAN    ohas_target          : 1;
  502. X     BOOLEAN    oforce_target         : 1;
  503. X     BOOLEAN    ois_tag              : 1;
  504. X     BOOLEAN    ohas_tag             : 1;
  505. X     BOOLEAN    ohas_body            : 1;
  506. X     BOOLEAN    oindefinite          : 1;
  507. X     BOOLEAN    orecursive           : 1;
  508. X     BOOLEAN    ouses_extern_target  : 1;
  509. X     BOOLEAN    ois_extern_target    : 1;
  510. X     BOOLEAN    ois_key             : 1;
  511. X     BOOLEAN    ohas_key         : 1;
  512. X     unsigned    odirty               : 1;
  513. X     unsigned    char oprecedence;
  514. X     FILE_POS    ofpos;
  515. X     union rec    *oenclosing;
  516. X     union rec    *osym_body;
  517. X     union rec    *obase_uses;
  518. X     union rec    *ouses;
  519. X     union rec    *omarker;
  520. X     union rec    *ocross_sym;
  521. X     union rec    *oimports;
  522. X     unsigned char ouses_count;
  523. X     BOOLEAN    ovisible         : 1;
  524. X     BOOLEAN    ohas_mark         : 1;
  525. X     BOOLEAN    ohas_join         : 1;
  526. X     BOOLEAN    ohas_par             : 1;
  527. X     BOOLEAN    ouses_galley         : 1;
  528. X     short unsigned opredefined;
  529. X  } os6;
  530. X
  531. X  struct cr_type
  532. X  {  LIST        olist[2];
  533. X     unsigned char    otype;
  534. X     unsigned char    otarget_state;
  535. X     FILE_NUM        otarget_file;
  536. X     FILE_NUM        ocr_file;
  537. X     union rec        *otarget_val;
  538. X     int        otarget_seq;
  539. X     int        otarget_pos;
  540. X     int        ocr_seq;
  541. X     int        ogall_seq;
  542. X     union rec        *osymb;
  543. X     union rec        *ogall_tag;
  544. X     FILE_NUM        ogall_tfile;
  545. X     FILE_NUM        ogentag_file;
  546. X     int        ogentag_seq;
  547. X     union rec        *ogentag_fseq;
  548. X  } os7;
  549. X
  550. X  struct ext_gall_type
  551. X  {  LIST        olist[2];
  552. X     unsigned char    otype;
  553. X     FILE_NUM        oeg_fnum;
  554. X     long        oeg_fpos;
  555. X     long        oeg_cont;
  556. X     union rec        *oeg_symbol;
  557. X  } os8;
  558. X
  559. X  struct uses_type
  560. X  {  union rec    *oitem;
  561. X     union rec    *onext;
  562. X  } os9;
  563. X
  564. X  struct hash_entry_type
  565. X  {  LIST    olist[1];
  566. X  } os10;
  567. X
  568. X} *OBJECT;
  569. X
  570. X#define    succ(x, dim)    (x)->os1.olist[dim].osucc
  571. X#define    pred(x, dim)    (x)->os1.olist[dim].opred
  572. X#define type(x)        (x)->os1.ou1.oi1.otype
  573. X#define    gall_rec(x)    (x)->os1.ou1.oi2.ogall_rec
  574. X#define    non_blocking(x)    gall_rec(x)
  575. X#define    broken(x)    (x)->os1.ou1.oi2.obroken
  576. X#define    external(x)    (x)->os1.ou1.oi2.oexternal
  577. X#define    threaded(x)    (x)->os1.ou1.oi2.othreaded
  578. X#define    blocked(x)    (x)->os1.ou1.oi2.oblocked
  579. X#define    backward(x)    (x)->os1.ou1.oi2.obackward
  580. X#define    sized(x)    broken(x)
  581. X#define    seen_nojoin(x)    blocked(x)
  582. X#define    must_expand(x)    (x)->os1.ou1.oi2.omust_expand
  583. X#define    trigger_externs(x) (x)->os1.ou1.oi2.otrigger_externs
  584. X#define    hspace(x)    (x)->os1.ou1.oi1.ohspace
  585. X#define    vspace(x)    (x)->os1.ou1.oi1.ovspace
  586. X#define    word_font(x)    (x)->os1.ou1.oi2.oword_font
  587. X#define    rec_size(x)    (x)->os1.ou1.oi2.orec_size
  588. X#define    fpos(x)        (x)->os2.ofpos
  589. X#define    back(x, dim)    (x)->os2.oback[dim]
  590. X#define    fwd(x, dim)    (x)->os2.ofwd[dim]
  591. X#define    size(x, dim)    (back(x, dim) + fwd(x, dim))
  592. X#define word_save_mark(x) (x)->os1.ou5.oword_save_mark
  593. X#define string(x)    (x)->os1.ostring
  594. X
  595. X#define    precedence(x)    (x)->os2.ou1.oi1.oprecedence
  596. X#define    cross_type(x)    (x)->os2.ou1.oi2.ocross_type
  597. X#define    thr_state(x)    cross_type(x)
  598. X#define    save_style(x)    (x)->os2.ou2.osave_style
  599. X#define    constraint(x)    (x)->os2.ou2.oconstraint
  600. X#define actual(x)    (x)->os2.oactual
  601. X#define whereto(x)    (x)->os2.ou3.owhereto
  602. X#define save_mark(x)    (x)->os2.ou3.osave_mark
  603. X#define ready_galls(x)    (x)->os2.oready_galls
  604. X
  605. X#define    number(x)    (x)->os4.onumber
  606. X#define    db_targ(x)    (x)->os4.odb_targ
  607. X#define    gap(x)        (x)->os5.ogap
  608. X#define    save_space(x)    (x)->os5.osave_space
  609. X#define    save_badness(x)    (x)->os5.osave_badness
  610. X#define    save_actual_gap(x)  (x)->os5.osave_actual_gap
  611. X#define    save_prev(x)    (x)->os5.osave_prev
  612. X
  613. X#define    has_lpar(x)    (x)->os6.ohas_lpar
  614. X#define    has_rpar(x)    (x)->os6.ohas_rpar
  615. X#define    right_assoc(x)    (x)->os6.oright_assoc
  616. X#define    is_target(x)    (x)->os6.ois_target
  617. X#define    has_target(x)    (x)->os6.ohas_target
  618. X#define    force_target(x)    (x)->os6.oforce_target
  619. X#define    is_tag(x)    (x)->os6.ois_tag
  620. X#define    has_tag(x)    (x)->os6.ohas_tag
  621. X#define    has_body(x)    (x)->os6.ohas_body
  622. X#define    indefinite(x)    (x)->os6.oindefinite
  623. X#define    recursive(x)    (x)->os6.orecursive
  624. X#define    predefined(x)    (x)->os6.opredefined
  625. X#define    dirty(x)    (x)->os6.odirty
  626. X#define    enclosing(x)    (x)->os6.oenclosing
  627. X#define    sym_body(x)    (x)->os6.osym_body
  628. X#define    base_uses(x)    (x)->os6.obase_uses
  629. X#define    uses(x)        (x)->os6.ouses
  630. X#define    marker(x)    (x)->os6.omarker
  631. X#define    cross_sym(x)    (x)->os6.ocross_sym
  632. X#define    imports(x)    (x)->os6.oimports
  633. X#define    uses_count(x)    (x)->os6.ouses_count
  634. X#define    visible(x)    (x)->os6.ovisible
  635. X#define    has_mark(x)    (x)->os6.ohas_mark
  636. X#define    has_join(x)    (x)->os6.ohas_join
  637. X#define    has_par(x)    (x)->os6.ohas_par
  638. X#define    uses_galley(x)    (x)->os6.ouses_galley
  639. X#define    is_extern_target(x) (x)->os6.ois_extern_target
  640. X#define    uses_extern_target(x) (x)->os6.ouses_extern_target
  641. X#define    is_key(x)    (x)->os6.ois_key
  642. X#define    has_key(x)    (x)->os6.ohas_key
  643. X
  644. X#define    target_state(x)    (x)->os7.otarget_state
  645. X#define    target_val(x)    (x)->os7.otarget_val
  646. X#define    target_file(x)    (x)->os7.otarget_file
  647. X#define    target_seq(x)    (x)->os7.otarget_seq
  648. X#define    target_pos(x)    (x)->os7.otarget_pos
  649. X#define    cr_file(x)    (x)->os7.ocr_file
  650. X#define    cr_seq(x)    (x)->os7.ocr_seq
  651. X#define    gall_seq(x)    (x)->os7.ogall_seq
  652. X#define    symb(x)        (x)->os7.osymb
  653. X#define    gall_tag(x)    (x)->os7.ogall_tag
  654. X#define    gall_tfile(x)    (x)->os7.ogall_tfile
  655. X#define    gentag_file(x)    (x)->os7.ogentag_file
  656. X#define    gentag_seq(x)    (x)->os7.ogentag_seq
  657. X#define    gentag_fseq(x) (x)->os7.ogentag_fseq
  658. X
  659. X#define    filep(x)    (x)->os1.ou3.ofilep
  660. X/* #define    gall_sym(x)    (x)->os1.ou3.ogall_sym */
  661. X#define    gall_pos(x)    (x)->os1.ou4.ogall_pos
  662. X#define    left_pos(x)    fwd(x, COL)
  663. X#define    save_scope(x)    fwd(x, ROW)
  664. X
  665. X#define    eg_fnum(x)    (x)->os8.oeg_fnum
  666. X#define    eg_fpos(x)    (x)->os8.oeg_fpos
  667. X#define    eg_cont(x)    (x)->os8.oeg_cont
  668. X#define    eg_symbol(x)    (x)->os8.oeg_symbol
  669. X#define    eg_scope(x)    (x)->os8.oeg_scope
  670. X
  671. X#define    item(x)        (x)->os9.oitem
  672. X#define    next(x)        (x)->os9.onext
  673. X
  674. X/*@::object types@************************************************************/
  675. X/*                                                                           */
  676. X/*  OBJECT, TOKEN AND OTHER TYPES inhabiting type(x) and predefined(x)       */
  677. X/*                                                                           */
  678. X/*  Key letters in the adjacent comment indicate where the tag is legal:     */
  679. X/*                                                                           */
  680. X/*    t  a token type, pushed on token stack                                 */
  681. X/*    o  an object type (returned by reduce(), inserted by Manifest)         */
  682. X/*    i  an index type (a child of a galley header other than an object)     */
  683. X/*    s  a predefined symbol (some symbol table entry has this predefined()) */
  684. X/*    n  an indefinite object i.e. one which is ignored in catenation ops    */
  685. X/*                                                                           */
  686. X/*****************************************************************************/
  687. X
  688. X#define    LINK         0        /*        a link between objects     */
  689. X#define    GAP_OBJ         1        /*  o     a gap object               */
  690. X#define    CLOSURE         2        /* to  n  a closure of a symbol      */
  691. X#define    NULL_CLOS     3        /* to sn  @Null                      */
  692. X#define    CROSS         4        /* to sn  && (a cross reference obj) */
  693. X#define    HEAD         5        /*  o  n  a galley header            */
  694. X#define    SPLIT         6        /*  o     @Split                     */
  695. X#define    PAR         7        /*  o     a parameter of a closure   */
  696. X#define    WORD         8        /*  o     a literal word             */
  697. X#define    ROW_THR         9        /*  o     a row thread               */
  698. X#define    COL_THR        10        /*  o     a column thread            */
  699. X#define    ACAT        11        /* to s   a sequence of &-ed objs    */
  700. X#define    HCAT        12        /* to s   a sequence of |-ed objs    */
  701. X#define    VCAT        13        /* to s   a sequence of /-ed objs    */
  702. X#define    ONE_COL        14        /* to s   @OneCol                    */
  703. X#define    ONE_ROW        15        /* to s   @OneRow                    */
  704. X#define    WIDE        16        /* to s   @Wide                      */
  705. X#define    HIGH        17        /* to s   @High                      */
  706. X#define    HSCALE        18        /* to s   @HScale                    */
  707. X#define    VSCALE        19        /* to s   @HScale                    */
  708. X#define    SCALE        20        /* to s   @Scale                     */
  709. X#define    HCONTRACT    21        /* to s   @HContract                 */
  710. X#define    VCONTRACT    22        /* to s   @VContract                 */
  711. X#define    HEXPAND        23        /* to s   @HExpand                   */
  712. X#define    VEXPAND        24        /* to s   @VExpand                   */
  713. X#define    PADJUST        25        /* to s   @PAdjust                   */
  714. X#define    HADJUST        26        /* to s   @HAdjust                   */
  715. X#define    VADJUST        27        /* to s   @VAdjust                   */
  716. X#define    ROTATE        28        /* to s   @Rotate                    */
  717. X#define    CASE        29        /* to s   @Case                      */
  718. X#define    YIELD        30        /* to s   @Yield                     */
  719. X#define    FONT        31        /* to s   @Font                      */
  720. X#define    SPACE        32        /* to s   @Space                     */
  721. X#define    BREAK        33        /* to s   @Break                     */
  722. X#define    NEXT        34        /* to s   @Next                      */
  723. X#define    ENV        35        /* to s   @LEnv                      */
  724. X#define    CLOS        36        /* to s   @LClos                     */
  725. X#define    LVIS        37        /* to s   @LVis                      */
  726. X#define    OPEN        38        /* to s   @Open                      */
  727. X#define    TAGGED        39        /* to s   @Tagged                    */
  728. X#define    INCGRAPHIC    40        /* to s   @IncludeGraphic            */
  729. X#define    SINCGRAPHIC    41        /* to s   @SysIncludeGraphic         */
  730. X#define    GRAPHIC        42        /* to s   @Graphic                   */
  731. X
  732. X#define    TSPACE        43        /* t      a space token, parser only */
  733. X#define    TJUXTA        44        /* t      a juxta token, parser only */
  734. X#define    LBR        45        /* t  s   left brace token           */
  735. X#define    RBR        46        /* t  s   right brace token          */
  736. X#define    BEGIN        47        /* t  s   @Begin token               */
  737. X#define    END        48        /* t  s   @End token                 */
  738. X#define    USE        49        /* t  s   @Use                       */
  739. X#define    GSTUB_NONE    50        /* t      a galley stub, no rpar     */
  740. X#define    GSTUB_INT    51        /* t      galley stub internal rpar  */
  741. X#define    GSTUB_EXT    52        /* t      galley stub external rpar  */
  742. X#define    INCLUDE        53        /*    s   @Include                   */
  743. X#define    SYS_INCLUDE    54        /*    s   @SysInclude                */
  744. X#define    PREPEND        55        /*    s   @Prepend                   */
  745. X#define    SYS_PREPEND    56        /*    s   @SysPrepend                */
  746. X#define    DATABASE    57        /*    s   @Database                  */
  747. X#define    SYS_DATABASE    58        /*    s   @SysDatabase               */
  748. X#define    START        59        /*    s   \Start                     */
  749. X
  750. X#define    DEAD        60        /*   i    a dead galley              */
  751. X#define    UNATTACHED    61        /*   i    an inner, unsized galley   */
  752. X#define    CLOSE_INDEX    62        /*   i    synchronize galley closing */
  753. X#define    RECEPTIVE    63        /*   i    a receptive object index   */
  754. X#define    RECEIVING    64        /*   i    a receiving object index   */
  755. X#define    RECURSIVE    65        /*   i    a recursive definite obj.  */
  756. X#define    PRECEDES    66        /*   i    an ordering constraint     */
  757. X#define    FOLLOWS        67        /*   i    other end of ordering c.   */
  758. X#define    CROSS_FOLL    68        /*   i    following type cross-ref   */
  759. X#define    GALL_FOLL    69        /*   i    galley with &&following    */
  760. X#define    CROSS_TARG    70        /*   i    value of cross-ref         */
  761. X#define    GALL_TARG    71        /*   i    target of these galleys    */
  762. X#define    GALL_PREC    72        /*   i    galley with &&preceding    */
  763. X#define    CROSS_PREC    73        /*   i    preceding type cross-ref   */
  764. X#define    EXPAND_IND    74        /*   i    index of HEXPAND or VEXPD  */
  765. X#define    THREAD        75        /*        a sequence of threads      */
  766. X#define    CROSS_SYM    76        /*        cross-ref info             */
  767. X#define    CR_ROOT        77        /*        RootCross                  */
  768. X#define    MACRO        78        /*        a macro symbol             */
  769. X#define    LOCAL        79        /*        a local symbol             */
  770. X#define    LPAR        80        /*        a left parameter           */
  771. X#define    NPAR        81        /*        a named parameter          */
  772. X#define    RPAR        82        /*        a right parameter          */
  773. X#define    EXT_GALL    83        /*        an external galley         */
  774. X#define    CR_LIST        84        /*        a list of cross references */
  775. X#define    DISPOSED    85        /*        a disposed record          */
  776. X
  777. X#define is_indefinite(x)  ((x) >= CLOSURE && (x) <= HEAD)
  778. X#define is_definite(x)      ((x) >= SPLIT && (x) <= GRAPHIC)
  779. X#define    is_par(x)    ((x) >= LPAR   && (x) <= RPAR)
  780. X#define    is_index(x)    ((x) >= DEAD && (x) <= EXPAND_IND)
  781. X#define    is_type(x)    ((x) >= LINK && (x) < DISPOSED)
  782. X#define    is_filecom(x)    ((x) >= INCLUDE && (x) <= SYS_DATABASE)
  783. X
  784. X/*@::miscellaneous constants@*************************************************/
  785. X/*                                                                           */
  786. X/*  Miscellaneous Globally Defined Constants                                 */
  787. X/*                                                                           */
  788. X/*****************************************************************************/
  789. X
  790. X/* gap modes occupying mode(x) */
  791. X#define    NO_MODE        0        /* for error detection: no mode      */
  792. X#define    EDGE_MODE    1        /* edge-to-edge spacing              */
  793. X#define    HYPH_MODE    2        /* edge-to-edge with hyphenation     */
  794. X#define    MARK_MODE    3        /* mark-to-mark spacing              */
  795. X#define    OVER_MODE    4        /* overstrike spacing                */
  796. X#define    KERN_MODE    5        /* kerning spacing                   */
  797. X#define    TAB_MODE    6        /* tabulation spacing                */
  798. X#define    ADD_HYPH    7        /* temp value used by FillObject     */
  799. X
  800. X/* hyph_style(style) options                                                 */
  801. X#define    HYPH_UNDEF    0        /* hyphenation option undefined      */
  802. X#define    HYPH_OFF    1        /* hyphenation off                   */
  803. X#define    HYPH_ON        2        /* hyphenation on                    */
  804. X
  805. X/* fill_style(style) options                                                 */
  806. X#define    FILL_UNDEF    0        /* fill option undefined             */
  807. X#define    FILL_OFF    1        /* no filling of lines               */
  808. X#define    FILL_ON        2        /* fill lines with text              */
  809. X
  810. X/* display_style(style) options                                              */
  811. X#define    DISPLAY_UNDEF    0        /* display option undefined          */
  812. X#define    DISPLAY_ADJUST    1        /* adjust lines (except last)        */
  813. X#define    DISPLAY_OUTDENT    2        /* outdent lines (except first)      */
  814. X#define    DISPLAY_LEFT    3        /* left-justify lines, no adjust     */
  815. X#define    DISPLAY_CENTRE    4        /* centre lines, no adjust           */
  816. X#define    DISPLAY_RIGHT    5        /* right-justify lines, no adjust    */
  817. X#define    DO_ADJUST    6        /* placed in ACATs when adjust need  */
  818. X
  819. X/* sides of a mark */
  820. X#define    BACK        86        /* means 'lies to left of mark'      */
  821. X#define    ON        87        /* means 'lies on mark'              */
  822. X#define    FWD        88        /* means 'lies to right of mark'     */
  823. X
  824. X/* statuses of thread objects */
  825. X#define    NOTSIZED     0        /* this thread object is not sized   */
  826. X#define    SIZED         1        /* thread is sized but not printed   */
  827. X#define    FINALSIZE     2        /* thread object's size is now final */
  828. X
  829. X/* constraint statuses */
  830. X#define    PROMOTE        89        /* this component may be promoted    */
  831. X#define    CLOSE        90        /* must close dest before promoting  */
  832. X#define    BLOCK        91        /* cannot promote this component     */
  833. X#define    CLEAR        92        /* this constraint is now satisfied  */
  834. X
  835. X/* gap increment types */
  836. X#define    ABS        93        /* absolute,  e.g.  3p               */
  837. X#define    INC        94        /* increment, e.g. +3p               */
  838. X#define    DEC        95        /* decrement, e.g. -3p               */
  839. X
  840. X/* file types */
  841. X#define    SOURCE_FILE     0        /* input file from command line      */
  842. X#define    INCLUDE_FILE     1        /* @Include file                     */
  843. X#define    INCGRAPHIC_FILE     2        /* @IncludeGraphic file              */
  844. X#define    DATABASE_FILE     3        /* database file                     */
  845. X#define    INDEX_FILE     4        /* database index file               */
  846. X#define    FONT_FILE     5        /* font file                         */
  847. X#define    PREPEND_FILE     6        /* PostScript prologue file          */
  848. X#define    HYPH_FILE     7        /* hyphenation file                  */
  849. X#define    HYPH_PACKED_FILE 8        /* packed hyphenation file           */
  850. X
  851. X/* path types (i.e. sequences of directories for file searching) */
  852. X#define    SOURCE_PATH     0        /* path to search for source files   */
  853. X#define    INCLUDE_PATH     1        /* path for @Include files           */
  854. X#define    SYSINCLUDE_PATH     2        /* path for @SysInclude files        */
  855. X#define    DATABASE_PATH     3        /* path for @Database files          */
  856. X#define    SYSDATABASE_PATH 4        /* path for @SysDatabase files       */
  857. X#define    FONT_PATH     5        /* path for fontdef files            */
  858. X
  859. X/* units of measurement */
  860. X#define    NO_UNIT         0        /* no unit - for error detection     */
  861. X#define    FIXED_UNIT     1        /* inches, cm, points, ems           */
  862. X#define    FRAME_UNIT     2        /* f's (frame widths)                */
  863. X#define    AVAIL_UNIT     3        /* a's (available spaces)            */
  864. X#define    DEG_UNIT     4        /* d's (degrees)                     */
  865. X#define    NEXT_UNIT     5        /* b's (inners)                      */
  866. X/* units of distance as multiples of the basic unit */
  867. X#define    CM           567        /* 1 centimetre                      */
  868. X#define    IN          1440        /* 1 inch                            */
  869. X#define    EM           120        /* 1 em (= 1/12 inch)                */
  870. X#define    PT        20        /* 1 point (= 1/72 inch)             */
  871. X#define    FR          4096        /* virtual unit for frame units      */
  872. X#define    DG           128        /* virtual unit for degrees          */
  873. X#define    SF           128        /* virtual unit for @Scale factors   */
  874. X
  875. X/* precedences */
  876. X#define    NO_PREC         0        /* lower than any precedence         */
  877. X#define    BEGIN_PREC     1        /* precedence of '@Begin'            */
  878. X#define    END_PREC     2        /* precedence of '@End'              */
  879. X#define    LBR_PREC     3        /* precedence of '{'                 */
  880. X#define    RBR_PREC     4        /* precedence of '}'                 */
  881. X#define    VCAT_PREC     5        /* precedence of /                   */
  882. X#define    HCAT_PREC     6        /* precedence of |                   */
  883. X#define    ACAT_PREC     7        /* precedence of & and white space   */
  884. X#define    MIN_PREC        10        /* minimum precedence of user ops    */
  885. X#define    MAX_PREC       100        /* maximim precedence of user ops    */
  886. X#define    DEFAULT_PREC   100        /* default precedence of user ops    */
  887. X#define CROSSOP_PREC   101        /* precedence of cross op &&         */
  888. X#define GAP_PREC       102        /* precedence of gap op after cat op */
  889. X#define JUXTA_PREC     103        /* precedence of juxtaposition &     */
  890. X#define    FORCE_PREC     104        /* higher than any precedence        */
  891. X
  892. X/* error types */
  893. X#define    INTERN    0            /* internal error (i.e. bug)         */
  894. X#define    FATAL    1            /* fatal error, abort now            */
  895. X#define    WARN    2            /* warning, non-fatal                */
  896. X
  897. X/*@::keywords@****************************************************************/
  898. X/*                                                                           */
  899. X/*  KEYWORDS                                                                 */
  900. X/*                                                                           */
  901. X/*****************************************************************************/
  902. X
  903. X#define    KW_DEF        "def"
  904. X#define    KW_FONTDEF    "fontdef"
  905. X#define    KW_FORCE    "force"
  906. X#define    KW_INTO        "into"
  907. X#define    KW_IMPORT    "import"
  908. X#define    KW_EXPORT    "export"
  909. X#define    KW_PRECEDENCE    "precedence"
  910. X#define    KW_ASSOC    "associativity"
  911. X#define    KW_LEFT        "left"
  912. X#define    KW_RIGHT    "right"
  913. X#define    KW_BODY        "body"
  914. X#define    KW_MACRO    "macro"
  915. X#define    KW_NAMED    "named"
  916. X#define    KW_NEXT        "@Next"
  917. X#define    KW_WIDE        "@Wide"
  918. X#define    KW_HIGH        "@High"
  919. X#define    KW_ONE_COL    "@OneCol"
  920. X#define    KW_ONE_ROW    "@OneRow"
  921. X#define    KW_HSCALE    "@HScale"
  922. X#define    KW_VSCALE    "@VScale"
  923. X#define    KW_SCALE    "@Scale"
  924. X#define    KW_HCONTRACT    "@HContract"
  925. X#define    KW_VCONTRACT    "@VContract"
  926. X#define    KW_HEXPAND    "@HExpand"
  927. X#define    KW_VEXPAND    "@VExpand"
  928. X#define    KW_PADJUST    "@PAdjust"
  929. X#define    KW_HADJUST    "@HAdjust"
  930. X#define    KW_VADJUST    "@VAdjust"
  931. X#define    KW_ROTATE    "@Rotate"
  932. X#define    KW_INCGRAPHIC    "@IncludeGraphic"
  933. X#define    KW_SINCGRAPHIC    "@SysIncludeGraphic"
  934. X#define    KW_GRAPHIC    "@Graphic"
  935. X#define    KW_CASE        "@Case"
  936. X#define    KW_YIELD    "@Yield"
  937. X#define    KW_FONT        "@Font"
  938. X#define    KW_SPACE    "@Space"
  939. X#define    KW_BREAK    "@Break"
  940. X#define    KW_ENV        "@LEnv"
  941. X#define    KW_CLOS        "@LClos"
  942. X#define    KW_LVIS        "@LVis"
  943. X#define    KW_OPEN        "@Open"
  944. X#define    KW_USE        "@Use"
  945. X#define    KW_TAGGED    "@Tagged"
  946. X#define    KW_DATABASE    "@Database"
  947. X#define    KW_SYSDATABASE    "@SysDatabase"
  948. X#define    KW_INCLUDE    "@Include"
  949. X#define    KW_SYSINCLUDE    "@SysInclude"
  950. X#define    KW_PREPEND    "@PrependGraphic"
  951. X#define    KW_SYSPREPEND    "@SysPrependGraphic"
  952. X#define    KW_TARGET    "@Target"
  953. X#define    KW_FOLLOWING    "following"
  954. X#define    KW_PRECEDING    "preceding"
  955. X#define    KW_NOW        "now"
  956. X#define    KW_NULL        "@Null"
  957. X#define    KW_GALLEY    "@Galley"
  958. X#define    KW_INPUT    "@LInput"
  959. X#define    KW_SPLIT    "@Split"
  960. X#define    KW_TAG        "@Tag"
  961. X#define    KW_KEY        "@Key"
  962. X#define    KW_CROSS    "&&"
  963. X
  964. X#define    KW_LBR        "{"
  965. X#define    KW_RBR        "}"
  966. X#define    KW_BEGIN    "@Begin"
  967. X#define    KW_END        "@End"
  968. X
  969. X#define    KW_VCAT_NN    "//"
  970. X#define    KW_VCAT_MN    "^//"
  971. X#define    KW_VCAT_NJ    "/"
  972. X#define    KW_VCAT_MJ    "^/"
  973. X#define    KW_HCAT_NN    "||"
  974. X#define    KW_HCAT_MN    "^||"
  975. X#define    KW_HCAT_NJ    "|"
  976. X#define    KW_HCAT_MJ    "^|"
  977. X#define    KW_ACAT_NJ    "&"
  978. X#define    KW_ACAT_MJ    "^&"
  979. X
  980. X
  981. X/*@::memory allocation and list macros@***************************************/
  982. X/*                                                                           */
  983. X/*  OBJECT GetMem(siz, pos)                                                  */
  984. X/*  OBJECT New(typ)                                                          */
  985. X/*  OBJECT NewWord(len, pos)                                                 */
  986. X/*                                                                           */
  987. X/*  Return a pointer to a new record, of appropriate length (in ALIGNs).     */
  988. X/*  The New and NewWord versions initialise LIST, type and rec_size fields.  */
  989. X/*  Note that NewWord must be used for WORD objects.                         */
  990. X/*                                                                           */
  991. X/*****************************************************************************/
  992. X#define    USES_SIZE ceiling( sizeof(struct uses_type), sizeof(ALIGN) )
  993. X
  994. X#if DEBUG_ON
  995. X#define newcount zz_newcount++,
  996. X#else
  997. X#define newcount
  998. X#endif
  999. X
  1000. X#define    GetMem(siz, pos)                        \
  1001. X( newcount                                \
  1002. X  (zz_size=(siz))>=MAX_OBJECT_REC ?                    \
  1003. X      (OBJECT) Error(FATAL,pos,"word is too long")            \
  1004. X  : zz_free[zz_size] == nil ? zz_hold = GetMemory(zz_size, pos)        \
  1005. X  : (zz_hold = zz_free[zz_size],                    \
  1006. X    zz_free[zz_size] = pred(zz_hold, CHILD), zz_hold)        \
  1007. X)
  1008. X
  1009. X#if DEBUG_ON
  1010. X#define checknew(typ)                            \
  1011. X  !is_type(typ) ? Error(INTERN, no_fpos,"New: type = %s", Image(typ)) :    \
  1012. X  zz_lengths[typ] == 0 ? Error(INTERN, no_fpos, "New: 0 length!") : 0,
  1013. X#else
  1014. X#define checknew(typ)
  1015. X#endif
  1016. X
  1017. X#define    New(typ)                            \
  1018. X( checknew(typ)                                \
  1019. X  GetMem(zz_lengths[typ], no_fpos),                    \
  1020. X  type(zz_hold) = typ,                            \
  1021. X  pred(zz_hold, CHILD)  = succ(zz_hold, CHILD)  =            \
  1022. X  pred(zz_hold, PARENT) = succ(zz_hold, PARENT) = zz_hold        \
  1023. X)
  1024. X
  1025. X#define NewWord(len, pos)                        \
  1026. X( zz_size = sizeof(struct word_type) + (len) - 3,            \
  1027. X  GetMem(ceiling(zz_size, sizeof(ALIGN)), pos),  /* RESETS zz_size */    \
  1028. X  rec_size(zz_hold) = zz_size,  type(zz_hold) = WORD,            \
  1029. X  pred(zz_hold, CHILD)  = succ(zz_hold, CHILD)  =            \
  1030. X  pred(zz_hold, PARENT) = succ(zz_hold, PARENT) = zz_hold        \
  1031. X)
  1032. X
  1033. X
  1034. X/*****************************************************************************/
  1035. X/*                                                                           */
  1036. X/*  PutMem(x, siz)                                                           */
  1037. X/*  Dispose(x)                                                               */
  1038. X/*                                                                           */
  1039. X/*  Dispose x, which is of size siz.  Dispose works out the size itself.     */
  1040. X/*                                                                           */
  1041. X/*****************************************************************************/
  1042. X
  1043. X#if DEBUG_ON
  1044. X#define disposecount zz_disposecount++,
  1045. X#define    setdisposed  , type(zz_hold) = DISPOSED
  1046. X#else
  1047. X#define disposecount
  1048. X#define    setdisposed
  1049. X#endif
  1050. X
  1051. X#define PutMem(x, siz)                            \
  1052. X( disposecount                                \
  1053. X  zz_hold = (x),                            \
  1054. X  zz_size = (siz),                            \
  1055. X  pred(zz_hold, CHILD) = zz_free[zz_size],                \
  1056. X  zz_free[zz_size] = zz_hold                        \
  1057. X)
  1058. X
  1059. X#define Dispose(x)                            \
  1060. X( zz_hold = (x),                            \
  1061. X  assert( pred(zz_hold, CHILD)  == zz_hold, "Dispose: pred(CHILD)!"  ),    \
  1062. X  assert( succ(zz_hold, CHILD)  == zz_hold, "Dispose: succ(CHILD)!"  ),    \
  1063. X  assert( pred(zz_hold, PARENT) == zz_hold, "Dispose: pred(PARENT)!" ),    \
  1064. X  assert( succ(zz_hold, PARENT) == zz_hold, "Dispose: succ(PARENT)!" ),    \
  1065. X  PutMem(zz_hold, type(zz_hold) == WORD ? rec_size(zz_hold)        \
  1066. X                  : zz_lengths[type(zz_hold)])        \
  1067. X  setdisposed                                \
  1068. X)
  1069. X
  1070. X/*@@**************************************************************************/
  1071. X/*                                                                           */
  1072. X/*  OBJECT Append(x, y, dir)                                                 */
  1073. X/*                                                                           */
  1074. X/*  Return the append of lists x and y (dir is PARENT or CHILD).             */
  1075. X/*                                                                           */
  1076. X/*****************************************************************************/
  1077. X
  1078. X#define    Append(x, y, dir)                        \
  1079. X( zz_res = (x),    zz_hold = (y),                        \
  1080. X  zz_hold == nil ? zz_res  :                        \
  1081. X  zz_res  == nil ? zz_hold :                        \
  1082. X  ( zz_tmp = pred(zz_hold, dir),                    \
  1083. X    pred(zz_hold, dir) = pred(zz_res, dir),                \
  1084. X    succ(pred(zz_res, dir), dir) = zz_hold,                \
  1085. X    pred(zz_res, dir) = zz_tmp,                        \
  1086. X    succ(zz_tmp, dir) = zz_res                        \
  1087. X  )                                    \
  1088. X)
  1089. X
  1090. X
  1091. X/*****************************************************************************/
  1092. X/*                                                                           */
  1093. X/*  OBJECT Delete(x, dir)                                                    */
  1094. X/*                                                                           */
  1095. X/*  Delete x from its dir list, and return succ(x, dir) or nil if none.      */
  1096. X/*                                                                           */
  1097. X/*****************************************************************************/
  1098. X
  1099. X#define Delete(x, dir)                            \
  1100. X( zz_hold = (x),                            \
  1101. X  succ(zz_hold, dir) == zz_hold ? nil :                    \
  1102. X  ( zz_res = succ(zz_hold, dir),                    \
  1103. X    pred(zz_res, dir) = pred(zz_hold, dir),                \
  1104. X    succ(pred(zz_hold, dir), dir) = zz_res,                \
  1105. X    pred(zz_hold, dir) = succ(zz_hold, dir) = zz_hold,            \
  1106. X    zz_res                                \
  1107. X  )                                    \
  1108. X)
  1109. X
  1110. X/*****************************************************************************/
  1111. X/*                                                                           */
  1112. X/*  OBJECT DeleteAndDispose(x, dir)                                          */
  1113. X/*                                                                           */
  1114. X/*  Delete x as above, dispose it, and return succ(x, dir) or nil if none.   */
  1115. X/*                                                                           */
  1116. X/*****************************************************************************/
  1117. X
  1118. X#define DeleteAndDispose(x, dir)                    \
  1119. X( zz_hold = (x),                            \
  1120. X  zz_res  = succ(zz_hold, dir) == zz_hold ? nil :            \
  1121. X        ( pred(succ(zz_hold, dir), dir) = pred(zz_hold, dir),    \
  1122. X          succ(pred(zz_hold, dir), dir) = succ(zz_hold, dir) ),    \
  1123. X  pred(zz_hold, dir) = succ(zz_hold, dir) = zz_hold,            \
  1124. X  Dispose(zz_hold),                            \
  1125. X  zz_res                                \
  1126. X)
  1127. X
  1128. X#define Down(x)        succ(x, CHILD)
  1129. X#define NextDown(x)    succ(x, CHILD)
  1130. X#define LastDown(x)    pred(x, CHILD)
  1131. X#define PrevDown(x)    pred(x, CHILD)
  1132. X#define    Up(x)        succ(x, PARENT)
  1133. X#define    NextUp(x)    succ(x, PARENT)
  1134. X#define    LastUp(x)    pred(x, PARENT)
  1135. X#define    PrevUp(x)    pred(x, PARENT)
  1136. X
  1137. X#define    Child(y, link)                            \
  1138. Xfor( y = pred(link, PARENT);  type(y) == LINK;  y = pred(y, PARENT) )
  1139. X
  1140. X#define    Parent(y, link)                            \
  1141. Xfor( y = pred(link, CHILD);   type(y) == LINK;  y = pred(y, CHILD) )
  1142. X
  1143. X
  1144. X/*****************************************************************************/
  1145. X/*                                                                           */
  1146. X/*  UpDim(x, dim)                                                            */
  1147. X/*  DownDim(x, dim)                                                          */
  1148. X/*                                                                           */
  1149. X/*  Returns the dim'th child or parent link of node x (dim == COL or ROW).   */
  1150. X/*                                                                           */
  1151. X/*****************************************************************************/
  1152. X
  1153. X#define UpDim(x, dim)    ( (dim) == COL ? succ(x, PARENT) : pred(x, PARENT) )
  1154. X#define DownDim(x, dim)    ( (dim) == COL ? succ(x, CHILD) : pred(x, CHILD) )
  1155. X
  1156. X
  1157. X/*****************************************************************************/
  1158. X/*                                                                           */
  1159. X/*  OBJECT Link(x, y)                                                        */
  1160. X/*                                                                           */
  1161. X/*  Make y a child of x in the directed graph, using a new link.             */
  1162. X/*  The link node is returned.                                               */
  1163. X/*                                                                           */
  1164. X/*****************************************************************************/
  1165. X
  1166. X#define Link(x, y)                            \
  1167. X( xx_link = New(LINK),                            \
  1168. X  Append(xx_link, (x), CHILD),                        \
  1169. X  Append(xx_link, (y), PARENT)                        \
  1170. X)
  1171. X
  1172. X
  1173. X/*****************************************************************************/
  1174. X/*                                                                           */
  1175. X/*  OBJECT DeleteLink(link)                                                  */
  1176. X/*                                                                           */
  1177. X/*  Cut the link between nodes x and y of the directed graph.                */
  1178. X/*  Returns the link node of the next child of x, or x if none.              */
  1179. X/*                                                                           */
  1180. X/*****************************************************************************/
  1181. X
  1182. X#define DeleteLink(link)                        \
  1183. X( xx_link = (link),                            \
  1184. X  Delete(xx_link, PARENT),                        \
  1185. X  DeleteAndDispose(xx_link, CHILD)                    \
  1186. X)
  1187. X
  1188. X
  1189. X/*@@**************************************************************************/
  1190. X/*                                                                           */
  1191. X/*  DisposeChild(link)                                                       */
  1192. X/*                                                                           */
  1193. X/*  Delete link, and if its child is thereby unattached, dispose it.         */
  1194. X/*                                                                           */
  1195. X/*****************************************************************************/
  1196. X
  1197. X#define DisposeChild(link)                        \
  1198. X( xx_link = (link),                            \
  1199. X  xx_tmp = Delete(xx_link, PARENT),                    \
  1200. X  DeleteAndDispose(xx_link, CHILD),                    \
  1201. X  succ(xx_tmp, PARENT) == xx_tmp ? DisposeObject(xx_tmp) : 0        \
  1202. X) /* end DisposeChild */
  1203. X
  1204. X
  1205. X/*****************************************************************************/
  1206. X/*                                                                           */
  1207. X/*  MoveLink(link, x, dir)                                                   */
  1208. X/*                                                                           */
  1209. X/*  Move the dir end of link from wherever it is now to node x.              */
  1210. X/*                                                                           */
  1211. X/*****************************************************************************/
  1212. X
  1213. X#define MoveLink(link, x, dir)                        \
  1214. X( xx_link = (link),                            \
  1215. X  Delete(xx_link, 1 - (dir) ),                        \
  1216. X  Append(xx_link, (x), 1 - (dir) )                    \
  1217. X) /* end MoveLink */
  1218. X
  1219. X
  1220. X/*****************************************************************************/
  1221. X/*                                                                           */
  1222. X/*  TransferLinks(start_link, stop_link, dest_link)                          */
  1223. X/*                                                                           */
  1224. X/*  Move parent end of links start_link (inclusive) to stop_link (exclusive) */
  1225. X/*  to just before dest_link.                                                */
  1226. X/*                                                                           */
  1227. X/*****************************************************************************/
  1228. X
  1229. X#define TransferLinks(start_link, stop_link, dest_link)            \
  1230. X{ OBJECT xxstart = start_link, xxstop = stop_link, xxdest = dest_link;    \
  1231. X  if( xxstart != xxstop )                        \
  1232. X  {    assert( type(xxstart) == LINK, "TransferLinks: start_link!" );    \
  1233. X    Append(xxstart, xxstop, CHILD); /* actually a split */        \
  1234. X    Append(xxstart, xxdest, CHILD);                    \
  1235. X  }                                    \
  1236. X}
  1237. X
  1238. X
  1239. X/*****************************************************************************/
  1240. X/*                                                                           */
  1241. X/*  DeleteNode(x)                                                            */
  1242. X/*                                                                           */
  1243. X/*  Delete node x and every edge attaching to x.                             */
  1244. X/*                                                                           */
  1245. X/*****************************************************************************/
  1246. X
  1247. X#define DeleteNode(x)                            \
  1248. X{ xx_hold = (x);                            \
  1249. X  while( Up(xx_hold)   != xx_hold ) DeleteLink( Up(xx_hold) );        \
  1250. X  while( Down(xx_hold) != xx_hold ) DeleteLink( Down(xx_hold) );    \
  1251. X  Dispose(xx_hold);                            \
  1252. X}
  1253. X
  1254. X
  1255. X/*****************************************************************************/
  1256. X/*                                                                           */
  1257. X/*  MergeNode(x, y)                                                          */
  1258. X/*                                                                           */
  1259. X/*  Take all the children of y and make them children of x.                  */
  1260. X/*  Take all the parents of y and make them parents of x.  Dispose y.        */
  1261. X/*                                                                           */
  1262. X/*****************************************************************************/
  1263. X
  1264. X#define MergeNode(x, y)                            \
  1265. X{ xx_res = (x); xx_hold = (y);                        \
  1266. X  xx_tmp = Delete(xx_hold, PARENT);                    \
  1267. X  Append(xx_res, xx_tmp, PARENT);                    \
  1268. X  xx_tmp = DeleteAndDispose(xx_hold, CHILD);                \
  1269. X  Append(xx_res, xx_tmp, CHILD);                    \
  1270. X}  /* end MergeNode */
  1271. X
  1272. X
  1273. X/*****************************************************************************/
  1274. X/*                                                                           */
  1275. X/*  ReplaceNode(x, y)                                                        */
  1276. X/*                                                                           */
  1277. X/*  Move all the parent links of y to x.                                     */
  1278. X/*                                                                           */
  1279. X/*****************************************************************************/
  1280. X
  1281. X#define ReplaceNode(x, y)                        \
  1282. X( xx_tmp = Delete((y), PARENT),                        \
  1283. X  Append((x), xx_tmp, PARENT)                        \
  1284. X) /* end ReplaceNode */
  1285. X
  1286. X
  1287. X/*@::scanning catenation objects@*********************************************/
  1288. X/*                                                                           */
  1289. X/*  FirstDefinite(x, link, y)                                                */
  1290. X/*                                                                           */
  1291. X/*  On input, x is an object and link and y are undefined.  On output there  */
  1292. X/*  are two cases:                                                           */
  1293. X/*                                                                           */
  1294. X/*  link != x.  Then y is first definite child of x and link is its link.    */
  1295. X/*                                                                           */
  1296. X/*  link == x.  Then x has no definite child and y is undefined.             */
  1297. X/*                                                                           */
  1298. X/*  A SPLIT object is considered to be definite if both its children are     */
  1299. X/*  definite.  This condition is returned by SplitIsDefinite.                */
  1300. X/*                                                                           */
  1301. X/*****************************************************************************/
  1302. X
  1303. X#define FirstDefinite(x, link, y)                    \
  1304. X{ for( link = Down(x);  link != x;  link = NextDown(link) )        \
  1305. X  { Child(y, link);                            \
  1306. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  1307. X    break;                                \
  1308. X  }                                    \
  1309. X} /* end FirstDefinite */
  1310. X
  1311. X
  1312. X/*****************************************************************************/
  1313. X/*                                                                           */
  1314. X/*  NextDefinite(x, link, y)                                                 */
  1315. X/*                                                                           */
  1316. X/*  On input, x is an object and link is a link to one of its children; y    */
  1317. X/*  is undefined.  On output there are two cases:                            */
  1318. X/*                                                                           */
  1319. X/*  link != x.  Then y is the first definite child of x following link, and  */
  1320. X/*              link is changed to be the link of y.                         */
  1321. X/*                                                                           */
  1322. X/*  link == x.  Then x has no definite child following link, and y remains   */
  1323. X/*              undefined.                                                   */
  1324. X/*                                                                           */
  1325. X/*****************************************************************************/
  1326. X
  1327. X#define NextDefinite(x, link, y)                    \
  1328. X{ for( link = NextDown(link);  link != x;  link = NextDown(link) )    \
  1329. X  { Child(y, link);                            \
  1330. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  1331. X    break;                                \
  1332. X  }                                    \
  1333. X} /* end NextDefinite */
  1334. X
  1335. X
  1336. X/*****************************************************************************/
  1337. X/*                                                                           */
  1338. X/*  NextDefiniteWithGap(x, link, y, g)                                       */
  1339. X/*                                                                           */
  1340. X/*  On input, x is an object and link is a link to one of its children; y    */
  1341. X/*  and g are undefined.  On output there are two cases:                     */
  1342. X/*                                                                           */
  1343. X/*  link != x.  Then y is the first definite child of x following link, and  */
  1344. X/*              link is changed to be the link of y.  Also, g is defined     */
  1345. X/*              to be the gap just before y; this must exist and is tested   */
  1346. X/*              by an assert test.                                           */
  1347. X/*                                                                           */
  1348. X/*  link == x.  Then x has no definite child following link, and y and g     */
  1349. X/*              remain undefined.                                            */
  1350. X/*                                                                           */
  1351. X/*****************************************************************************/
  1352. X
  1353. X#define NextDefiniteWithGap(x, link, y, g)                \
  1354. X{ g = nil;                                \
  1355. X  for( link = NextDown(link);  link != x;  link = NextDown(link) )    \
  1356. X  { Child(y, link);                            \
  1357. X    if( type(y) == GAP_OBJ )  g = y;                    \
  1358. X    else if( type(y)==SPLIT ? SplitIsDefinite(y):is_definite(type(y)) )    \
  1359. X    { assert( g != nil, "NextDefinite: g == nil!" );            \
  1360. X      break;                                \
  1361. X    }                                    \
  1362. X  }                                    \
  1363. X} /* end NextDefiniteWithGap */
  1364. X
  1365. X
  1366. X/*****************************************************************************/
  1367. X/*                                                                           */
  1368. X/*  LastDefinite(x, link, y)                                                 */
  1369. X/*                                                                           */
  1370. X/*  On input, x is an object and link and y are undefined.  On output there  */
  1371. X/*  are two cases:                                                           */
  1372. X/*                                                                           */
  1373. X/*  link != x.  Then y is the last definite child of x and link is its link. */
  1374. X/*                                                                           */
  1375. X/*  link == x.  Then x has no definite child and y is undefined.             */
  1376. X/*                                                                           */
  1377. X/*  A SPLIT object is considered to be definite if both its children are     */
  1378. X/*  definite.  This condition is returned by SplitIsDefinite.                */
  1379. X/*                                                                           */
  1380. X/*****************************************************************************/
  1381. X
  1382. X#define LastDefinite(x, link, y)                    \
  1383. X{ for( link = LastDown(x);  link != x;  link = PrevDown(link) )        \
  1384. X  { Child(y, link);                            \
  1385. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  1386. X    break;                                \
  1387. X  }                                    \
  1388. X} /* end LastDefinite */
  1389. X
  1390. X
  1391. X/*****************************************************************************/
  1392. X/*                                                                           */
  1393. X/*  PrevDefinite(x, link, y)                                                 */
  1394. X/*                                                                           */
  1395. X/*  On input, x is an object and link is a link to one of its children; y    */
  1396. X/*  is undefined.  On output there are two cases:                            */
  1397. X/*                                                                           */
  1398. X/*  link != x.  Then y is the first definite child of x preceding link, and  */
  1399. X/*              link is changed to be the link of y.                         */
  1400. X/*                                                                           */
  1401. X/*  link == x.  Then x has no definite child preceding link, and y remains   */
  1402. X/*              undefined.                                                   */
  1403. X/*                                                                           */
  1404. X/*****************************************************************************/
  1405. X
  1406. X#define PrevDefinite(x, link, y)                    \
  1407. X{ for( link = PrevDown(link);  link != x;  link = PrevDown(link) )    \
  1408. X  { Child(y, link);                            \
  1409. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  1410. X    break;                                \
  1411. X  }                                    \
  1412. X} /* end PrevDefinite */
  1413. X
  1414. X
  1415. X/*@::module declarations@*****************************************************/
  1416. X/*                                                                           */
  1417. X/*  MODULE DECLARATIONS                                                      */
  1418. X/*                                                                           */
  1419. X/*****************************************************************************/
  1420. X
  1421. X/*****  z01.c        Start Up        ******************************/
  1422. Xextern            main();            /* main program              */
  1423. Xextern    OBJECT        StartSym;        /* sym tab entry for \Start  */
  1424. Xextern    OBJECT        GalleySym;        /* sym tab entry for @Galley */
  1425. Xextern    OBJECT        InputSym;        /* sym tab entry for \Input  */
  1426. Xextern    OBJECT        PrintSym;        /* sym tab entry for \Print  */
  1427. Xextern    BOOLEAN        AllowCrossDb;        /* true when -s flag absent  */
  1428. Xextern    BOOLEAN        Encapsulated;        /* true when eps wanted      */
  1429. Xextern    BOOLEAN        StringBeginsWith();    /* string compare            */
  1430. Xextern    BOOLEAN        StringContains();    /* string search             */
  1431. X
  1432. X/*****  z02.c        Lexical Analyser    ******************************/
  1433. Xextern            LexInit();        /* initialise lex. analyser  */
  1434. Xextern            LexPush();        /* switch to new file list   */
  1435. Xextern            LexPop();        /* return to prev. file list */
  1436. Xextern    BOOLEAN        LexLegalName();        /* check identifier format   */
  1437. Xextern    OBJECT        LexGetToken();        /* get next token from input */
  1438. Xextern    long        LexNextTokenPos();    /* like ftell() on curr file */
  1439. X
  1440. X/*****  z03.c        File Service            ******************************/
  1441. Xextern    FILE_POS    *no_fpos;        /* a null filepos            */
  1442. Xextern            InitFiles();        /* initialize this module    */
  1443. Xextern            AddToPath();        /* add directory to path     */
  1444. Xextern    FILE_NUM    DefineFile();        /* declare input file        */
  1445. Xextern    FILE_NUM    FirstFile();        /* first file of given type  */
  1446. Xextern    FILE_NUM    NextFile();        /* next file of given type   */
  1447. Xextern    FILE_NUM    FileNum();        /* file with given name      */
  1448. Xextern    unsigned char    *FileName();        /* file name of file         */
  1449. Xextern    unsigned char    *EchoFilePos();        /* string value of FILE_POS  */
  1450. Xextern    FILE_POS    *PosOfFile();        /* string of file's FILE_POS */
  1451. Xextern    FILE        *OpenFile();        /* open file for reading     */
  1452. Xextern    FILE        *OpenIncGraphicFile();    /* open @IncludeGraphic file */
  1453. Xextern    OBJECT        ReadFromFile();        /* read object from file     */
  1454. Xextern            AppendToFile();        /* append object to file     */
  1455. Xextern            CloseFiles();        /* close database files      */
  1456. X
  1457. X/*****  z04.c        Token Service            ******************************/
  1458. Xextern    OBJECT        NewToken();        /* get a new token           */
  1459. Xextern    OBJECT        CopyTokenList();    /* copy a list of tokens     */
  1460. Xextern    unsigned char    *EchoCatOp();        /* string value of CAT op    */
  1461. Xextern    unsigned char    *EchoToken();        /* returns image of token    */
  1462. X
  1463. X/*****  z05.c        Definitions Reader    ******************************/
  1464. Xextern            ReadDefinitions();    /* read definitions          */
  1465. X
  1466. X/*****  z06.c        Parser            ******************************/
  1467. Xextern            InitParser();        /* initialise parser         */
  1468. Xextern    OBJECT        Parse();        /* parser                    */
  1469. X
  1470. X/*****  z07.c        Object Service            ******************************/
  1471. Xextern    OBJECT        MakeWord();        /* a new WORD object         */
  1472. Xextern    OBJECT        MakeWordTwo();        /* a new WORD object         */
  1473. Xextern    OBJECT        CopyObject();        /* make a copy of an object  */
  1474. Xextern            DisposeObject();    /* dispose an object         */
  1475. Xextern    BOOLEAN        SplitIsDefinite();    /* TRUE if SPLIT is definite */
  1476. X
  1477. X/*****  z08.c        Object Manifest            ******************************/
  1478. Xextern    OBJECT        ReplaceWithTidy();    /* tidy up an object         */
  1479. Xextern    OBJECT        Manifest();        /* manifest an object        */
  1480. X
  1481. X/*****  z09.c        Closure Expansion    ******************************/
  1482. Xextern    OBJECT        SetEnv();        /* build up environment      */
  1483. Xextern            AttachEnv();        /* attach env. to object     */
  1484. Xextern    OBJECT        SearchEnv();        /* search environment        */
  1485. Xextern    OBJECT        GetEnv();        /* retrieve env. from object */
  1486. Xextern    OBJECT        DetachEnv();        /* retrieve and detach env.  */
  1487. Xextern    OBJECT        ClosureExpand();    /* expand a user-def CLOSURE */
  1488. X
  1489. X/*****  z10.c        Cross References    ******************************/
  1490. Xextern            CrossInit();        /* initialize cr record      */
  1491. Xextern    OBJECT        CrossGenTag();        /* generates a tag           */
  1492. Xextern    OBJECT        CrossMake();        /* returns a cross-reference */
  1493. Xextern    OBJECT        GallTargEval();        /* returns the value of a cr */
  1494. Xextern    OBJECT        CrossExpand();        /* returns the value of a cr */
  1495. Xextern            CrossSequence();    /* record cr off root galley */
  1496. Xextern            CrossClose();        /* close down this module    */
  1497. X
  1498. X/*****  z11.c        Style Service        ******************************/
  1499. Xextern            BreakChange();        /* change line spacing       */
  1500. Xextern            SpaceChange();        /* change word spacing       */
  1501. Xextern    unsigned char    *EchoStyle();        /* string value of a style   */
  1502. X
  1503. X/*****  z12.c        Size Finder        ******************************/
  1504. Xextern    OBJECT        MinSize();        /* min. possible size of obj */
  1505. X
  1506. X/*****  z13.c        Object Breaking        ******************************/
  1507. Xextern    OBJECT        BreakObject();        /* break object to fit width */
  1508. X
  1509. X/*****  z14.c        Object Filling            ******************************/
  1510. Xextern    OBJECT        FillObject();        /* optimal paragraph breaker */
  1511. Xextern    OBJECT        SimpleFillObject();    /* simple paragraph breaker  */
  1512. X
  1513. X/*****  z15.c        Size Constraints    ******************************/
  1514. Xextern    unsigned char    *EchoConstraint();    /* string value of a constr. */
  1515. Xextern            MinConstraint();    /* take minimum of two const */
  1516. Xextern            EnlargeToConstraint();    /* enlarge obj to constraint */
  1517. Xextern            RotateConstraint();    /* rotate constraints        */
  1518. Xextern            InvScaleConstraint();    /* inverse scale a constr.   */
  1519. Xextern            Constrained();        /* finds size constraint     */
  1520. Xextern            DebugConstrained();    /* debug constraint code     */
  1521. X
  1522. X/*****  z16.c        Size Adjustments    ******************************/
  1523. Xextern            SetNeighbours();    /* locate definite neighbours*/
  1524. Xextern            AdjustSize();        /* updates sizes if changed  */
  1525. X
  1526. X/*****  z17.c        Gap Widths        ******************************/
  1527. Xextern            GetGap();        /* convert string gap to num */
  1528. Xextern    LENGTH        MinGap();        /* min. possible gap width   */
  1529. Xextern    LENGTH        ExtraGap();        /* extra available gap width */
  1530. Xextern    LENGTH        ActualGap();        /* gap width for output      */
  1531. Xextern    unsigned char    *EchoGap();        /* echo gap (cat. operator)  */
  1532. X
  1533. X/*****  z18.c        Galley Transfer        ******************************/
  1534. Xextern            TransferInit();        /* initialise this module    */
  1535. Xextern    OBJECT        TransferBegin();    /* begin transfer of galley  */
  1536. Xextern            TransferComponent();    /* transfer one component    */
  1537. Xextern            TransferEnd();        /* end galley transfer       */
  1538. Xextern            TransferClose();    /* close this module         */
  1539. X
  1540. X/*****  z19.c        Galley Attaching    ******************************/
  1541. Xextern    OBJECT        SearchGalley();        /* search galley for target  */
  1542. Xextern            AttachGalley();        /* start off a galley        */
  1543. Xextern            DetachGalley();        /* detach a galley           */
  1544. X
  1545. X/*****  z20.c        Galley Flushing        ******************************/
  1546. Xextern            FlushGalley();        /* flush out a galley        */
  1547. X
  1548. X/***    z21.c        Galley Maker        ******************************/
  1549. Xextern            SizeGalley();        /* convert object to galley  */
  1550. X
  1551. X/***    z22.c        Galley Service        ******************************/
  1552. Xextern            FlushInners();        /* flush a list of galleys.  */
  1553. Xextern            ExpandRecursives();    /* expand recursive definite */
  1554. Xextern            Promote();        /* promote components        */
  1555. Xextern            KillGalley();        /* destroy a galley          */
  1556. Xextern            FreeGalley();        /* free a galley to flush    */
  1557. Xextern            Interpose();        /* interpose a VCAT          */
  1558. Xextern    BOOLEAN        TargetSymbol();        /* find target of galley     */
  1559. Xextern    int        CheckConstraint();    /* check ordering constraint */
  1560. X
  1561. X/*****  z23.c        Galley Printer        ******************************/
  1562. Xextern            FixAndPrintObject();    /* fix and print component   */
  1563. X
  1564. X/*****  z24.c        Back End                ******************************/
  1565. Xextern            PrintInit();        /* initialise this module    */
  1566. Xextern            FontStripQuotes();    /* convert quoted string     */
  1567. Xextern            FontDefine();        /* define a font             */
  1568. Xextern            FontChange();        /* change current font       */
  1569. Xextern            FontAtomSize();        /* set sizes of an atom      */
  1570. Xextern    LENGTH        FontSize();        /* size of current font      */
  1571. Xextern            PrintPrologue();    /* print output prologue     */
  1572. Xextern            PrintOriginIncrement();    /* reset current o/p origin  */
  1573. Xextern            PrintAtom();        /* print atom at given pos   */
  1574. Xextern            PrintClose();        /* wrapup output stream      */
  1575. Xextern            CoordTranslate();    /* translate coord system    */
  1576. Xextern            CoordRotate();        /* rotate coord system       */
  1577. Xextern            CoordScale();        /* scale coord system        */
  1578. Xextern            SaveGraphicState();    /* save coord system etc.    */
  1579. Xextern            RestoreGraphicState();    /* restore coord system etc. */
  1580. Xextern            DefineGraphicNames();    /* define xsize, ysize, etc. */
  1581. Xextern            PrintGraphicObject();    /* print PostScript object   */
  1582. Xextern            PrintGraphicInclude();    /* include PostScript file   */
  1583. X
  1584. X/*****  z25.c        Object Echo            ******************************/
  1585. Xextern    unsigned char    *EchoObject();        /* print object, file or str */
  1586. X
  1587. X/*****  z26.c        Echo Service            ******************************/
  1588. Xextern            BeginString();        /* begin string accumulator  */
  1589. Xextern            AppendString();        /* append to current string  */
  1590. Xextern    unsigned char    *EndString();        /* return current string     */
  1591. Xextern    unsigned char    *EchoLength();        /* echo a length             */
  1592. Xextern    unsigned char    *Image();        /* string value of type(x)   */
  1593. X
  1594. X/*****    z27.c        Debug Service        ******************************/
  1595. Xextern            DebugInit();        /* set debug flag            */
  1596. Xextern            Debug();        /* print debug o/p on stderr */
  1597. Xextern            ProfileOn();        /* start profiling           */
  1598. Xextern            ProfileOff();        /* stop profiling            */
  1599. Xextern            ProfilePrint();        /* print profiling results   */
  1600. X
  1601. X/*****    z28.c        Error Service        ******************************/
  1602. Xextern            ErrorInit();        /* initialise log file       */
  1603. Xextern            Error();        /* print error message       */
  1604. Xextern    BOOLEAN        ErrorSeen();        /* TRUE after first error    */
  1605. Xextern            EnterErrorBlock();    /* new block of error mess's */
  1606. Xextern            LeaveErrorBlock();    /* commit or discard block   */
  1607. X
  1608. X/*****  z29.c        Symbol Table        ******************************/
  1609. Xextern            InitSym();        /* initialize table to empty */
  1610. Xextern            PushScope();        /* push a new scope on stack */
  1611. Xextern            PopScope();        /* pop a scope from stack    */
  1612. Xextern            SuppressVisible();    /* suppress visible flag     */
  1613. Xextern            UnSuppressVisible();    /* unsuppress visible flag   */
  1614. Xextern            SuppressScope();    /* suppress all scoping      */
  1615. Xextern            UnSuppressScope();    /* unsuppress scoping        */
  1616. Xextern            SwitchScope();        /* switch to a saved scope   */
  1617. Xextern            UnSwitchScope();    /* switch back from saved s. */
  1618. Xextern            BodyParAllowed();    /* let body par be invoked   */
  1619. Xextern            BodyParNotAllowed();    /* don't let body par be inv */
  1620. Xextern    OBJECT        SearchSym();        /* search table for symbol   */
  1621. Xextern    OBJECT        InsertSym();        /* insert a new symbol       */
  1622. Xextern            DeleteEverySym();    /* dispose all symbols       */
  1623. Xextern    unsigned char    *SymName();        /* string name of a symbol   */
  1624. Xextern    unsigned char    *FullSymName();        /* full path name of symbol  */
  1625. Xextern    OBJECT        ChildSym();        /* return a child of a sym   */
  1626. Xextern            CheckSymSpread();    /* check hash table spread   */
  1627. X
  1628. X/*****  z30.c        Symbol Uses        ******************************/
  1629. Xextern            InsertUses();        /* record symbol x uses y    */
  1630. Xextern            FlattenUses();        /* massage uses relation     */
  1631. Xextern    BOOLEAN        SearchUses();        /* retrieve uses info        */
  1632. Xextern    OBJECT        FirstExternTarget();    /* together these return all */
  1633. Xextern    OBJECT        NextExternTarget();    /*   targets of extern galls */
  1634. X
  1635. X/*****  z31.c        Memory Allocator    ******************************/
  1636. Xextern            MemInit();        /* initialise mem. allocator */
  1637. Xextern    OBJECT        GetMemory();        /* get some fresh memory     */
  1638. Xextern            DebugMemory();        /* print memory usage        */
  1639. Xextern    OBJECT        zz_free[];        /* array of free lists       */
  1640. Xextern    unsigned char    zz_lengths[];        /* array of record lengths   */
  1641. Xextern    int        zz_newcount;        /* debug count of New calls  */
  1642. Xextern    int        zz_disposecount;    /* debug count of Disposes   */
  1643. Xextern    OBJECT        zz_hold;        /* temporary variable only   */
  1644. Xextern    OBJECT        zz_tmp;            /* temporary variable only   */
  1645. Xextern    OBJECT        zz_res;            /* temporary variable only   */
  1646. Xextern    int        zz_size;        /* temporary variable only   */
  1647. Xextern    OBJECT        xx_link, xx_tmp;    /* temporary variable only   */
  1648. Xextern    OBJECT        xx_hold, xx_res;    /* temporary variable only   */
  1649. X
  1650. X/*****  z32.c        Counter Service        ******************************/
  1651. Xextern    OBJECT        Next();            /* increment argument by one */
  1652. X
  1653. X/*****  z33.c        Database Service    ******************************/
  1654. Xextern    OBJECT        OldCrossDb;        /* cross refs from last run  */
  1655. Xextern    OBJECT        NewCrossDb;        /* cross refs from this run  */
  1656. Xextern    OBJECT        DbCreate();        /* create writable database  */
  1657. Xextern            DbInsert();        /* insert into database      */
  1658. Xextern            DbConvert();        /* con. writable to readable */
  1659. Xextern    OBJECT        DbLoad();        /* open readable database    */
  1660. Xextern    BOOLEAN        DbRetrieve();        /* retrieve from database    */
  1661. Xextern    BOOLEAN        DbRetrieveNext();    /* next entry from database  */
  1662. X
  1663. X/*****  z34.c        Rotation Service        ******************************/
  1664. Xextern            RotateSize();        /* calculate rotated size    */
  1665. X
  1666. X/*****  z35.c        Time Keeper         ******************************/
  1667. Xextern    OBJECT        MomentSym;        /* the @Moment symbol        */
  1668. Xextern            InitTime();        /* initialize this module    */
  1669. Xextern    OBJECT        StartMoment();        /* a copy of the init time   */
  1670. Xextern    unsigned char    *TimeString();        /* a string containing time  */
  1671. X
  1672. X/*****  z36.c        Hyphenation         ******************************/
  1673. Xextern    OBJECT        Hyphenate();        /* hyphenate a paragraph     */
  1674. X
  1675. X/*@::assert and debug code@***************************************************/
  1676. X/*                                                                           */
  1677. X/*  ASSERT AND DEBUG CODE                                                    */
  1678. X/*                                                                           */
  1679. X/*****************************************************************************/
  1680. X
  1681. X#if ASSERT_ON
  1682. X#define assert(c, m)                            \
  1683. X   ( (c) ? 0 : Error(INTERN, no_fpos, "Assert failed in %s", m) )
  1684. X#else
  1685. X#define assert(c, m)    0
  1686. X#endif
  1687. X
  1688. X#if DEBUG_ON
  1689. X
  1690. Xstruct dbs
  1691. X{    unsigned char    *flag;        /* external names for debug flags    */
  1692. X    BOOLEAN    on[3];            /* the debug flags                   */
  1693. X};
  1694. Xextern    struct dbs     dbg[];
  1695. X
  1696. X/* debug routines */
  1697. X#define debug0(cat, urg, str)                                \
  1698. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str); else
  1699. X#define debug1(cat, urg, str, p1)                    \
  1700. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1); else
  1701. X#define debug2(cat, urg, str, p1, p2)                    \
  1702. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2); else
  1703. X#define debug3(cat, urg, str, p1, p2, p3)                \
  1704. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3); else
  1705. X#define debug4(cat, urg, str, p1, p2, p3, p4)                \
  1706. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4); else
  1707. X#define debug5(cat, urg, str, p1, p2, p3, p4, p5)            \
  1708. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4, p5); else
  1709. X#define debug6(cat, urg, str, p1, p2, p3, p4, p5, p6)            \
  1710. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4, p5, p6); else
  1711. X#define debug7(cat, urg, str, p1, p2, p3, p4, p5, p6, p7)        \
  1712. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4, p5,p6,p7); else
  1713. X#define debug8(cat, urg, str, p1, p2, p3, p4, p5, p6, p7, p8)        \
  1714. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2,p3,p4,p5,p6,p7,p8); else
  1715. X#define    ifdebug(cat, urg, x)                        \
  1716. X    if( dbg[cat].on[urg] ) { x; } else 
  1717. X#define    debug_init(str)                            \
  1718. X    DebugInit(str)
  1719. X
  1720. X/* debug styles */
  1721. X#define    D     0
  1722. X#define    DD     1
  1723. X#define    DDD     2
  1724. X
  1725. X/* debug flags */
  1726. X#define    DSP     1        /*  z01.c   -dsp   Supervise                 */
  1727. X#define    DLA     2        /*  z02.c   -dla   Lexical Analyser          */
  1728. X#define    DFS     3        /*  z03.c   -dfs   File Service              */
  1729. X#define    DTS     4        /*  z04.c   -dts   Token Service             */
  1730. X#define    DRD     5        /*  z05.c   -drd   Read Definitions          */
  1731. X#define    DOP     6        /*  z06.c   -dop   Object Parser             */
  1732. X#define    DOS     7        /*  z07.c   -dos   Object Service            */
  1733. X#define    DOM     8        /*  z08.c   -dom   Object Manifest           */
  1734. X#define    DCE     9        /*  z09.c   -dce   Closure Expansion         */
  1735. X#define    DCR    10        /*  z10.c   -dcr   Cross References         */
  1736. X#define    DSS    11        /*  z11.c   -dss   Style Service         */
  1737. X#define    DSF    12        /*  z12.c   -dsf   Size Finder               */
  1738. X#define    DOB    13        /*  z13.c   -dob   Object Breaking         */
  1739. X#define    DOF    14        /*  z14.c   -dof   Object Filling         */
  1740. X#define    DSC    15        /*  z15.c   -dsc   Size Constraints          */
  1741. X#define    DSA    16        /*  z16.c   -dsa   Size Adjustments         */
  1742. X#define    DGW    17        /*  z17.c   -dgw   Gap Widths                */
  1743. X#define    DGT    18        /*  z18.c   -dgt   Galley Transfer           */
  1744. X#define    DGA    19        /*  z19.c   -dgf   Galley Attaching          */
  1745. X#define    DGF    20        /*  z20.c   -dgf   Galley Flushing           */
  1746. X#define    DGM    21        /*  z21.c   -dgm   Galley Maker              */
  1747. X#define    DGS    22        /*  z22.c   -dgs   Galley Service            */
  1748. X#define    DGP    23        /*  z23.c   -dgp   Galley Printer            */
  1749. X#define    DFT    24        /*  z24.c   -dft   Font Tables               */
  1750. X#define    DOE    25        /*  z25.c   -doe   Object Echo               */
  1751. X#define    DES    26        /*  z26.c   -des   Echo Service             */
  1752. X#define    DZZ    27        /*  z27.c   -dzz   Debug Service             */
  1753. X#define    DYY    28        /*  z28.c   -dyy   Error Service             */
  1754. X#define    DST    29        /*  z29.c   -dst   Symbol Table              */
  1755. X#define    DSU    30        /*  z30.c   -dsu   Symbol Uses               */
  1756. X#define    DMA    31        /*  z31.c   -dma   Memory Allocator          */
  1757. X#define    DCS    32        /*  z32.c   -dcs   Counter Service           */
  1758. X#define    DBS    33        /*  z33.c   -dbs   Database Service          */
  1759. X#define    DRS    34        /*  z34.c   -drs   Rotation Service          */
  1760. X#define    DTK    35        /*  z35.c   -dtk   Time Keeper               */
  1761. X#define    DHY    36        /*  z36.c   -dhy   Hyphenation               */
  1762. X#define    DPP    37        /*          -dpp   Profiling                 */
  1763. X#define    ANY    38        /*          -d     any                       */
  1764. X
  1765. X#else
  1766. X#define ifdebug(cat, urg, x)
  1767. X#define debug0(cat, urg, str)
  1768. X#define debug1(cat, urg, str, p1)
  1769. X#define debug2(cat, urg, str, p1, p2)
  1770. X#define debug3(cat, urg, str, p1, p2, p3)
  1771. X#define debug4(cat, urg, str, p1, p2, p3, p4)
  1772. X#define debug5(cat, urg, str, p1, p2, p3, p4, p5)
  1773. X#define debug6(cat, urg, str, p1, p2, p3, p4, p5, p6)
  1774. X#define debug7(cat, urg, str, p1, p2, p3, p4, p5, p6, p7)
  1775. X#define debug8(cat, urg, str, p1, p2, p3, p4, p5, p6, p7, p8)
  1776. X#define    debug_init(str)    Error(FATAL, no_fpos,            \
  1777. X            "%s - debug flags not implemented", str)
  1778. X#endif
  1779. END_OF_FILE
  1780.   if test 79673 -ne `wc -c <'lout/externs'`; then
  1781.     echo shar: \"'lout/externs'\" unpacked with wrong size!
  1782.   fi
  1783.   # end of 'lout/externs'
  1784. fi
  1785. echo shar: End of archive 2 \(of 30\).
  1786. cp /dev/null ark2isdone
  1787. MISSING=""
  1788. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ; do
  1789.     if test ! -f ark${I}isdone ; then
  1790.     MISSING="${MISSING} ${I}"
  1791.     fi
  1792. done
  1793. if test "${MISSING}" = "" ; then
  1794.     echo You have unpacked all 30 archives.
  1795.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1796. else
  1797.     echo You still must unpack the following archives:
  1798.     echo "        " ${MISSING}
  1799. fi
  1800. exit 0
  1801. exit 0 # Just in case...
  1802.