home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume38 / lout / part03 < prev    next >
Encoding:
Text File  |  1993-08-11  |  73.7 KB  |  1,712 lines

  1. Newsgroups: comp.sources.misc
  2. From: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  3. Subject: v38i071:  lout - Lout document formatting system, v2.05, Part03/35
  4. Message-ID: <1993Aug8.180555.11183@sparky.sterling.com>
  5. X-Md4-Signature: 477a4f00e488769a4673a318728b2e69
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Sun, 8 Aug 1993 18:05:55 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  12. Posting-number: Volume 38, Issue 71
  13. Archive-name: lout/part03
  14. Environment: UNIX
  15. Supersedes: lout: Volume 37, Issue 99-128
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  externs.B font/README z05.c
  22. # Wrapped by kent@sparky on Sun Aug  8 12:29:21 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 3 (of 35)."'
  26. if test -f 'externs.B' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'externs.B'\"
  28. else
  29.   echo shar: Extracting \"'externs.B'\" \(49929 characters\)
  30.   sed "s/^X//" >'externs.B' <<'END_OF_FILE'
  31. X#define    DO_ADJUST    6        /* placed in ACATs when adjust need  */
  32. X
  33. X/* sides of a mark */
  34. X#define    BACK        88        /* means lies to left of mark        */
  35. X#define    ON        89        /* means lies on mark                */
  36. X#define    FWD        90        /* means lies to right of mark       */
  37. X
  38. X/* statuses of thread objects */
  39. X#define    NOTSIZED     0        /* this thread object is not sized   */
  40. X#define    SIZED         1        /* thread is sized but not printed   */
  41. X#define    FINALSIZE     2        /* thread object size is now final   */
  42. X
  43. X/* constraint statuses */
  44. X#define    PROMOTE        91        /* this component may be promoted    */
  45. X#define    CLOSE        92        /* must close dest before promoting  */
  46. X#define    BLOCK        93        /* cannot promote this component     */
  47. X#define    CLEAR        94        /* this constraint is now satisfied  */
  48. X
  49. X/* gap increment types */
  50. X#define    GAP_ABS        95        /* absolute,  e.g.  3p               */
  51. X#define    GAP_INC        96        /* increment, e.g. +3p               */
  52. X#define    GAP_DEC        97        /* decrement, e.g. -3p               */
  53. X
  54. X/* file types */
  55. X#define    SOURCE_FILE     0        /* input file from command line      */
  56. X#define    INCLUDE_FILE     1        /* @Include file                     */
  57. X#define    INCGRAPHIC_FILE     2        /* @IncludeGraphic file              */
  58. X#define    DATABASE_FILE     3        /* database file                     */
  59. X#define    INDEX_FILE     4        /* database index file               */
  60. X#define    FONT_FILE     5        /* font file                         */
  61. X#define    PREPEND_FILE     6        /* PostScript prologue file          */
  62. X#define    HYPH_FILE     7        /* hyphenation file                  */
  63. X#define    HYPH_PACKED_FILE 8        /* packed hyphenation file           */
  64. X#define    ENCODING_FILE     9        /* encoding vector file              */
  65. X
  66. X/* path types (i.e. sequences of directories for file searching) */
  67. X#define    SOURCE_PATH     0        /* path to search for source files   */
  68. X#define    INCLUDE_PATH     1        /* path for @Include files           */
  69. X#define    SYSINCLUDE_PATH     2        /* path for @SysInclude files        */
  70. X#define    DATABASE_PATH     3        /* path for @Database files          */
  71. X#define    SYSDATABASE_PATH 4        /* path for @SysDatabase files       */
  72. X#define    FONT_PATH     5        /* path for font metrics (AFM) files */
  73. X#define    ENCODING_PATH     6        /* path for encoding (CEV) files     */
  74. X
  75. X/* units of measurement */
  76. X#define    NO_UNIT         0        /* no unit - for error detection     */
  77. X#define    FIXED_UNIT     1        /* inches, cm, points, ems           */
  78. X#define    FRAME_UNIT     2        /* f unit (frame widths)             */
  79. X#define    AVAIL_UNIT     3        /* r unit (available spaces)         */
  80. X#define    DEG_UNIT     4        /* d unit (degrees)                  */
  81. X#define    NEXT_UNIT     5        /* b unit (inners)                   */
  82. X/* units of distance as multiples of the basic unit */
  83. X#define    CM           567        /* 1 centimetre                      */
  84. X#define    IN          1440        /* 1 inch                            */
  85. X#define    EM           120        /* 1 em (= 1/12 inch)                */
  86. X#define    PT        20        /* 1 point (= 1/72 inch)             */
  87. X#define    FR          4096        /* virtual unit for frame units      */
  88. X#define    DG           128        /* virtual unit for degrees          */
  89. X#define    SF           128        /* virtual unit for @Scale factors   */
  90. X
  91. X/* precedences */
  92. X#define    NO_PREC         0        /* lower than any precedence         */
  93. X#define    BEGIN_PREC     1        /* precedence of @Begin              */
  94. X#define    END_PREC     2        /* precedence of @End                */
  95. X#define    LBR_PREC     3        /* precedence of {                   */
  96. X#define    RBR_PREC     4        /* precedence of }                   */
  97. X#define    VCAT_PREC     5        /* precedence of /                   */
  98. X#define    HCAT_PREC     6        /* precedence of |                   */
  99. X#define    ACAT_PREC     7        /* precedence of & and white space   */
  100. X#define    MIN_PREC        10        /* minimum precedence of user ops    */
  101. X#define    MAX_PREC       100        /* maximim precedence of user ops    */
  102. X#define    DEFAULT_PREC   100        /* default precedence of user ops    */
  103. X#define CROSSOP_PREC   101        /* precedence of cross op &&         */
  104. X#define GAP_PREC       102        /* precedence of gap op after cat op */
  105. X#define JUXTA_PREC     103        /* precedence of juxtaposition &     */
  106. X#define    FORCE_PREC     104        /* higher than any precedence        */
  107. X
  108. X/* error types */
  109. X#define    INTERN    0            /* internal error (i.e. bug)         */
  110. X#define    FATAL    1            /* fatal error, abort now            */
  111. X#define    WARN    2            /* warning, non-fatal                */
  112. X
  113. X
  114. X/*@::Keywords@****************************************************************/
  115. X/*                                                                           */
  116. X/*  Keywords.                                                                */
  117. X/*                                                                           */
  118. X/*****************************************************************************/
  119. X
  120. X#define    KW_START        AsciiToFull("\\Start")
  121. X#define    KW_PRINT        AsciiToFull("\\Print")
  122. X#define    KW_DEF            AsciiToFull("def")
  123. X#define    KW_FONTDEF        AsciiToFull("fontdef")
  124. X#define    KW_FORCE        AsciiToFull("force")
  125. X#define    KW_INTO            AsciiToFull("into")
  126. X#define    KW_IMPORT        AsciiToFull("import")
  127. X#define    KW_EXPORT        AsciiToFull("export")
  128. X#define    KW_PRECEDENCE        AsciiToFull("precedence")
  129. X#define    KW_ASSOC        AsciiToFull("associativity")
  130. X#define    KW_LEFT            AsciiToFull("left")
  131. X#define    KW_RIGHT        AsciiToFull("right")
  132. X#define    KW_BODY            AsciiToFull("body")
  133. X#define    KW_MACRO        AsciiToFull("macro")
  134. X#define    KW_NAMED        AsciiToFull("named")
  135. X#define    KW_NEXT            AsciiToFull("@Next")
  136. X#define    KW_WIDE            AsciiToFull("@Wide")
  137. X#define    KW_HIGH            AsciiToFull("@High")
  138. X#define    KW_ONE_COL        AsciiToFull("@OneCol")
  139. X#define    KW_ONE_ROW        AsciiToFull("@OneRow")
  140. X#define    KW_HSCALE        AsciiToFull("@HScale")
  141. X#define    KW_VSCALE        AsciiToFull("@VScale")
  142. X#define    KW_SCALE        AsciiToFull("@Scale")
  143. X#define    KW_HCONTRACT        AsciiToFull("@HContract")
  144. X#define    KW_VCONTRACT        AsciiToFull("@VContract")
  145. X#define    KW_HEXPAND        AsciiToFull("@HExpand")
  146. X#define    KW_VEXPAND        AsciiToFull("@VExpand")
  147. X#define    KW_PADJUST        AsciiToFull("@PAdjust")
  148. X#define    KW_HADJUST        AsciiToFull("@HAdjust")
  149. X#define    KW_VADJUST        AsciiToFull("@VAdjust")
  150. X#define    KW_ROTATE        AsciiToFull("@Rotate")
  151. X#define    KW_INCGRAPHIC        AsciiToFull("@IncludeGraphic")
  152. X#define    KW_SINCGRAPHIC        AsciiToFull("@SysIncludeGraphic")
  153. X#define    KW_GRAPHIC        AsciiToFull("@Graphic")
  154. X#define    KW_CASE            AsciiToFull("@Case")
  155. X#define    KW_YIELD        AsciiToFull("@Yield")
  156. X#define    KW_XCHAR        AsciiToFull("@Char")
  157. X#define    KW_FONT            AsciiToFull("@Font")
  158. X#define    KW_SPACE        AsciiToFull("@Space")
  159. X#define    KW_BREAK        AsciiToFull("@Break")
  160. X#define    KW_ENV            AsciiToFull("@LEnv")
  161. X#define    KW_CLOS            AsciiToFull("@LClos")
  162. X#define    KW_LVIS            AsciiToFull("@LVis")
  163. X#define    KW_OPEN            AsciiToFull("@Open")
  164. X#define    KW_USE            AsciiToFull("@Use")
  165. X#define    KW_TAGGED        AsciiToFull("@Tagged")
  166. X#define    KW_DATABASE        AsciiToFull("@Database")
  167. X#define    KW_SYSDATABASE        AsciiToFull("@SysDatabase")
  168. X#define    KW_INCLUDE        AsciiToFull("@Include")
  169. X#define    KW_SYSINCLUDE        AsciiToFull("@SysInclude")
  170. X#define    KW_PREPEND        AsciiToFull("@PrependGraphic")
  171. X#define    KW_SYSPREPEND        AsciiToFull("@SysPrependGraphic")
  172. X#define    KW_TARGET        AsciiToFull("@Target")
  173. X#define    KW_FOLLOWING        AsciiToFull("following")
  174. X#define    KW_PRECEDING        AsciiToFull("preceding")
  175. X#define    KW_NOW            AsciiToFull("now")
  176. X#define    KW_NULL            AsciiToFull("@Null")
  177. X#define    KW_GALLEY        AsciiToFull("@Galley")
  178. X#define    KW_INPUT        AsciiToFull("@LInput")
  179. X#define    KW_SPLIT        AsciiToFull("@Split")
  180. X#define    KW_TAG            AsciiToFull("@Tag")
  181. X#define    KW_KEY            AsciiToFull("@Key")
  182. X#define    KW_CROSS        AsciiToFull("&&")
  183. X#define    KW_LBR            AsciiToFull("{")
  184. X#define    KW_RBR            AsciiToFull("}")
  185. X#define    KW_BEGIN        AsciiToFull("@Begin")
  186. X#define    KW_END            AsciiToFull("@End")
  187. X#define    KW_VCAT_NN        AsciiToFull("//")
  188. X#define    KW_VCAT_MN        AsciiToFull("^//")
  189. X#define    KW_VCAT_NJ        AsciiToFull("/")
  190. X#define    KW_VCAT_MJ        AsciiToFull("^/")
  191. X#define    KW_HCAT_NN        AsciiToFull("||")
  192. X#define    KW_HCAT_MN        AsciiToFull("^||")
  193. X#define    KW_HCAT_NJ        AsciiToFull("|")
  194. X#define    KW_HCAT_MJ        AsciiToFull("^|")
  195. X#define    KW_ACAT_NJ        AsciiToFull("&")
  196. X#define    KW_ACAT_MJ        AsciiToFull("^&")
  197. X#define    KW_MOMENT        AsciiToFull("@Moment")
  198. X#define    KW_SECOND        AsciiToFull("@Second")
  199. X#define    KW_MINUTE        AsciiToFull("@Minute")
  200. X#define    KW_HOUR            AsciiToFull("@Hour")
  201. X#define    KW_DAY            AsciiToFull("@Day")
  202. X#define    KW_MONTH        AsciiToFull("@Month")
  203. X#define    KW_YEAR            AsciiToFull("@Year")
  204. X#define    KW_CENTURY        AsciiToFull("@Century")
  205. X#define    KW_WEEKDAY        AsciiToFull("@WeekDay")
  206. X#define    KW_YEARDAY        AsciiToFull("@YearDay")
  207. X#define    KW_DAYLIGHTSAVING    AsciiToFull("@DaylightSaving")
  208. X
  209. X
  210. X/*@::GetMem(), New(), NewWord(), PutMem(), Dispose()@*************************/
  211. X/*                                                                           */
  212. X/*  OBJECT GetMem(siz, pos)                                                  */
  213. X/*  OBJECT New(typ)                                                          */
  214. X/*  OBJECT NewWord(typ, len, pos)                                            */
  215. X/*         PutMem(x, siz)                                                    */
  216. X/*         Dispose(x)                                                        */
  217. X/*                                                                           */
  218. X/*  Return a pointer to a new record, of appropriate length (in ALIGNs).     */
  219. X/*  The New and NewWord versions initialise LIST, type and rec_size fields.  */
  220. X/*  Note that NewWord must be used for WORD and QWORD objects.               */
  221. X/*  Dispose x, which is of size siz.  Dispose works out the size itself.     */
  222. X/*                                                                           */
  223. X/*****************************************************************************/
  224. X#define    USES_SIZE ceiling( sizeof(struct uses_type), sizeof(ALIGN) )
  225. X
  226. X#if DEBUG_ON
  227. X#define newcount zz_newcount++,
  228. X#else
  229. X#define newcount
  230. X#endif
  231. X
  232. X#define    GetMem(siz, pos)                        \
  233. X( newcount (zz_size=(siz))>=MAX_OBJECT_REC ?                \
  234. X      (OBJECT) Error(FATAL, pos, "word is too long")            \
  235. X  : zz_free[zz_size] == nil ? zz_hold = GetMemory(zz_size, pos)        \
  236. X  : (zz_hold = zz_free[zz_size],                    \
  237. X    zz_free[zz_size] = pred(zz_hold, CHILD), zz_hold)        \
  238. X)
  239. X
  240. X#if DEBUG_ON
  241. X#define checknew(typ)                            \
  242. X  !is_type(typ) ? Error(INTERN, no_fpos,"New: type = %s", Image(typ)) :    \
  243. X  zz_lengths[typ] == 0 ? Error(INTERN, no_fpos, "New: 0 length!") : 0,
  244. X#else
  245. X#define checknew(typ)
  246. X#endif
  247. X
  248. X#define    New(typ)                            \
  249. X( checknew(typ) GetMem(zz_lengths[typ], no_fpos), type(zz_hold) = typ,    \
  250. X  pred(zz_hold, CHILD)  = succ(zz_hold, CHILD)  =            \
  251. X  pred(zz_hold, PARENT) = succ(zz_hold, PARENT) = zz_hold        \
  252. X)
  253. X
  254. X#define NewWord(typ, len, pos)                        \
  255. X( zz_size = sizeof(struct word_type) - 4 + ((len)+1)*sizeof(FULL_CHAR),    \
  256. X  GetMem(ceiling(zz_size, sizeof(ALIGN)), pos),  /* RESETS zz_size */    \
  257. X  rec_size(zz_hold) = zz_size,  type(zz_hold) = typ,            \
  258. X  pred(zz_hold, CHILD)  = succ(zz_hold, CHILD)  =            \
  259. X  pred(zz_hold, PARENT) = succ(zz_hold, PARENT) = zz_hold        \
  260. X)
  261. X
  262. X#if DEBUG_ON
  263. X#define disposecount zz_disposecount++,
  264. X#define    setdisposed  , type(zz_hold) = DISPOSED
  265. X#else
  266. X#define disposecount
  267. X#define    setdisposed
  268. X#endif
  269. X
  270. X#define PutMem(x, siz)                            \
  271. X( disposecount zz_hold = (x), zz_size = (siz),                \
  272. X  pred(zz_hold, CHILD) = zz_free[zz_size], zz_free[zz_size] = zz_hold )
  273. X
  274. X#define Dispose(x)                            \
  275. X( zz_hold = (x),                            \
  276. X  assert( pred(zz_hold, CHILD)  == zz_hold, "Dispose: pred(CHILD)!"  ),    \
  277. X  assert( succ(zz_hold, CHILD)  == zz_hold, "Dispose: succ(CHILD)!"  ),    \
  278. X  assert( pred(zz_hold, PARENT) == zz_hold, "Dispose: pred(PARENT)!" ),    \
  279. X  assert( succ(zz_hold, PARENT) == zz_hold, "Dispose: succ(PARENT)!" ),    \
  280. X  PutMem(zz_hold, is_word(type(zz_hold)) ? rec_size(zz_hold)        \
  281. X              : zz_lengths[type(zz_hold)]) setdisposed  )
  282. X
  283. X/*@::Append(), Delete(), DeleteAndDispose()@**********************************/
  284. X/*                                                                           */
  285. X/*  OBJECT Append(x, y, dir)                                                 */
  286. X/*                                                                           */
  287. X/*  Return the append of lists x and y (dir is PARENT or CHILD).             */
  288. X/*                                                                           */
  289. X/*****************************************************************************/
  290. X
  291. X#define    Append(x, y, dir)                        \
  292. X( zz_res = (x),    zz_hold = (y),                        \
  293. X  zz_hold == nil ? zz_res  :                        \
  294. X  zz_res  == nil ? zz_hold :                        \
  295. X  ( zz_tmp = pred(zz_hold, dir),                    \
  296. X    pred(zz_hold, dir) = pred(zz_res, dir),                \
  297. X    succ(pred(zz_res, dir), dir) = zz_hold,                \
  298. X    pred(zz_res, dir) = zz_tmp,                        \
  299. X    succ(zz_tmp, dir) = zz_res                        \
  300. X  )                                    \
  301. X)
  302. X
  303. X
  304. X/*****************************************************************************/
  305. X/*                                                                           */
  306. X/*  OBJECT Delete(x, dir)                                                    */
  307. X/*                                                                           */
  308. X/*  Delete x from its dir list, and return succ(x, dir) or nil if none.      */
  309. X/*                                                                           */
  310. X/*****************************************************************************/
  311. X
  312. X#define Delete(x, dir)                            \
  313. X( zz_hold = (x),                            \
  314. X  succ(zz_hold, dir) == zz_hold ? nil :                    \
  315. X  ( zz_res = succ(zz_hold, dir),                    \
  316. X    pred(zz_res, dir) = pred(zz_hold, dir),                \
  317. X    succ(pred(zz_hold, dir), dir) = zz_res,                \
  318. X    pred(zz_hold, dir) = succ(zz_hold, dir) = zz_hold,            \
  319. X    zz_res                                \
  320. X  )                                    \
  321. X)
  322. X
  323. X/*****************************************************************************/
  324. X/*                                                                           */
  325. X/*  OBJECT DeleteAndDispose(x, dir)                                          */
  326. X/*                                                                           */
  327. X/*  Delete x as above, dispose it, and return succ(x, dir) or nil if none.   */
  328. X/*                                                                           */
  329. X/*****************************************************************************/
  330. X
  331. X#define DeleteAndDispose(x, dir)                    \
  332. X( zz_hold = (x),                            \
  333. X  zz_res  = succ(zz_hold, dir) == zz_hold ? nil :            \
  334. X        ( pred(succ(zz_hold, dir), dir) = pred(zz_hold, dir),    \
  335. X          succ(pred(zz_hold, dir), dir) = succ(zz_hold, dir) ),    \
  336. X  pred(zz_hold, dir) = succ(zz_hold, dir) = zz_hold,            \
  337. X  Dispose(zz_hold),                            \
  338. X  zz_res                                \
  339. X)
  340. X
  341. X#define Down(x)        succ(x, CHILD)
  342. X#define NextDown(x)    succ(x, CHILD)
  343. X#define LastDown(x)    pred(x, CHILD)
  344. X#define PrevDown(x)    pred(x, CHILD)
  345. X#define    Up(x)        succ(x, PARENT)
  346. X#define    NextUp(x)    succ(x, PARENT)
  347. X#define    LastUp(x)    pred(x, PARENT)
  348. X#define    PrevUp(x)    pred(x, PARENT)
  349. X
  350. X#define    Child(y, link)                            \
  351. Xfor( y = pred(link, PARENT);  type(y) == LINK;  y = pred(y, PARENT) )
  352. X
  353. X#define    Parent(y, link)                            \
  354. Xfor( y = pred(link, CHILD);   type(y) == LINK;  y = pred(y, CHILD) )
  355. X
  356. X
  357. X/*@::UpDim(), DownDim(), Link(), DeleteLink(), etc.@**************************/
  358. X/*                                                                           */
  359. X/*  UpDim(x, dim)                                                            */
  360. X/*  DownDim(x, dim)                                                          */
  361. X/*                                                                           */
  362. X/*  Returns the dim child or parent link of node x (dim == COL or ROW).      */
  363. X/*                                                                           */
  364. X/*****************************************************************************/
  365. X
  366. X#define UpDim(x, dim)    ( (dim) == COL ? succ(x, PARENT) : pred(x, PARENT) )
  367. X#define DownDim(x, dim)    ( (dim) == COL ? succ(x, CHILD) : pred(x, CHILD) )
  368. X
  369. X
  370. X/*****************************************************************************/
  371. X/*                                                                           */
  372. X/*  OBJECT Link(x, y)                                                        */
  373. X/*                                                                           */
  374. X/*  Make y a child of x in the directed graph, using a new link.             */
  375. X/*  The link node is returned.                                               */
  376. X/*                                                                           */
  377. X/*****************************************************************************/
  378. X
  379. X#define Link(x, y)                            \
  380. X( xx_link = New(LINK),                            \
  381. X  Append(xx_link, (x), CHILD),                        \
  382. X  Append(xx_link, (y), PARENT)                        \
  383. X)
  384. X
  385. X
  386. X/*****************************************************************************/
  387. X/*                                                                           */
  388. X/*  OBJECT DeleteLink(link)                                                  */
  389. X/*                                                                           */
  390. X/*  Cut the link between nodes x and y of the directed graph.                */
  391. X/*  Returns the link node of the next child of x, or x if none.              */
  392. X/*                                                                           */
  393. X/*****************************************************************************/
  394. X
  395. X#define DeleteLink(link)                        \
  396. X( xx_link = (link),                            \
  397. X  Delete(xx_link, PARENT),                        \
  398. X  DeleteAndDispose(xx_link, CHILD)                    \
  399. X)
  400. X
  401. X
  402. X/*****************************************************************************/
  403. X/*                                                                           */
  404. X/*  DisposeChild(link)                                                       */
  405. X/*                                                                           */
  406. X/*  Delete link, and if its child is thereby unattached, dispose it.         */
  407. X/*                                                                           */
  408. X/*****************************************************************************/
  409. X
  410. X#define DisposeChild(link)                        \
  411. X( xx_link = (link),                            \
  412. X  xx_tmp = Delete(xx_link, PARENT),                    \
  413. X  DeleteAndDispose(xx_link, CHILD),                    \
  414. X  succ(xx_tmp, PARENT) == xx_tmp ? DisposeObject(xx_tmp) : 0        \
  415. X) /* end DisposeChild */
  416. X
  417. X
  418. X/*****************************************************************************/
  419. X/*                                                                           */
  420. X/*  MoveLink(link, x, dir)                                                   */
  421. X/*                                                                           */
  422. X/*  Move the dir end of link from wherever it is now to node x.              */
  423. X/*                                                                           */
  424. X/*****************************************************************************/
  425. X
  426. X#define MoveLink(link, x, dir)                        \
  427. X( xx_link = (link),                            \
  428. X  Delete(xx_link, 1 - (dir) ),                        \
  429. X  Append(xx_link, (x), 1 - (dir) )                    \
  430. X) /* end MoveLink */
  431. X
  432. X
  433. X/*@::TransferLinks(), DeleteNode(), etc.@*************************************/
  434. X/*                                                                           */
  435. X/*  TransferLinks(start_link, stop_link, dest_link)                          */
  436. X/*                                                                           */
  437. X/*  Move parent end of links start_link (inclusive) to stop_link (exclusive) */
  438. X/*  to just before dest_link.                                                */
  439. X/*                                                                           */
  440. X/*****************************************************************************/
  441. X
  442. X#define TransferLinks(start_link, stop_link, dest_link)            \
  443. X{ OBJECT xxstart = start_link, xxstop = stop_link, xxdest = dest_link;    \
  444. X  if( xxstart != xxstop )                        \
  445. X  {    assert( type(xxstart) == LINK, "TransferLinks: start_link!" );    \
  446. X    Append(xxstart, xxstop, CHILD); /* actually a split */        \
  447. X    Append(xxstart, xxdest, CHILD);                    \
  448. X  }                                    \
  449. X}
  450. X
  451. X
  452. X/*****************************************************************************/
  453. X/*                                                                           */
  454. X/*  DeleteNode(x)                                                            */
  455. X/*                                                                           */
  456. X/*  Delete node x and every edge attaching to x.                             */
  457. X/*                                                                           */
  458. X/*****************************************************************************/
  459. X
  460. X#define DeleteNode(x)                            \
  461. X{ xx_hold = (x);                            \
  462. X  while( Up(xx_hold)   != xx_hold ) DeleteLink( Up(xx_hold) );        \
  463. X  while( Down(xx_hold) != xx_hold ) DeleteLink( Down(xx_hold) );    \
  464. X  Dispose(xx_hold);                            \
  465. X}
  466. X
  467. X
  468. X/*****************************************************************************/
  469. X/*                                                                           */
  470. X/*  MergeNode(x, y)                                                          */
  471. X/*                                                                           */
  472. X/*  Take all the children of y and make them children of x.                  */
  473. X/*  Take all the parents of y and make them parents of x.  Dispose y.        */
  474. X/*                                                                           */
  475. X/*****************************************************************************/
  476. X
  477. X#define MergeNode(x, y)                            \
  478. X{ xx_res = (x); xx_hold = (y);                        \
  479. X  xx_tmp = Delete(xx_hold, PARENT);                    \
  480. X  Append(xx_res, xx_tmp, PARENT);                    \
  481. X  xx_tmp = DeleteAndDispose(xx_hold, CHILD);                \
  482. X  Append(xx_res, xx_tmp, CHILD);                    \
  483. X}  /* end MergeNode */
  484. X
  485. X
  486. X/*****************************************************************************/
  487. X/*                                                                           */
  488. X/*  ReplaceNode(x, y)                                                        */
  489. X/*                                                                           */
  490. X/*  Move all the parent links of y to x.                                     */
  491. X/*                                                                           */
  492. X/*****************************************************************************/
  493. X
  494. X#define ReplaceNode(x, y)                        \
  495. X( xx_tmp = Delete((y), PARENT),                        \
  496. X  Append((x), xx_tmp, PARENT)                        \
  497. X) /* end ReplaceNode */
  498. X
  499. X
  500. X/*@::FirstDefinite(), NextDefinite(), etc.@***********************************/
  501. X/*                                                                           */
  502. X/*  FirstDefinite(x, link, y)                                                */
  503. X/*                                                                           */
  504. X/*  On input, x is an object and link and y are undefined.  On output there  */
  505. X/*  are two cases:                                                           */
  506. X/*                                                                           */
  507. X/*  link != x.  Then y is first definite child of x and link is its link.    */
  508. X/*                                                                           */
  509. X/*  link == x.  Then x has no definite child and y is undefined.             */
  510. X/*                                                                           */
  511. X/*  A SPLIT object is considered to be definite if both its children are     */
  512. X/*  definite.  This condition is returned by SplitIsDefinite.                */
  513. X/*                                                                           */
  514. X/*****************************************************************************/
  515. X
  516. X#define FirstDefinite(x, link, y)                    \
  517. X{ for( link = Down(x);  link != x;  link = NextDown(link) )        \
  518. X  { Child(y, link);                            \
  519. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  520. X    break;                                \
  521. X  }                                    \
  522. X} /* end FirstDefinite */
  523. X
  524. X
  525. X/*****************************************************************************/
  526. X/*                                                                           */
  527. X/*  NextDefinite(x, link, y)                                                 */
  528. X/*                                                                           */
  529. X/*  On input, x is an object and link is a link to one of its children; y    */
  530. X/*  is undefined.  On output there are two cases:                            */
  531. X/*                                                                           */
  532. X/*  link != x.  Then y is the first definite child of x following link, and  */
  533. X/*              link is changed to be the link of y.                         */
  534. X/*                                                                           */
  535. X/*  link == x.  Then x has no definite child following link, and y remains   */
  536. X/*              undefined.                                                   */
  537. X/*                                                                           */
  538. X/*****************************************************************************/
  539. X
  540. X#define NextDefinite(x, link, y)                    \
  541. X{ for( link = NextDown(link);  link != x;  link = NextDown(link) )    \
  542. X  { Child(y, link);                            \
  543. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  544. X    break;                                \
  545. X  }                                    \
  546. X} /* end NextDefinite */
  547. X
  548. X
  549. X/*****************************************************************************/
  550. X/*                                                                           */
  551. X/*  NextDefiniteWithGap(x, link, y, g)                                       */
  552. X/*                                                                           */
  553. X/*  On input, x is an object and link is a link to one of its children; y    */
  554. X/*  and g are undefined.  On output there are two cases:                     */
  555. X/*                                                                           */
  556. X/*  link != x.  Then y is the first definite child of x following link, and  */
  557. X/*              link is changed to be the link of y.  Also, g is defined     */
  558. X/*              to be the gap just before y; this must exist and is tested   */
  559. X/*              by an assert test.                                           */
  560. X/*                                                                           */
  561. X/*  link == x.  Then x has no definite child following link, and y and g     */
  562. X/*              remain undefined.                                            */
  563. X/*                                                                           */
  564. X/*****************************************************************************/
  565. X
  566. X#define NextDefiniteWithGap(x, link, y, g)                \
  567. X{ g = nil;                                \
  568. X  for( link = NextDown(link);  link != x;  link = NextDown(link) )    \
  569. X  { Child(y, link);                            \
  570. X    if( type(y) == GAP_OBJ )  g = y;                    \
  571. X    else if( type(y)==SPLIT ? SplitIsDefinite(y):is_definite(type(y)) )    \
  572. X    { assert( g != nil, "NextDefinite: g == nil!" );            \
  573. X      break;                                \
  574. X    }                                    \
  575. X  }                                    \
  576. X} /* end NextDefiniteWithGap */
  577. X
  578. X/*@@**************************************************************************/
  579. X/*                                                                           */
  580. X/*  LastDefinite(x, link, y)                                                 */
  581. X/*                                                                           */
  582. X/*  On input, x is an object and link and y are undefined.  On output there  */
  583. X/*  are two cases:                                                           */
  584. X/*                                                                           */
  585. X/*  link != x.  Then y is the last definite child of x and link is its link. */
  586. X/*                                                                           */
  587. X/*  link == x.  Then x has no definite child and y is undefined.             */
  588. X/*                                                                           */
  589. X/*  A SPLIT object is considered to be definite if both its children are     */
  590. X/*  definite.  This condition is returned by SplitIsDefinite.                */
  591. X/*                                                                           */
  592. X/*****************************************************************************/
  593. X
  594. X#define LastDefinite(x, link, y)                    \
  595. X{ for( link = LastDown(x);  link != x;  link = PrevDown(link) )        \
  596. X  { Child(y, link);                            \
  597. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  598. X    break;                                \
  599. X  }                                    \
  600. X} /* end LastDefinite */
  601. X
  602. X
  603. X/*****************************************************************************/
  604. X/*                                                                           */
  605. X/*  PrevDefinite(x, link, y)                                                 */
  606. X/*                                                                           */
  607. X/*  On input, x is an object and link is a link to one of its children; y    */
  608. X/*  is undefined.  On output there are two cases:                            */
  609. X/*                                                                           */
  610. X/*  link != x.  Then y is the first definite child of x preceding link, and  */
  611. X/*              link is changed to be the link of y.                         */
  612. X/*                                                                           */
  613. X/*  link == x.  Then x has no definite child preceding link, and y remains   */
  614. X/*              undefined.                                                   */
  615. X/*                                                                           */
  616. X/*****************************************************************************/
  617. X
  618. X#define PrevDefinite(x, link, y)                    \
  619. X{ for( link = PrevDown(link);  link != x;  link = PrevDown(link) )    \
  620. X  { Child(y, link);                            \
  621. X    if( type(y) == SPLIT ? SplitIsDefinite(y) : is_definite(type(y)) )    \
  622. X    break;                                \
  623. X  }                                    \
  624. X} /* end PrevDefinite */
  625. X
  626. X
  627. X/*@::Module Declarations@*****************************************************/
  628. X/*                                                                           */
  629. X/*  MODULE DECLARATIONS                                                      */
  630. X/*                                                                           */
  631. X/*****************************************************************************/
  632. X
  633. X/*****  z01.c        Supervise        ******************************/
  634. Xextern            main();            /* main program              */
  635. Xextern    OBJECT        StartSym;        /* sym tab entry for \Start  */
  636. Xextern    OBJECT        GalleySym;        /* sym tab entry for @Galley */
  637. Xextern    OBJECT        InputSym;        /* sym tab entry for \Input  */
  638. Xextern    OBJECT        PrintSym;        /* sym tab entry for \Print  */
  639. Xextern    BOOLEAN        AllowCrossDb;        /* true when -s flag absent  */
  640. Xextern    BOOLEAN        Encapsulated;        /* true when eps wanted      */
  641. X
  642. X/*****  z02.c        Lexical Analyser    ******************************/
  643. Xextern            LexInit();        /* initialise lex. analyser  */
  644. Xextern            LexPush();        /* switch to new file list   */
  645. Xextern            LexPop();        /* return to prev. file list */
  646. Xextern    BOOLEAN        LexLegalName();        /* check identifier format   */
  647. Xextern    OBJECT        LexGetToken();        /* get next token from input */
  648. Xextern    long        LexNextTokenPos();    /* like ftell() on curr file */
  649. X
  650. X/*****  z03.c        File Service            ******************************/
  651. Xextern    FILE_POS    *no_fpos;        /* a null filepos            */
  652. Xextern            InitFiles();        /* initialize this module    */
  653. Xextern            AddToPath();        /* add directory to path     */
  654. Xextern    FILE_NUM    DefineFile();        /* declare input file        */
  655. Xextern    FILE_NUM    FirstFile();        /* first file of given type  */
  656. Xextern    FILE_NUM    NextFile();        /* next file of given type   */
  657. Xextern    FILE_NUM    FileNum();        /* file with given name      */
  658. Xextern    FULL_CHAR    *FileName();        /* file name of file         */
  659. Xextern    FULL_CHAR    *EchoFilePos();        /* string value of FILE_POS  */
  660. Xextern    FILE_POS    *PosOfFile();        /* string of file FILE_POS   */
  661. Xextern    FILE        *OpenFile();        /* open file for reading     */
  662. Xextern    FILE        *OpenIncGraphicFile();    /* open @IncludeGraphic file */
  663. Xextern    OBJECT        ReadFromFile();        /* read object from file     */
  664. Xextern            AppendToFile();        /* append object to file     */
  665. Xextern            CloseFiles();        /* close database files      */
  666. X
  667. X/*****  z04.c        Token Service            ******************************/
  668. Xextern    OBJECT        NewToken();        /* get a new token           */
  669. Xextern    OBJECT        CopyTokenList();    /* copy a list of tokens     */
  670. Xextern    FULL_CHAR    *EchoCatOp();        /* string value of CAT op    */
  671. Xextern    FULL_CHAR    *EchoToken();        /* returns image of token    */
  672. X
  673. X/*****  z05.c        Read Definitions      ******************************/
  674. Xextern            ReadPrependDef();    /* read @Prepend ...         */
  675. Xextern            ReadDatabaseDef();    /* read @Database ...        */
  676. Xextern            ReadDefinitions();    /* read definitions          */
  677. X
  678. X/*****  z06.c        Object Parser            ******************************/
  679. Xextern            InitParser();        /* initialise parser         */
  680. Xextern    OBJECT        Parse();        /* parser                    */
  681. X
  682. X/*****  z07.c        Object Service            ******************************/
  683. Xextern    OBJECT        MakeWord();        /* a new WORD or QWORD       */
  684. Xextern    OBJECT        MakeWordTwo();        /* a new WORD from 2 strings */
  685. Xextern    OBJECT        CopyObject();        /* make a copy of an object  */
  686. Xextern            DisposeObject();    /* dispose an object         */
  687. Xextern    BOOLEAN        SplitIsDefinite();    /* TRUE if SPLIT is definite */
  688. X
  689. X/*****  z08.c        Object Manifest            ******************************/
  690. Xextern    OBJECT        ReplaceWithTidy();    /* tidy up an object         */
  691. Xextern    OBJECT        Manifest();        /* manifest an object        */
  692. X
  693. X/*****  z09.c        Closure Expansion    ******************************/
  694. Xextern    OBJECT        SetEnv();        /* build up environment      */
  695. Xextern            AttachEnv();        /* attach env. to object     */
  696. Xextern    OBJECT        SearchEnv();        /* search environment        */
  697. Xextern    OBJECT        GetEnv();        /* retrieve env. from object */
  698. Xextern    OBJECT        DetachEnv();        /* retrieve and detach env.  */
  699. Xextern    OBJECT        ClosureExpand();    /* expand a user-def CLOSURE */
  700. X
  701. X/*****  z10.c        Cross References    ******************************/
  702. Xextern            CrossInit();        /* initialize cr record      */
  703. Xextern            CrossAddTag();        /* add auto tag to closure   */
  704. Xextern    OBJECT        CrossMake();        /* returns a cross-reference */
  705. Xextern    OBJECT        GallTargEval();        /* returns the value of a cr */
  706. Xextern    OBJECT        CrossExpand();        /* returns the value of a cr */
  707. Xextern            CrossSequence();    /* record cr off root galley */
  708. Xextern            CrossClose();        /* close down this module    */
  709. X
  710. X/*****  z11.c        Style Service        ******************************/
  711. Xextern            BreakChange();        /* change line spacing       */
  712. Xextern            SpaceChange();        /* change word spacing       */
  713. Xextern    FULL_CHAR    *EchoStyle();        /* string value of a style   */
  714. X
  715. X/*****  z12.c        Size Finder        ******************************/
  716. Xextern    OBJECT        MinSize();        /* min. possible size of obj */
  717. X
  718. X/*****  z13.c        Object Breaking        ******************************/
  719. Xextern    OBJECT        BreakObject();        /* break object to fit width */
  720. X
  721. X/*****  z14.c        Object Filling            ******************************/
  722. Xextern    OBJECT        FillObject();        /* optimal paragraph breaker */
  723. Xextern    OBJECT        SimpleFillObject();    /* simple paragraph breaker  */
  724. X
  725. X/*****  z15.c        Size Constraints    ******************************/
  726. Xextern    FULL_CHAR    *EchoConstraint();    /* string value of a constr. */
  727. Xextern            MinConstraint();    /* take minimum of two const */
  728. Xextern            EnlargeToConstraint();    /* enlarge obj to constraint */
  729. Xextern            RotateConstraint();    /* rotate constraints        */
  730. Xextern            InvScaleConstraint();    /* inverse scale a constr.   */
  731. Xextern            Constrained();        /* finds size constraint     */
  732. Xextern            DebugConstrained();    /* debug constraint code     */
  733. X
  734. X/*****  z16.c        Size Adjustments    ******************************/
  735. Xextern            SetNeighbours();    /* locate definite neighbours*/
  736. Xextern            AdjustSize();        /* updates sizes if changed  */
  737. X
  738. X/*****  z17.c        Gap Widths        ******************************/
  739. Xextern            GetGap();        /* convert string gap to num */
  740. Xextern    LENGTH        MinGap();        /* min. possible gap width   */
  741. Xextern    LENGTH        ExtraGap();        /* extra available gap width */
  742. Xextern    LENGTH        ActualGap();        /* gap width for output      */
  743. Xextern    FULL_CHAR    *EchoGap();        /* echo gap (cat. operator)  */
  744. X
  745. X/*****  z18.c        Galley Transfer        ******************************/
  746. Xextern            TransferInit();        /* initialise this module    */
  747. Xextern    OBJECT        TransferBegin();    /* begin transfer of galley  */
  748. Xextern            TransferComponent();    /* transfer one component    */
  749. Xextern            TransferEnd();        /* end galley transfer       */
  750. Xextern            TransferClose();    /* close this module         */
  751. X
  752. X/*****  z19.c        Galley Attaching    ******************************/
  753. Xextern    OBJECT        SearchGalley();        /* search galley for target  */
  754. Xextern            AttachGalley();        /* start off a galley        */
  755. Xextern            DetachGalley();        /* detach a galley           */
  756. X
  757. X/*****  z20.c        Galley Flushing        ******************************/
  758. Xextern            FlushGalley();        /* flush out a galley        */
  759. X
  760. X/***    z21.c        Galley Maker        ******************************/
  761. Xextern            SizeGalley();        /* convert object to galley  */
  762. X
  763. X/***    z22.c        Galley Service        ******************************/
  764. Xextern            FlushInners();        /* flush a list of galleys.  */
  765. Xextern            ExpandRecursives();    /* expand recursive definite */
  766. Xextern            Promote();        /* promote components        */
  767. Xextern            KillGalley();        /* destroy a galley          */
  768. Xextern            FreeGalley();        /* free a galley to flush    */
  769. Xextern            Interpose();        /* interpose a VCAT          */
  770. Xextern    BOOLEAN        TargetSymbol();        /* find target of galley     */
  771. Xextern    int        CheckConstraint();    /* check ordering constraint */
  772. X
  773. X/*****  z23.c        Galley Printer        ******************************/
  774. Xextern            FixAndPrintObject();    /* fix and print component   */
  775. X
  776. X/*****  z24.c        Print Service           ******************************/
  777. Xextern            PrintInit();        /* initialise this module    */
  778. Xextern            PrintPrologue();    /* print output prologue     */
  779. Xextern            PrintOriginIncrement();    /* reset current o/p origin  */
  780. Xextern            PrintWord();        /* print word at given pos   */
  781. Xextern            PrintClose();        /* wrapup output stream      */
  782. Xextern            CoordTranslate();    /* translate coord system    */
  783. Xextern            CoordRotate();        /* rotate coord system       */
  784. Xextern            CoordScale();        /* scale coord system        */
  785. Xextern            SaveGraphicState();    /* save coord system etc.    */
  786. Xextern            RestoreGraphicState();    /* restore coord system etc. */
  787. Xextern            DefineGraphicNames();    /* define xsize, ysize, etc. */
  788. Xextern            PrintGraphicObject();    /* print PostScript object   */
  789. Xextern            PrintGraphicInclude();    /* include PostScript file   */
  790. X
  791. X/*****  z25.c        Object Echo            ******************************/
  792. Xextern    FULL_CHAR    *EchoObject();        /* return object as string   */
  793. Xextern            DebugObject();        /* print object on stderr    */
  794. X
  795. X/*****  z26.c        Echo Service            ******************************/
  796. Xextern            BeginString();        /* begin string accumulator  */
  797. Xextern            AppendString();        /* append to current string  */
  798. Xextern    FULL_CHAR    *EndString();        /* return current string     */
  799. Xextern    FULL_CHAR    *EchoLength();        /* echo a length             */
  800. Xextern    FULL_CHAR    *Image();        /* string value of type(x)   */
  801. X
  802. X/*****    z27.c        Debug Service        ******************************/
  803. Xextern            DebugInit();        /* set debug flag            */
  804. Xextern            Debug();        /* print debug o/p on stderr */
  805. Xextern            ProfileOn();        /* start profiling           */
  806. Xextern            ProfileOff();        /* stop profiling            */
  807. Xextern            ProfilePrint();        /* print profiling results   */
  808. X
  809. X/*****    z28.c        Error Service        ******************************/
  810. Xextern            ErrorInit();        /* initialise log file       */
  811. Xextern            Error();        /* print error message       */
  812. Xextern    BOOLEAN        ErrorSeen();        /* TRUE after first error    */
  813. Xextern            EnterErrorBlock();    /* new error message block   */
  814. Xextern            LeaveErrorBlock();    /* commit or discard block   */
  815. X
  816. X/*****  z29.c        Symbol Table        ******************************/
  817. Xextern            InitSym();        /* initialize table to empty */
  818. Xextern            PushScope();        /* push a new scope on stack */
  819. Xextern            PopScope();        /* pop a scope from stack    */
  820. Xextern            SuppressVisible();    /* suppress visible flag     */
  821. Xextern            UnSuppressVisible();    /* unsuppress visible flag   */
  822. Xextern            SuppressScope();    /* suppress all scoping      */
  823. Xextern            UnSuppressScope();    /* unsuppress scoping        */
  824. Xextern            SwitchScope();        /* switch to a saved scope   */
  825. Xextern            UnSwitchScope();    /* switch back from saved s. */
  826. Xextern            BodyParAllowed();    /* body par is invokable     */
  827. Xextern            BodyParNotAllowed();    /* body par is not invokable */
  828. Xextern    OBJECT        SearchSym();        /* search table for symbol   */
  829. Xextern    OBJECT        InsertSym();        /* insert a new symbol       */
  830. Xextern            DeleteEverySym();    /* dispose all symbols       */
  831. Xextern    FULL_CHAR    *SymName();        /* string name of a symbol   */
  832. Xextern    FULL_CHAR    *FullSymName();        /* full path name of symbol  */
  833. Xextern    OBJECT        ChildSym();        /* return a child of a sym   */
  834. Xextern            CheckSymSpread();    /* check hash table spread   */
  835. X
  836. X/*****  z30.c        Symbol Uses        ******************************/
  837. Xextern            InsertUses();        /* record symbol x uses y    */
  838. Xextern            FlattenUses();        /* massage uses relation     */
  839. Xextern    BOOLEAN        SearchUses();        /* retrieve uses info        */
  840. Xextern    OBJECT        FirstExternTarget();    /* together these return all */
  841. Xextern    OBJECT        NextExternTarget();    /*   targets of extern galls */
  842. X
  843. X/*****  z31.c        Memory Allocator    ******************************/
  844. Xextern            MemInit();        /* initialise mem. allocator */
  845. Xextern    OBJECT        GetMemory();        /* get some fresh memory     */
  846. Xextern            DebugMemory();        /* print memory usage        */
  847. Xextern    OBJECT        zz_free[];        /* array of free lists       */
  848. Xextern    unsigned char    zz_lengths[];        /* array of record lengths   */
  849. Xextern    int        zz_newcount;        /* debug count of News       */
  850. Xextern    int        zz_disposecount;    /* debug count of Disposes   */
  851. Xextern    OBJECT        zz_hold;        /* temporary variable only   */
  852. Xextern    OBJECT        zz_tmp;            /* temporary variable only   */
  853. Xextern    OBJECT        zz_res;            /* temporary variable only   */
  854. Xextern    int        zz_size;        /* temporary variable only   */
  855. Xextern    OBJECT        xx_link, xx_tmp;    /* temporary variable only   */
  856. Xextern    OBJECT        xx_hold, xx_res;    /* temporary variable only   */
  857. X
  858. X/*****  z32.c        Counter Service        ******************************/
  859. Xextern    OBJECT        Next();            /* increment argument by one */
  860. X
  861. X/*****  z33.c        Database Service    ******************************/
  862. Xextern    OBJECT        OldCrossDb;        /* cross refs from last run  */
  863. Xextern    OBJECT        NewCrossDb;        /* cross refs from this run  */
  864. Xextern    OBJECT        DbCreate();        /* create writable database  */
  865. Xextern            DbInsert();        /* insert into database      */
  866. Xextern            DbConvert();        /* con. writable to readable */
  867. Xextern    OBJECT        DbLoad();        /* open readable database    */
  868. Xextern    BOOLEAN        DbRetrieve();        /* retrieve from database    */
  869. Xextern    BOOLEAN        DbRetrieveNext();    /* next entry from database  */
  870. Xextern            DbClose();        /* close a readable database */
  871. X
  872. X/*****  z34.c        Rotation Service        ******************************/
  873. Xextern            RotateSize();        /* calculate rotated size    */
  874. X
  875. X/*****  z35.c        Time Keeper         ******************************/
  876. Xextern    OBJECT        MomentSym;        /* the @Moment symbol        */
  877. Xextern            InitTime();        /* initialize this module    */
  878. Xextern    OBJECT        StartMoment();        /* a copy of the init time   */
  879. Xextern    FULL_CHAR    *TimeString();        /* a string containing time  */
  880. X
  881. X/*****  z36.c        Hyphenation         ******************************/
  882. Xextern    OBJECT        Hyphenate();        /* hyphenate a paragraph     */
  883. X
  884. X/*****  z37.c        Font Service             *****************************/
  885. Xextern            FontInit();        /* intialize this module     */
  886. Xextern            FontDefine();        /* define a font             */
  887. Xextern            FontChange();        /* change current font       */
  888. Xextern            FontWordSize();        /* set sizes of a word       */
  889. Xextern    LENGTH        FontSize();        /* size of a font            */
  890. Xextern    LENGTH        FontHalfXHeight();    /* xheight/2 of a font       */
  891. Xextern    ENCODING    FontEncoding();        /* encoding vector of a font */
  892. Xextern    FULL_CHAR    *FontName();        /* output name of a font     */
  893. Xextern    FULL_CHAR    *FontFamilyAndFace();    /* Lout name of a font       */
  894. Xextern    BOOLEAN        FontNeeded();        /* writes out font needs     */
  895. X
  896. X/*****  z38.c        Encoding Vectors    ******************************/
  897. Xextern    ENCODING    EvLoad();        /* load one encoding vector  */
  898. Xextern    FULL_CHAR    EvRetrieve();        /* convert char name to code */
  899. Xextern    FULL_CHAR    *EvName();        /* name of encoding vector   */
  900. Xextern            EvPrintAll();        /* print encoding vectors    */
  901. X
  902. X/*****  z39.c        String Handler          ******************************/
  903. X#define            AsciiToFull(x)        ( (FULL_CHAR *) (x) )
  904. X#define            StringEqual(a, b) (strcmp((char *)(a), (char *)(b))==0)
  905. X#define            StringLessEqual(a, b) (strcmp((char*)(a),(char*)(b))<=0)
  906. X#define            StringCat(a, b)        strcat((char *)(a),(char *)(b))
  907. X#define            StringCopy(a, b)    strcpy((char *)(a),(char *)(b))
  908. X#define            StringLength(a)        strlen((char *)(a))
  909. X#define            StringFOpen(a, b)    fopen( (char *) (a), (b) )
  910. X#define            StringFPuts(a, b)    fputs( (char *) (a), (b) )
  911. X#define            StringFGets(a, b, c)    fgets( (char *) (a), (b), (c) )
  912. X#define            StringUnlink(a)        unlink((char *)(a))
  913. X#define            StringLink(a, b)    link((char *)(a),(char *)(b))
  914. Xextern    BOOLEAN        StringBeginsWith();    /* string compare            */
  915. Xextern    BOOLEAN        StringContains();    /* string search             */
  916. Xextern    FULL_CHAR    *StringInt();        /* returns integer as string */
  917. Xextern    FULL_CHAR    *StringFiveInt();    /* returns integer as string */
  918. Xextern    FULL_CHAR    *StringQuotedWord();    /* returns string in Lout    */
  919. X
  920. X/*@::assert(), debug(), debug flags@******************************************/
  921. X/*                                                                           */
  922. X/*  ASSERT AND DEBUG CODE                                                    */
  923. X/*                                                                           */
  924. X/*****************************************************************************/
  925. X
  926. X#if ASSERT_ON
  927. X#define assert(c, m)                            \
  928. X   ( (c) ? 0 : Error(INTERN, no_fpos, "Assert failed in %s", m) )
  929. X#else
  930. X#define assert(c, m)    0
  931. X#endif
  932. X
  933. X#if DEBUG_ON
  934. X
  935. Xstruct dbs
  936. X{    char    *flag;            /* external names for debug flags    */
  937. X    BOOLEAN    on[3];            /* the debug flags                   */
  938. X};
  939. Xextern    struct dbs     dbg[];
  940. X
  941. X/* debug routines */
  942. X#define debug0(cat, urg, str)                                \
  943. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str); else
  944. X#define debug1(cat, urg, str, p1)                    \
  945. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1); else
  946. X#define debug2(cat, urg, str, p1, p2)                    \
  947. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2); else
  948. X#define debug3(cat, urg, str, p1, p2, p3)                \
  949. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3); else
  950. X#define debug4(cat, urg, str, p1, p2, p3, p4)                \
  951. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4); else
  952. X#define debug5(cat, urg, str, p1, p2, p3, p4, p5)            \
  953. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4, p5); else
  954. X#define debug6(cat, urg, str, p1, p2, p3, p4, p5, p6)            \
  955. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4, p5, p6); else
  956. X#define debug7(cat, urg, str, p1, p2, p3, p4, p5, p6, p7)        \
  957. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2, p3, p4, p5,p6,p7); else
  958. X#define debug8(cat, urg, str, p1, p2, p3, p4, p5, p6, p7, p8)        \
  959. X    if( dbg[cat].on[urg] ) Debug(cat, urg, str, p1, p2,p3,p4,p5,p6,p7,p8); else
  960. X#define    ifdebug(cat, urg, x)                        \
  961. X    if( dbg[cat].on[urg] ) { x; } else 
  962. X#define    debug_init(str)                            \
  963. X    DebugInit(str)
  964. X
  965. X/* debug styles */
  966. X#define    D     0
  967. X#define    DD     1
  968. X#define    DDD     2
  969. X
  970. X/* debug flags */
  971. X#define    DSP     1        /*  z01.c   -dsp   Supervise                 */
  972. X#define    DLA     2        /*  z02.c   -dla   Lexical Analyser          */
  973. X#define    DFS     3        /*  z03.c   -dfs   File Service              */
  974. X#define    DTS     4        /*  z04.c   -dts   Token Service             */
  975. X#define    DRD     5        /*  z05.c   -drd   Read Definitions          */
  976. X#define    DOP     6        /*  z06.c   -dop   Object Parser             */
  977. X#define    DOS     7        /*  z07.c   -dos   Object Service            */
  978. X#define    DOM     8        /*  z08.c   -dom   Object Manifest           */
  979. X#define    DCE     9        /*  z09.c   -dce   Closure Expansion         */
  980. X#define    DCR    10        /*  z10.c   -dcr   Cross References         */
  981. X#define    DSS    11        /*  z11.c   -dss   Style Service         */
  982. X#define    DSF    12        /*  z12.c   -dsf   Size Finder               */
  983. X#define    DOB    13        /*  z13.c   -dob   Object Breaking         */
  984. X#define    DOF    14        /*  z14.c   -dof   Object Filling         */
  985. X#define    DSC    15        /*  z15.c   -dsc   Size Constraints          */
  986. X#define    DSA    16        /*  z16.c   -dsa   Size Adjustments         */
  987. X#define    DGW    17        /*  z17.c   -dgw   Gap Widths                */
  988. X#define    DGT    18        /*  z18.c   -dgt   Galley Transfer           */
  989. X#define    DGA    19        /*  z19.c   -dgf   Galley Attaching          */
  990. X#define    DGF    20        /*  z20.c   -dgf   Galley Flushing           */
  991. X#define    DGM    21        /*  z21.c   -dgm   Galley Maker              */
  992. X#define    DGS    22        /*  z22.c   -dgs   Galley Service            */
  993. X#define    DGP    23        /*  z23.c   -dgp   Galley Printer            */
  994. X#define    DPS    24        /*  z24.c   -dps   Print Service             */
  995. X#define    DOE    25        /*  z25.c   -doe   Object Echo               */
  996. X#define    DES    26        /*  z26.c   -des   Echo Service             */
  997. X#define    DZZ    27        /*  z27.c   -dzz   Debug Service             */
  998. X#define    DYY    28        /*  z28.c   -dyy   Error Service             */
  999. X#define    DST    29        /*  z29.c   -dst   Symbol Table              */
  1000. X#define    DSU    30        /*  z30.c   -dsu   Symbol Uses               */
  1001. X#define    DMA    31        /*  z31.c   -dma   Memory Allocator          */
  1002. X#define    DCS    32        /*  z32.c   -dcs   Counter Service           */
  1003. X#define    DBS    33        /*  z33.c   -dbs   Database Service          */
  1004. X#define    DRS    34        /*  z34.c   -drs   Rotation Service          */
  1005. X#define    DTK    35        /*  z35.c   -dtk   Time Keeper               */
  1006. X#define    DHY    36        /*  z36.c   -dhy   Hyphenation               */
  1007. X#define    DFT    37        /*  z37.c   -dft   Font Service              */
  1008. X#define    DEV    38        /*  z38.c   -dev   Encoding Vectors          */
  1009. X#define    DSH    39        /*  z39.c   -dsh   String Handler            */
  1010. X#define    DPP    40        /*          -dpp   Profiling                 */
  1011. X#define    ANY    41        /*          -d     any                       */
  1012. X
  1013. X#else
  1014. X#define ifdebug(cat, urg, x)
  1015. X#define debug0(cat, urg, str)
  1016. X#define debug1(cat, urg, str, p1)
  1017. X#define debug2(cat, urg, str, p1, p2)
  1018. X#define debug3(cat, urg, str, p1, p2, p3)
  1019. X#define debug4(cat, urg, str, p1, p2, p3, p4)
  1020. X#define debug5(cat, urg, str, p1, p2, p3, p4, p5)
  1021. X#define debug6(cat, urg, str, p1, p2, p3, p4, p5, p6)
  1022. X#define debug7(cat, urg, str, p1, p2, p3, p4, p5, p6, p7)
  1023. X#define debug8(cat, urg, str, p1, p2, p3, p4, p5, p6, p7, p8)
  1024. X#define    debug_init(str)    Error(FATAL, no_fpos,            \
  1025. X            "%s - debug flags not implemented", str)
  1026. X#endif
  1027. END_OF_FILE
  1028.   if test 49929 -ne `wc -c <'externs.B'`; then
  1029.     echo shar: \"'externs.B'\" unpacked with wrong size!
  1030.   elif test -f 'externs.A' ; then
  1031.     echo shar: Combining  \"'externs'\" \(96127 characters\)
  1032.     cat 'externs.A' 'externs.B' > 'externs'
  1033.     if test 96127 -ne `wc -c <'externs'`; then
  1034.       echo shar: \"'externs'\" combined with wrong size!
  1035.     else
  1036.       rm externs.A externs.B
  1037.     fi
  1038.   fi
  1039.   # end of 'externs.B'
  1040. fi
  1041. if test -f 'font/README' -a "${1}" != "-c" ; then 
  1042.   echo shar: Will not clobber existing file \"'font/README'\"
  1043. else
  1044.   echo shar: Extracting \"'font/README'\" \(419 characters\)
  1045.   sed "s/^X//" >'font/README' <<'END_OF_FILE'
  1046. XDirectory lout/font0 - font metrics for ASCII
  1047. X
  1048. XThis directory contains Adobe Systems font metrics
  1049. X(.AFM) files for the ASCII character set, exactly as
  1050. Xdistributed by Adobe Systems except that erroneous
  1051. Xligature information has been removed from Couri*.AFM
  1052. X(Courier font).  These files are the source of Lout's
  1053. Xinformation about the height and width of all characters.
  1054. X
  1055. XJeffrey H. Kingston
  1056. X30 July 1991
  1057. X22 December 1992
  1058. END_OF_FILE
  1059.   if test 419 -ne `wc -c <'font/README'`; then
  1060.     echo shar: \"'font/README'\" unpacked with wrong size!
  1061.   fi
  1062.   # end of 'font/README'
  1063. fi
  1064. if test -f 'z05.c' -a "${1}" != "-c" ; then 
  1065.   echo shar: Will not clobber existing file \"'z05.c'\"
  1066. else
  1067.   echo shar: Extracting \"'z05.c'\" \(20549 characters\)
  1068.   sed "s/^X//" >'z05.c' <<'END_OF_FILE'
  1069. X/*@z05.c:Read Definitions:ReadFontDef()@**************************************/
  1070. X/*                                                                           */
  1071. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  1072. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1073. X/*                                                                           */
  1074. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1075. X/*  Basser Department of Computer Science                                    */
  1076. X/*  The University of Sydney 2006                                            */
  1077. X/*  AUSTRALIA                                                                */
  1078. X/*                                                                           */
  1079. X/*  This program is free software; you can redistribute it and/or modify     */
  1080. X/*  it under the terms of the GNU General Public License as published by     */
  1081. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1082. X/*  any later version.                                                       */
  1083. X/*                                                                           */
  1084. X/*  This program is distributed in the hope that it will be useful,          */
  1085. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1086. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1087. X/*  GNU General Public License for more details.                             */
  1088. X/*                                                                           */
  1089. X/*  You should have received a copy of the GNU General Public License        */
  1090. X/*  along with this program; if not, write to the Free Software              */
  1091. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1092. X/*                                                                           */
  1093. X/*  FILE:         z05.c                                                      */
  1094. X/*  MODULE:       Read Definitions                                           */
  1095. X/*  EXTERNS:      ReadPrependDef(), ReadDatabaseDef(), ReadDefinitions()     */
  1096. X/*                                                                           */
  1097. X/*****************************************************************************/
  1098. X#include "externs"
  1099. X
  1100. X
  1101. X/*****************************************************************************/
  1102. X/*                                                                           */
  1103. X/*  is_string(t, str)                                                        */
  1104. X/*                                                                           */
  1105. X/*  If t is a token denoting unquoted word str, return TRUE.                 */
  1106. X/*                                                                           */
  1107. X/*****************************************************************************/
  1108. X
  1109. X#define is_string(t, str)    (type(t) == WORD && StringEqual(string(t), str) )
  1110. X
  1111. X
  1112. X/*****************************************************************************/
  1113. X/*                                                                           */
  1114. X/*  static ReadFontDef(encl)                                                 */
  1115. X/*                                                                           */
  1116. X/*  Read one font definition and pass it on to the font module.  The         */
  1117. X/*  syntax is  fontdef <family> <face> { <object> }.                         */
  1118. X/*                                                                           */
  1119. X/*****************************************************************************/
  1120. X
  1121. Xstatic ReadFontDef(encl)
  1122. XOBJECT encl;
  1123. X{ OBJECT t, family, face, inside;
  1124. X  
  1125. X  SuppressScope();
  1126. X  family = LexGetToken();
  1127. X  if( !is_word(type(family)) )
  1128. X    Error(WARN, &fpos(family), "expected font family name here");
  1129. X  face = LexGetToken();
  1130. X  if( !is_word(type(face)) )
  1131. X    Error(WARN, &fpos(face), "expected font face name here");
  1132. X  UnSuppressScope();
  1133. X  t = LexGetToken();
  1134. X  if( type(t) != LBR )
  1135. X  { Error(WARN, &fpos(t), "expected opening %s of fontdef here", KW_LBR);
  1136. X    Dispose(t);
  1137. X    return;
  1138. X  }
  1139. X  inside = Parse(&t, encl, FALSE, FALSE);
  1140. X  inside = ReplaceWithTidy(inside);
  1141. X  FontDefine(family, face, inside);
  1142. X  return;
  1143. X} /* end ReadFontDef */
  1144. X
  1145. X
  1146. X/*@::ReadPrependDef(), ReadDatabaseDef()@*************************************/
  1147. X/*                                                                           */
  1148. X/*  ReadPrependDef(typ, encl)                                                */
  1149. X/*                                                                           */
  1150. X/*  Read @Prepend { <filename> } and record its presence.                    */
  1151. X/*                                                                           */
  1152. X/*****************************************************************************/
  1153. X
  1154. XReadPrependDef(typ, encl)
  1155. Xunsigned typ;  OBJECT encl;
  1156. X{ OBJECT t, fname;  FILE_NUM fnum;
  1157. X  t = LexGetToken();
  1158. X  if( type(t) != LBR )
  1159. X  { Error(WARN, &fpos(t), "symbol name or %s expected here in %s declaration",
  1160. X      KW_LBR, KW_PREPEND);
  1161. X    Dispose(t);
  1162. X    return;
  1163. X  }
  1164. X  fname = Parse(&t, encl, FALSE, FALSE);
  1165. X  fname = ReplaceWithTidy(fname);
  1166. X  if( !is_word(type(fname)) )
  1167. X  { Error(WARN, &fpos(fname), "name of %s file expected here", KW_PREPEND);
  1168. X    DisposeObject(fname);
  1169. X    return;
  1170. X  }
  1171. X  fnum = DefineFile(string(fname), STR_EMPTY, &fpos(fname), PREPEND_FILE,
  1172. X       typ == PREPEND ? INCLUDE_PATH : SYSINCLUDE_PATH);
  1173. X
  1174. X} /* end ReadPrependDef */
  1175. X
  1176. X
  1177. X/*****************************************************************************/
  1178. X/*                                                                           */
  1179. X/*  ReadDatabaseDef(typ, encl)                                               */
  1180. X/*                                                                           */
  1181. X/*  Read @Database <symname> ... <symname> { <filename> } and record it.     */
  1182. X/*                                                                           */
  1183. X/*****************************************************************************/
  1184. X
  1185. XReadDatabaseDef(typ, encl)
  1186. Xunsigned typ;  OBJECT encl;
  1187. X{ OBJECT symbs, t, db, fname;
  1188. X  symbs = New(ACAT);
  1189. X  t = LexGetToken();
  1190. X  while( type(t) == CLOSURE )
  1191. X  { Link(symbs, t);
  1192. X    t = LexGetToken();
  1193. X  }
  1194. X  if( type(t) != LBR )
  1195. X  { Error(WARN, &fpos(t), "symbol name or %s expected here in %s declaration",
  1196. X      KW_LBR, KW_DATABASE);
  1197. X    Dispose(t);
  1198. X    return;
  1199. X  }
  1200. X  if( Down(symbs) == symbs )
  1201. X  { Error(WARN, &fpos(t), "symbol names missing in %s declaration",
  1202. X      KW_DATABASE);
  1203. X    Dispose(t);
  1204. X    return;
  1205. X  }
  1206. X  fname = Parse(&t, encl, FALSE, FALSE);
  1207. X  fname = ReplaceWithTidy(fname);
  1208. X  if( !is_word(type(fname)) )
  1209. X  { Error(WARN, &fpos(fname), "name of %s file expected here", KW_DATABASE);
  1210. X    DisposeObject(fname);
  1211. X    return;
  1212. X  }
  1213. X  db = DbLoad(fname, typ == DATABASE ? DATABASE_PATH : SYSDATABASE_PATH,
  1214. X     TRUE, symbs);
  1215. X} /* end ReadDatabaseDef */
  1216. X
  1217. X
  1218. X/*@::ReadTokenList()@*********************************************************/
  1219. X/*                                                                           */
  1220. X/*  static ReadTokenList(res)                                                */
  1221. X/*                                                                           */
  1222. X/*  Read a list of tokens from input and append them to sym_body(res).       */
  1223. X/*  The list is assumed to begin immediately after an LBR, and input is      */
  1224. X/*  to be read up to and including the matching RBR.                         */
  1225. X/*                                                                           */
  1226. X/*****************************************************************************/
  1227. X#define NextToken(t, res)                        \
  1228. X  t = LexGetToken(); sym_body(res) = Append(sym_body(res), t, PARENT);
  1229. X
  1230. Xstatic ReadTokenList(res)
  1231. XOBJECT res;
  1232. X{ OBJECT t, xsym, new_par;
  1233. X  NextToken(t, res);
  1234. X  for(;;) switch(type(t))
  1235. X  {
  1236. X    case WORD:
  1237. X
  1238. X      if( string(t)[0] == CH_SYMSTART )
  1239. X    Error(WARN, &fpos(t), "symbol %s unknown", string(t));
  1240. X      NextToken(t, res);
  1241. X      break;
  1242. X
  1243. X
  1244. X    case QWORD:
  1245. X
  1246. X      NextToken(t, res);
  1247. X      break;
  1248. X
  1249. X
  1250. X    case VCAT:
  1251. X    case HCAT:
  1252. X    case ACAT:
  1253. X    case CROSS:
  1254. X    case NULL_CLOS:
  1255. X    case ONE_COL:
  1256. X    case ONE_ROW:
  1257. X    case WIDE:
  1258. X    case HIGH:
  1259. X    case HSCALE:
  1260. X    case VSCALE:
  1261. X    case SCALE:
  1262. X    case HCONTRACT:
  1263. X    case VCONTRACT:
  1264. X    case HEXPAND:
  1265. X    case VEXPAND:
  1266. X    case PADJUST:
  1267. X    case HADJUST:
  1268. X    case VADJUST:
  1269. X    case ROTATE:
  1270. X    case CASE:
  1271. X    case YIELD:
  1272. X    case XCHAR:
  1273. X    case FONT:
  1274. X    case SPACE:
  1275. X    case BREAK:
  1276. X    case NEXT:
  1277. X    case TAGGED:
  1278. X    case INCGRAPHIC:
  1279. X    case SINCGRAPHIC:
  1280. X    case GRAPHIC:
  1281. X
  1282. X      NextToken(t, res);
  1283. X      break;
  1284. X
  1285. X
  1286. X    case LVIS:
  1287. X    case ENV:
  1288. X    case USE:
  1289. X    case BEGIN:
  1290. X    case END:
  1291. X    case DATABASE:
  1292. X    case SYS_DATABASE:
  1293. X    case PREPEND:
  1294. X    case SYS_PREPEND:
  1295. X    case OPEN:
  1296. X
  1297. X      Error(WARN, &fpos(t), "symbol %s not allowed in macro",
  1298. X    SymName(actual(t)));
  1299. X      NextToken(t, res);
  1300. X      break;
  1301. X
  1302. X
  1303. X    case LBR:
  1304. X
  1305. X      ReadTokenList(res);
  1306. X      NextToken(t, res);
  1307. X      break;
  1308. X
  1309. X
  1310. X    case RBR:
  1311. X
  1312. X      return;
  1313. X
  1314. X
  1315. X    case CLOSURE:
  1316. X
  1317. X      xsym = actual(t);
  1318. X      PushScope(xsym, TRUE, FALSE);
  1319. X      NextToken(t, res);
  1320. X      PopScope();
  1321. X      if( type(t) == CROSS )
  1322. X      { NextToken(t, res);
  1323. X    break;
  1324. X      }
  1325. X
  1326. X      /* read named parameters */
  1327. X      while( type(t) == CLOSURE && enclosing(actual(t)) == xsym &&
  1328. X         type(actual(t)) == NPAR )
  1329. X      {    new_par = t;
  1330. X    NextToken(t, res);
  1331. X    if( type(t) != LBR )
  1332. X    { Error(WARN, &fpos(new_par), "%s must follow name parameter %s",
  1333. X        KW_LBR, SymName(actual(new_par)));
  1334. X      break;
  1335. X    }
  1336. X    PushScope(actual(new_par), FALSE, FALSE);
  1337. X    ReadTokenList(res);
  1338. X    PopScope();
  1339. X
  1340. X    /* get next token, possibly another named parameter */
  1341. X    PushScope(xsym, TRUE, FALSE);
  1342. X    NextToken(t, res);
  1343. X    PopScope();
  1344. X      }
  1345. X
  1346. X      /* read body parameter, if any */
  1347. X      if( has_body(xsym) )
  1348. X      {    if( type(t) == LBR )
  1349. X    { PushScope(xsym, FALSE, TRUE);
  1350. X      PushScope(ChildSym(xsym, RPAR), FALSE, FALSE);
  1351. X      ReadTokenList(res);
  1352. X      PopScope();
  1353. X      PopScope();
  1354. X      NextToken(t, res);
  1355. X    }
  1356. X    else Error(WARN, &fpos(t), "right parameter of %s must begin with %s",
  1357. X        SymName(xsym), KW_LBR);
  1358. X      }
  1359. X      break;
  1360. X
  1361. X    default:
  1362. X
  1363. X
  1364. X      Error(INTERN, &fpos(t), "unknown token type %s", Image(type(t)));
  1365. X      break;
  1366. X
  1367. X  }
  1368. X} /* end ReadTokenList */
  1369. X
  1370. X
  1371. X/*@::ReadMacro()@*************************************************************/
  1372. X/*                                                                           */
  1373. X/*  static OBJECT ReadMacro(token, encl)                                     */
  1374. X/*                                                                           */
  1375. X/*  Read a macro from input and insert into symbol table.                    */
  1376. X/*  Token *token contains the "macro" keyword.  Input is read up to and      */
  1377. X/*  including the closing right brace, and nil is returned in *token if OK.  */
  1378. X/*  The proper scope for reading the macro body is open at entry and exit.   */
  1379. X/*  ReadMacro returns the new symbol table entry if successful, else nil.    */
  1380. X/*                                                                           */
  1381. X/*****************************************************************************/
  1382. X
  1383. Xstatic OBJECT ReadMacro(token, encl)
  1384. XOBJECT *token, encl;
  1385. X{ OBJECT t, res;
  1386. X
  1387. X  /* find macro name and insert into symbol table */
  1388. X  SuppressScope();
  1389. X  Dispose(*token);  t = LexGetToken();
  1390. X  if( !is_word(type(t)) )
  1391. X  { Error(WARN, &fpos(t), "%s ignored - name is missing", KW_MACRO);
  1392. X    debug1(ANY, D, "offending type is %s", Image(type(t)));
  1393. X    UnSuppressScope();
  1394. X    *token = t;
  1395. X    return nil;
  1396. X  }
  1397. X  res = InsertSym(string(t), MACRO, &fpos(t), 0, FALSE, TRUE, 0, encl, nil);
  1398. X
  1399. X  /* find opening left brace */
  1400. X  t = LexGetToken();
  1401. X  if( !is_string(t, KW_LBR) )
  1402. X  { Error(WARN, &fpos(t), "%s ignored - opening %s missing", KW_MACRO, KW_LBR);
  1403. X    UnSuppressScope();
  1404. X    *token = t;
  1405. X    return nil;
  1406. X  }
  1407. X  Dispose(t);
  1408. X  
  1409. X  /* read macro body */
  1410. X  UnSuppressScope();
  1411. X  ReadTokenList(res);
  1412. X
  1413. X  /* clean up (kill final RBR, dispose macro name) and exit */
  1414. X  sym_body(res) = DeleteAndDispose(pred(sym_body(res), PARENT), PARENT);
  1415. X  recursive(res) = FALSE;
  1416. X  *token = nil;
  1417. X  return res;
  1418. X} /* end ReadMacro */
  1419. X
  1420. X
  1421. X/*@::ReadDefinitions()@*******************************************************/
  1422. X/*                                                                           */
  1423. X/*  ReadDefinitions(token, encl, res_type)                                   */
  1424. X/*                                                                           */
  1425. X/*  Read a sequence of definitions and insert them into the symbol table.    */
  1426. X/*  Either a sequence of local definitions (res_type == LOCAL) or named      */
  1427. X/*  parameters (res_type == NPAR) is expected; *token is the first def etc.  */
  1428. X/*  A scope appropriate for reading the bodies of the definitions is open.   */
  1429. X/*  The parent definition is encl.                                           */
  1430. X/*                                                                           */
  1431. X/*****************************************************************************/
  1432. X
  1433. XReadDefinitions(token, encl, res_type)
  1434. XOBJECT *token, encl;  unsigned char res_type;
  1435. X{ OBJECT t, res, res_target, export_list, import_list, link, y, z;
  1436. X  t = *token;
  1437. X
  1438. X  while( res_type != LOCAL ? is_string(t, KW_NAMED) : TRUE )
  1439. X  {
  1440. X    if( is_string(t, KW_FONTDEF) )
  1441. X    { ReadFontDef(encl);
  1442. X      t = LexGetToken();
  1443. X      continue;  /* next definition */
  1444. X    }
  1445. X    else if( type(t) == PREPEND || type(t) == SYS_PREPEND )
  1446. X    { ReadPrependDef(type(t), encl);
  1447. X      Dispose(t);
  1448. X      t = LexGetToken();
  1449. X      continue;  /* next definition */
  1450. X    }
  1451. X    else if( type(t) == DATABASE || type(t) == SYS_DATABASE )
  1452. X    { ReadDatabaseDef(type(t), encl);
  1453. X      Dispose(t);
  1454. X      t = LexGetToken();
  1455. X      continue;  /* next definition */
  1456. X    }
  1457. X
  1458. X    if( !is_string(t, KW_DEF)   && !is_string(t, KW_MACRO)  &&
  1459. X    !is_string(t, KW_NAMED) && !is_string(t, KW_IMPORT) &&
  1460. X        !is_string(t, KW_EXPORT) )
  1461. X      break;
  1462. X
  1463. X    /* get import list and change scope appropriately */
  1464. X    BodyParNotAllowed();
  1465. X    import_list = New(ACAT);
  1466. X    if( is_string(t, KW_IMPORT) )
  1467. X    { Dispose(t);
  1468. X      t = LexGetToken();
  1469. X      while( type(t) == CLOSURE ||
  1470. X           (type(t)==WORD && !is_string(t,KW_EXPORT) && !is_string(t,KW_DEF)
  1471. X           && !is_string(t, KW_MACRO)) )
  1472. X      {    if( type(t) == CLOSURE )
  1473. X    { if( type(actual(t)) == LOCAL )
  1474. X      { PushScope(actual(t), FALSE, TRUE);
  1475. X        Link(import_list, t);
  1476. X      }
  1477. X      else
  1478. X      { Error(WARN, &fpos(t), "import name expected here");
  1479. X        Dispose(t);
  1480. X      }
  1481. X    }
  1482. X    else
  1483. X    { Error(WARN,&fpos(t),"import %s not in scope", string(t));
  1484. X      Dispose(t);
  1485. X    }
  1486. X    t = LexGetToken();
  1487. X      }
  1488. X    }
  1489. X
  1490. X    /* get export list and store for setting visible flags below */
  1491. X    export_list = New(ACAT);
  1492. X    if( is_string(t, KW_EXPORT) )
  1493. X    { Dispose(t);
  1494. X      SuppressScope();
  1495. X      t = LexGetToken();
  1496. X      while( is_word(type(t)) && !is_string(t, KW_DEF) )
  1497. X      { Link(export_list, t);
  1498. X    t = LexGetToken();
  1499. X      }
  1500. X      UnSuppressScope();
  1501. X    }
  1502. X
  1503. X
  1504. X    if( res_type == LOCAL && !is_string(t, KW_DEF) && !is_string(t, KW_MACRO) )
  1505. X    { Error(WARN,&fpos(t),"keyword %s or %s expected here", KW_DEF, KW_MACRO);
  1506. X      break;
  1507. X    }
  1508. X    if( res_type == NPAR && !is_string(t, KW_NAMED) )
  1509. X    { Error(WARN, &fpos(t), "keyword %s expected here", KW_NAMED);
  1510. X      break;
  1511. X    }
  1512. X
  1513. X    if( is_string(t, KW_MACRO) )
  1514. X    { if( Down(export_list) != export_list )
  1515. X    Error(WARN, &fpos(t), "ignoring %s list of %s", KW_EXPORT, KW_MACRO);
  1516. X      res = ReadMacro(&t, encl);
  1517. X    }
  1518. X    else
  1519. X    {
  1520. X      SuppressScope();  Dispose(t);  t = LexGetToken();
  1521. X
  1522. X      /* find name of symbol and insert it */
  1523. X      if( !is_word(type(t)) )
  1524. X      { Error(WARN, &fpos(t), "cannot find symbol name");
  1525. X    debug1(ANY, D, "offending type is %s", Image(type(t)));
  1526. X    UnSuppressScope();
  1527. X    *token = t;
  1528. X    return;
  1529. X      }
  1530. X      res = InsertSym(string(t), res_type, &fpos(t), DEFAULT_PREC,
  1531. X        FALSE, FALSE, 0, encl, nil);
  1532. X      t = LexGetToken();
  1533. X
  1534. X      /* find force, if any */
  1535. X      if( is_string(t, KW_FORCE) )
  1536. X      {    force_target(res) = TRUE;
  1537. X    Dispose(t);  t = LexGetToken();
  1538. X    if( !is_string(t, KW_INTO) )
  1539. X       Error(WARN, &fpos(t), "%s expected after %s", KW_INTO, KW_FORCE);
  1540. X      }
  1541. X    
  1542. X      /* find into clause, if any */
  1543. X      res_target = nil;
  1544. X      if( is_string(t, KW_INTO) )
  1545. X      { UnSuppressScope();
  1546. X    Dispose(t);  t = LexGetToken();
  1547. X    if( type(t) != LBR )
  1548. X    { Error(WARN, &fpos(t), "%s expected after %s", KW_LBR, KW_INTO);
  1549. X      debug1(ANY, D, "offending type is %s", Image(type(t)));
  1550. X      UnSuppressScope();
  1551. X      *token = t;
  1552. X      return;
  1553. X    }
  1554. X    res_target = Parse(&t, encl, FALSE, FALSE);
  1555. X    SuppressScope();
  1556. X    if( t == nil )  t = LexGetToken();
  1557. X      }
  1558. X
  1559. X      /* find precedence clause, if any */
  1560. X      if( is_string(t, KW_PRECEDENCE) )
  1561. X      {    int prec = 0;
  1562. X    Dispose(t);
  1563. X    t = LexGetToken();
  1564. X    while( type(t) == WORD && decimaldigit(string(t)[0]) )
  1565. X    {
  1566. X      prec = prec * 10 + digitchartonum(string(t)[0]);
  1567. X      Dispose(t);  t = LexGetToken();
  1568. X    }
  1569. X
  1570. X    if( prec < MIN_PREC )
  1571. X    { Error(WARN, &fpos(t), "%s is too low - %d substituted",
  1572. X        KW_PRECEDENCE, MIN_PREC);
  1573. X      prec = MIN_PREC;
  1574. X    }
  1575. X    else if( prec > MAX_PREC )
  1576. X    { Error(WARN, &fpos(t), "%s is too high - %d substituted",
  1577. X        KW_PRECEDENCE, MAX_PREC);
  1578. X      prec = MAX_PREC;
  1579. X    }
  1580. X    precedence(res) = prec;
  1581. X      }
  1582. X
  1583. X      /* find associativity clause, if any */
  1584. X      if( is_string(t, KW_ASSOC) )
  1585. X      {    Dispose(t);  t = LexGetToken();
  1586. X    if( is_string(t, KW_LEFT) )  right_assoc(res) = FALSE;
  1587. X    else if( !is_string(t, KW_RIGHT) )
  1588. X      Error(WARN, &fpos(t), "%s replaced by %s", KW_ASSOC, KW_RIGHT);
  1589. X    Dispose(t);  t = LexGetToken();
  1590. X      }
  1591. X
  1592. X      /* find left parameter, if any */
  1593. X      if( is_string(t, KW_LEFT) )
  1594. X      {    Dispose(t);  t = LexGetToken();
  1595. X    if( type(t) != WORD )
  1596. X    { Error(WARN, &fpos(t), "cannot find %s parameter name", KW_LEFT);
  1597. X      debug1(ANY, D, "offending type is %s", Image(type(t)));
  1598. X      UnSuppressScope();
  1599. X      *token = t;
  1600. X      return;
  1601. X    }
  1602. X    InsertSym(string(t), LPAR, &fpos(t), DEFAULT_PREC, 
  1603. X      FALSE, FALSE, 0, res, nil);
  1604. X    Dispose(t);  t = LexGetToken();
  1605. X      }
  1606. X
  1607. X      /* find named parameters, if any */
  1608. X      UnSuppressScope();
  1609. X      ReadDefinitions(&t, res, NPAR);
  1610. X
  1611. X      /* find right or body parameter, if any */
  1612. X      if( is_string(t, KW_RIGHT) || is_string(t, KW_BODY) )
  1613. X      {    has_body(res) = is_string(t, KW_BODY);
  1614. X    SuppressScope();
  1615. X    Dispose(t);  t = LexGetToken();
  1616. X    if( type(t) != WORD )
  1617. X    { Error(WARN, &fpos(t), "cannot find %s parameter name", KW_RIGHT);
  1618. X      debug1(ANY, D, "offending type is %s", Image(type(t)));
  1619. X      UnSuppressScope();
  1620. X      *token = t;
  1621. X      return;
  1622. X    }
  1623. X    InsertSym(string(t), RPAR, &fpos(t), DEFAULT_PREC,
  1624. X      FALSE, FALSE, 0, res, nil);
  1625. X    UnSuppressScope();
  1626. X    Dispose(t);  t = LexGetToken();
  1627. X      }
  1628. X
  1629. X      /* read local definitions and body */
  1630. X      if( res_target != nil )
  1631. X    InsertSym(KW_TARGET, LOCAL, &fpos(res_target), DEFAULT_PREC,
  1632. X            FALSE, FALSE, 0, res, res_target);
  1633. X      if( type(t) == WORD && StringEqual(string(t), KW_LBR) )
  1634. X      {    z = NewToken(LBR, &fpos(t), 0, 0, LBR_PREC, StartSym);
  1635. X    Dispose(t);
  1636. X    t = z;
  1637. X      }
  1638. X      else if( type(t) == WORD && StringEqual(string(t), KW_BEGIN) )
  1639. X      {    z = NewToken(BEGIN, &fpos(t), 0, 0, BEGIN_PREC, StartSym);
  1640. X    Dispose(t);
  1641. X    t = z;
  1642. X      }
  1643. X      else if( type(t) != LBR && type(t) != BEGIN )
  1644. X    Error(FATAL, &fpos(t), "opening %s or %s of %s expected",
  1645. X     KW_LBR, KW_BEGIN, SymName(res));
  1646. X      if( type(t) == BEGIN )  actual(t) = res;
  1647. X      PushScope(res, FALSE, FALSE);
  1648. X      BodyParAllowed();
  1649. X      sym_body(res) = Parse(&t, res, TRUE, FALSE);
  1650. X
  1651. X      /* set visible flag of the exported symbols */
  1652. X      for( link=Down(export_list);  link != export_list;  link=NextDown(link) )
  1653. X      {    Child(y, link);
  1654. X    z = SearchSym(string(y), StringLength(string(y)));
  1655. X    if( z == nil || enclosing(z) != res )
  1656. X      Error(WARN, &fpos(y), "exported symbol %s not defined in %s",
  1657. X        string(y), SymName(res));
  1658. X    else if( has_body(res) && type(z) == RPAR )
  1659. X      Error(WARN, &fpos(y), "body parameter %s may not be exported",
  1660. X        string(y));
  1661. X    else if( visible(z) )
  1662. X      Error(WARN, &fpos(y), "symbol %s exported twice", string(y));
  1663. X    else visible(z) = TRUE;
  1664. X      }
  1665. X      DisposeObject(export_list);
  1666. X
  1667. X      /* pop scope of res */
  1668. X      PopScope();
  1669. X    }
  1670. X
  1671. X    /* pop import scopes and store imports in sym tab */
  1672. X    for( link=Down(import_list);  link != import_list;  link=NextDown(link) )
  1673. X      PopScope();
  1674. X    if( Down(import_list) == import_list )
  1675. X    { Dispose(import_list);
  1676. X      import_list = nil;
  1677. X    }
  1678. X    if( res != nil )  imports(res) = import_list;
  1679. X
  1680. X    BodyParAllowed();
  1681. X    if( t == nil ) t = LexGetToken();
  1682. X
  1683. X  } /* end while */
  1684. X
  1685. X  *token = t;
  1686. X  return;
  1687. X} /* end ReadDefinitions */
  1688. END_OF_FILE
  1689.   if test 20549 -ne `wc -c <'z05.c'`; then
  1690.     echo shar: \"'z05.c'\" unpacked with wrong size!
  1691.   fi
  1692.   # end of 'z05.c'
  1693. fi
  1694. echo shar: End of archive 3 \(of 35\).
  1695. cp /dev/null ark3isdone
  1696. MISSING=""
  1697. 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 31 32 33 34 35 ; do
  1698.     if test ! -f ark${I}isdone ; then
  1699.     MISSING="${MISSING} ${I}"
  1700.     fi
  1701. done
  1702. if test "${MISSING}" = "" ; then
  1703.     echo You have unpacked all 35 archives.
  1704.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1705. else
  1706.     echo You still must unpack the following archives:
  1707.     echo "        " ${MISSING}
  1708. fi
  1709. exit 0
  1710. exit 0 # Just in case...
  1711.