home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / ltroff / part02 < prev    next >
Encoding:
Text File  |  1993-07-14  |  75.4 KB  |  3,308 lines

  1. Newsgroups: comp.sources.unix
  2. From: ado@elsie.nci.nih.gov (Arthur David Olson)
  3. Subject: v26i295: ltroff - troff-classic to laserjet 4 filter (incl scalable fonts), Part02/02
  4. Sender: unix-sources-moderator@gw.home.vix.com
  5. Approved: vixie@gw.home.vix.com
  6.  
  7. Submitted-By: ado@elsie.nci.nih.gov (Arthur David Olson)
  8. Posting-Number: Volume 26, Issue 295
  9. Archive-Name: ltroff/part02
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 2 (of 2)."
  18. # Contents:  ansic.h catsup.c testfile tlc.c
  19. # Wrapped by vixie@gw.home.vix.com on Thu Jul 15 16:33:18 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'ansic.h' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'ansic.h'\"
  23. else
  24. echo shar: Extracting \"'ansic.h'\" \(9305 characters\)
  25. sed "s/^X//" >'ansic.h' <<'END_OF_FILE'
  26. X#ifndef ANSIC_H
  27. X
  28. X#define ANSIC_H
  29. X
  30. X/*
  31. X** ID
  32. X*/
  33. X
  34. X#ifndef ID
  35. X#ifndef lint
  36. X#ifndef NOID
  37. X#define ID(name, value)    static char    (name)[] = value;
  38. X#endif /* !defined NOID */
  39. X#endif /* !defined lint */
  40. X#ifndef ID
  41. X#define ID(name, value)    /* static char    (name)[] = value; */
  42. X#endif /* !defined ID */
  43. X#endif /* !defined ID */
  44. X
  45. X#ifndef ELSIEID
  46. X#define ELSIEID(value)    ID(elsieid, (value))
  47. X#endif /* !defined ELSIEID */
  48. X
  49. XID(ansichid, "@(#)ansic.h    4.1")
  50. X
  51. X/*
  52. X** Cover for stupid IBM PC/RT compilers (pcc and hc);
  53. X** they fib about being __STDC__ when they lack standard header files
  54. X** ("locale.h" for one).
  55. X*/
  56. X
  57. X#ifdef ibm032
  58. X#undef __STDC__
  59. X#define VOID_OK
  60. X#endif /* defined ibm032 */
  61. X
  62. X#ifdef sgi
  63. X#define STDIO_H    <stdio.h>
  64. X#define MATH_H    <math.h>
  65. X#define remove    unlink
  66. X#endif /* defined sgi */
  67. X
  68. X/*
  69. X** const
  70. X*/
  71. X
  72. X#ifndef const
  73. X
  74. X#ifndef CONST_OK
  75. X#ifndef CONST_NO
  76. X#ifdef __convexc__
  77. X/*
  78. X** Workaround for Convex CC bug that muffs
  79. X**    func(int * const * const p){}
  80. X*/
  81. X#define CONST_NO
  82. X#endif /* defined __convexc__ */
  83. X#endif /* !defined CONST_NO */
  84. X#endif /* !defined CONST_OK */
  85. X
  86. X#ifndef CONST_OK
  87. X#ifndef CONST_NO
  88. X#ifdef __STDC__
  89. X#define CONST_OK
  90. X#endif /* defined __STDC__ */
  91. X#endif /* !defined CONST_NO */
  92. X#endif /* !defined CONST_OK */
  93. X
  94. X#ifndef CONST_OK
  95. X#define const
  96. X#endif /* !defined CONST_OK */
  97. X
  98. X#endif /* !defined const */
  99. X
  100. X/*
  101. X** void
  102. X*/
  103. X
  104. X#ifndef void
  105. X
  106. X#ifndef VOID_NO
  107. X#ifndef VOID_OK
  108. X
  109. X#ifdef __STDC__
  110. X#define VOID_OK
  111. X#endif /* defined __STDC__ */
  112. X
  113. X#ifdef sun
  114. X#define VOID_OK
  115. X#endif /* defined sun */
  116. X
  117. X#ifdef __convexc__
  118. X#define VOID_OK
  119. X#endif /* defined __convexc__ */
  120. X
  121. X#endif /* !defined VOID_OK */
  122. X#endif /* !defined VOID_NO */
  123. X
  124. X#ifndef VOID_OK
  125. X#define void char
  126. X#endif /* !defined VOID_OK */
  127. X
  128. X#endif /* !defined void */
  129. X
  130. X/*
  131. X** P((args))
  132. X*/
  133. X
  134. X#ifndef P
  135. X
  136. X#ifndef PROTO_OK
  137. X#ifndef PROTO_NO
  138. X#ifdef __STDC__
  139. X#define PROTO_OK
  140. X#endif /* defined __STDC__ */
  141. X#endif /* !defined PROTO_NO */
  142. X#endif /* !defined PROTO_OK */
  143. X
  144. X#ifdef PROTO_OK
  145. X#define P(x)    x
  146. X#endif /* defined PROTO_OK */
  147. X
  148. X#ifndef PROTO_OK
  149. X#define P(x)    ()
  150. X#endif /* !defined PROTO_OK */
  151. X
  152. X#endif /* !defined P */
  153. X
  154. X/*
  155. X** Includes.  First the ones we expect to show up on all systems.
  156. X*/
  157. X
  158. X/*
  159. X** <assert.h>
  160. X*/
  161. X
  162. X#ifdef ASSERT_H
  163. X#include ASSERT_H
  164. X#endif /* defined ASSERT_H */
  165. X
  166. X#ifndef ASSERT_H
  167. X#include "assert.h"
  168. X#endif /* !defined ASSERT_H */
  169. X
  170. X/*
  171. X** <ctype.h>
  172. X*/
  173. X
  174. X#ifdef CTYPE_H
  175. X#include CTYPE_H
  176. X#endif /* defined CTYPE_H */
  177. X
  178. X#ifndef CTYPE_H
  179. X#include "ctype.h"
  180. X#ifdef sun
  181. X#ifndef tolower
  182. Xextern int    tolower P((
  183. X            int /*c*/
  184. X            ));
  185. Xextern int    toupper P((
  186. X            int /*c*/
  187. X            ));
  188. X#endif /* !defined tolower */
  189. X#endif /* defined sun */
  190. X#endif /* !defined CTYPE_H */
  191. X
  192. X/*
  193. X** <errno.h>
  194. X*/
  195. X
  196. X#ifdef ERRNO_H
  197. X#include ERRNO_H
  198. X#endif /* defined ERRNO_H */
  199. X
  200. X#ifndef ERRNO_H
  201. X#include "errno.h"
  202. X#ifndef errno
  203. Xextern int    errno;
  204. X#endif /* !defined errno */
  205. X#endif /* !defined ERRNO_H */
  206. X
  207. X/*
  208. X** <math.h>
  209. X*/
  210. X
  211. X#ifdef MATH_H
  212. X#include MATH_H
  213. X#endif /* defined MATH_H */
  214. X
  215. X#ifndef MATH_H
  216. X#include "math.h"
  217. X#ifndef __STDC__
  218. X#ifndef mips
  219. X/*
  220. X** This declaration is missing in the 4.1BSD math.h;
  221. X** we'll play it safe.
  222. X*/
  223. Xextern double    erf();
  224. X#endif /* !defined mips */
  225. X#endif  /* !defined __STDC__ */
  226. X#endif /* !defined MATH_H */
  227. X
  228. X/*
  229. X** <setjmp.h>
  230. X*/
  231. X
  232. X#ifdef SETJMP_H
  233. X#include SETJMP_H
  234. X#endif /* defined SETJMP_H */
  235. X
  236. X#ifndef SETJMP_H
  237. X#include "setjmp.h"
  238. X#endif /* !defined SETJMP_H */
  239. X
  240. X/*
  241. X** <signal.h>
  242. X*/
  243. X
  244. X#ifdef SIGNAL_H
  245. X#include SIGNAL_H
  246. X#endif /* defined SIGNAL_H */
  247. X
  248. X#ifndef SIGNAL_H
  249. X#include "signal.h"
  250. X#ifdef mips
  251. X/*
  252. X** For the benefit of MIPS boxes, where signal isn't declared.
  253. X*/
  254. Xextern void (*    signal P((
  255. X            int /*sig*/,
  256. X            void (* /*func*/)()
  257. X            )))();
  258. X#endif /* defined mips */
  259. X#endif /* !defined SIGNAL_H */
  260. X
  261. X/*
  262. X** <stdio.h>
  263. X*/
  264. X
  265. X#ifdef STDIO_H
  266. X#include STDIO_H
  267. X#endif /* defined STDIO_H */
  268. X
  269. X#ifndef STDIO_H
  270. X#include "stdio.h"
  271. X
  272. X/*
  273. X** We get to do stdio prototypes if we are not __STDC__ or we are __GNUC__
  274. X*/
  275. X
  276. X#ifndef DO_STDIO_PROTOS
  277. X#ifdef __GNUC__
  278. X#define DO_STDIO_PROTOS
  279. X#endif /* defined __GNUC__ */
  280. X#endif /* !defined DO_STDIO_PROTOS */
  281. X
  282. X#ifndef DO_STDIO_PROTOS
  283. X#ifndef __STDC__
  284. X#ifndef __convexc__
  285. X#define DO_STDIO_PROTOS
  286. X#endif /* !defined __convexc__ */
  287. X#endif /* !defined __STDC__ */
  288. X#endif /* !defined DO_STDIO_PROTOS */
  289. X
  290. X#ifdef DO_STDIO_PROTOS
  291. Xextern int    fclose P((
  292. X            FILE * /*stream*/
  293. X            ));
  294. Xextern int    fflush P((
  295. X            FILE * /*stream*/
  296. X            ));
  297. Xextern int    fprintf P((
  298. X            FILE * /*stream*/,
  299. X            const char * /*format*/,
  300. X            ...
  301. X            ));
  302. Xextern int    fputc P((
  303. X            int /*c*/,
  304. X            FILE * /*stream*/
  305. X            ));
  306. Xextern int    fputs P((
  307. X            const char * /*s*/,
  308. X            FILE * /*stream*/
  309. X            ));
  310. Xextern int    fread P((
  311. X            void * /*p*/,
  312. X            int /*s*/,
  313. X            int /*n*/,
  314. X            FILE * /*stream*/
  315. X            ));
  316. Xextern int    fscanf P((
  317. X            FILE * /*stream*/,
  318. X            const char * /*format*/,
  319. X            ...
  320. X            ));
  321. Xextern int    fseek P((
  322. X            FILE * /*stream*/,
  323. X            long int /*offset*/,
  324. X            int /*whence*/
  325. X            ));
  326. Xextern int    fwrite P((
  327. X            const void * /*p*/,
  328. X            int /*s*/,
  329. X            int /*n*/,
  330. X            FILE * /*stream*/
  331. X            ));
  332. Xextern int    printf P((
  333. X            const char * /*format*/,
  334. X            ...
  335. X            ));
  336. Xextern int    scanf P((
  337. X            const char * /*format*/,
  338. X            ...
  339. X            ));
  340. Xextern int    sscanf P((
  341. X            const char * /*string*/,
  342. X            const char * /*format*/,
  343. X            ...
  344. X            ));
  345. Xextern char *    tmpnam P((
  346. X            const char * /*name*/
  347. X            ));
  348. Xextern int    ungetc P((
  349. X            int /*c*/,
  350. X            FILE * /*stream*/
  351. X            ));
  352. X/*
  353. X** To prevent gcc squawks when in "prototypes required" mode. . .
  354. X*/
  355. Xextern int    _filbuf P((
  356. X            FILE * /*stream*/
  357. X            ));
  358. Xextern int    _flsbuf P((
  359. X            unsigned char /*c*/,
  360. X            FILE * /*stream*/
  361. X            ));
  362. X
  363. X/*
  364. X** And last but not least among the common stuff. . .
  365. X*/
  366. X#ifndef remove
  367. Xextern int    unlink P((
  368. X            const char * /*filename*/
  369. X            ));
  370. X#define remove    unlink
  371. X#endif /* !defined remove */
  372. X
  373. X#ifdef USG
  374. Xextern void    rewind P((
  375. X            FILE * /*stream*/
  376. X            ));
  377. X#ifndef sun
  378. Xextern int    sprintf P((
  379. X            char * /*string*/,
  380. X            const char * /*format*/,
  381. X            ...
  382. X            ));
  383. X#endif /* !defined sun */
  384. X#endif /* defined USG */
  385. X#ifndef USG
  386. Xextern int    rewind P((
  387. X            FILE * /*stream*/
  388. X            ));
  389. X#ifndef sun
  390. Xextern char *    sprintf P((
  391. X            char * /*string*/,
  392. X            const char * /*format*/,
  393. X            ...
  394. X            ));
  395. X#endif /* !defined sun */
  396. X#endif /* !defined USG */
  397. X
  398. X#endif /* defined DO_STDIO_PROTOS */
  399. X
  400. X#endif /* !defined STDIO_H */
  401. X
  402. X/*
  403. X** <string.h>
  404. X*/
  405. X
  406. X#ifdef STRING_H
  407. X#include STRING_H
  408. X#endif /* defined STRING_H */
  409. X
  410. X#ifndef STRING_H
  411. X#include "string.h"
  412. X#ifdef sun
  413. X#include "memory.h"
  414. X#endif /* defined sun */
  415. X#endif /* !defined STRING_H */
  416. X
  417. X/*
  418. X** <time.h>
  419. X*/
  420. X
  421. X#ifdef TIME_H
  422. X#include TIME_H
  423. X#endif /* defined TIME_H */
  424. X
  425. X#ifndef TIME_H
  426. X#include "time.h"
  427. X#endif /* !defined TIME_H */
  428. X
  429. X/*
  430. X** ANSI inventions--float, limits, locale, stdarg, stddef, and stdlib.
  431. X** GCC 1.28 comes with stddef.h, but using it causes clashes if you
  432. X** also (directly or indirectly) include <sys/types.h>.  So we don't
  433. X** use it here.
  434. X*/
  435. X
  436. X#ifdef __STDC__
  437. X
  438. X#ifndef LIMITS_H
  439. X#define LIMITS_H    "limits.h"
  440. X#endif /* !defined LIMITS_H */
  441. X
  442. X#ifndef __GNUC__
  443. X
  444. X#ifndef STDARG_H
  445. X#define STDARG_H    "stdarg.h"
  446. X#endif /* !defined STDARG_H */
  447. X
  448. X#ifndef FLOAT_H
  449. X#define FLOAT_H        "float.h"
  450. X#endif /* !defined FLOAT_H */
  451. X
  452. X#ifndef LOCALE_H
  453. X#define LOCALE_H    "locale.h"
  454. X#endif /* !defined LOCALE_H */
  455. X
  456. X#ifndef STDDEF_H
  457. X#define STDDEF_H    "stddef.h"
  458. X#endif /* !defined STDDEF_H */
  459. X
  460. X#ifndef STDLIB_H
  461. X#define STDLIB_H    "stdlib.h"
  462. X#endif /* !defined STDLIB_H */
  463. X
  464. X#endif /* !defined __GNUC__ */
  465. X#endif /* defined __STDC__ */
  466. X
  467. X#ifdef FLOAT_H
  468. X#include FLOAT_H
  469. X#endif /* defined FLOAT_H */
  470. X
  471. X#ifdef LIMITS_H
  472. X#include LIMITS_H
  473. X#endif /* defined LIMITS_H */
  474. X
  475. X#ifndef CHAR_BIT
  476. X#define CHAR_BIT    8
  477. X#endif /* !defined CHAR_BIT */
  478. X
  479. X#ifndef USHRT_MAX
  480. X#define USHRT_MAX    ((unsigned short) ~0)
  481. X#endif /* !defined USHRT_MAX */
  482. X
  483. X#ifdef LOCALE_H
  484. X#include LOCALE_H
  485. X#endif /* defined LOCALE_H */
  486. X
  487. X#ifdef STDARG_H
  488. X#include STDARG_H
  489. X#endif /* defined STDARG_H */
  490. X
  491. X#ifdef STDDEF_H
  492. X#include STDDEF_H
  493. X#endif /* defined STDDEF_H */
  494. X
  495. X#ifdef STDLIB_H
  496. X#include STDLIB_H
  497. X#endif /* defined STDLIB_H */
  498. X
  499. X#ifndef STDLIB_H
  500. Xextern int    atoi P((
  501. X            const char * /*nptr*/
  502. X            ));
  503. Xextern char *    getenv P((
  504. X            const char * /*name*/
  505. X            ));
  506. Xextern char *    malloc P((
  507. X            unsigned /*size*/
  508. X            ));
  509. Xextern char *    calloc P((
  510. X            unsigned /*nelem*/,
  511. X            unsigned /*elsize*/
  512. X            ));
  513. Xextern char *    realloc P((
  514. X            void * /*pointer*/,
  515. X            unsigned /*size*/
  516. X            ));
  517. Xextern int    system P((
  518. X            const char * /*command*/
  519. X            ));
  520. Xextern int    abs P((
  521. X            int /*j*/
  522. X            ));
  523. X
  524. X#ifdef USG
  525. Xextern void    exit P((
  526. X            int /*status*/
  527. X            ));
  528. Xextern void    free P((
  529. X            void * /*pointer*/
  530. X            ));
  531. Xextern void    qsort P((
  532. X            void * /*base*/,
  533. X            unsigned /*nmemb*/,
  534. X            unsigned /*size*/,
  535. X            int (*/*compar*/)(
  536. X                const void * /*left*/,
  537. X                const void * /*right*/
  538. X                )
  539. X            ));
  540. X#endif /* defined USG */
  541. X#ifndef USG
  542. X#ifdef sun
  543. Xextern void    exit P((
  544. X            int /*status*/
  545. X            ));
  546. X#endif /* defined sun */
  547. X#ifndef sun
  548. Xextern int    exit P((
  549. X            int /*status*/
  550. X            ));
  551. X#endif /* !defined sun */
  552. Xextern int    free P((
  553. X            void * /*pointer*/
  554. X            ));
  555. Xextern int    qsort P((
  556. X            void * /*base*/,
  557. X            unsigned /*nmemb*/,
  558. X            unsigned /*size*/,
  559. X            int (*/*compar*/)(
  560. X                const void * /*left*/,
  561. X                const void * /*right*/
  562. X                )
  563. X            ));
  564. X#endif /* !defined USG */
  565. X#endif /* !defined STDLIB_H */
  566. X
  567. X#ifndef EXIT_FAILURE
  568. X#define EXIT_FAILURE    1
  569. X#endif /* !defined EXIT_FAILURE */
  570. X
  571. X#ifndef EXIT_SUCCESS
  572. X#define EXIT_SUCCESS    0
  573. X#endif /* !defined EXIT_SUCCESS */
  574. X
  575. X/*
  576. X** One last bit of business. . .
  577. X*/
  578. X
  579. X#ifndef isascii
  580. X#define isascii(a_r_g)    (((unsigned) (a_r_g)) <= 127)
  581. X#endif /* !defined isascii */
  582. X
  583. X#endif /* !defined ANSIC_H */
  584. END_OF_FILE
  585. if test 9305 -ne `wc -c <'ansic.h'`; then
  586.     echo shar: \"'ansic.h'\" unpacked with wrong size!
  587. fi
  588. # end of 'ansic.h'
  589. fi
  590. if test -f 'catsup.c' -a "${1}" != "-c" ; then 
  591.   echo shar: Will not clobber existing file \"'catsup.c'\"
  592. else
  593. echo shar: Extracting \"'catsup.c'\" \(15726 characters\)
  594. sed "s/^X//" >'catsup.c' <<'END_OF_FILE'
  595. X/*LINTLIBRARY*/
  596. X
  597. X#include "ansic.h"
  598. X#include "cat.h"
  599. X
  600. X#ifndef lint
  601. X#ifndef NOID
  602. Xstatic char    elsieid[] = "@(#)catsup.c    4.1";
  603. X#endif /* !defined NOID */
  604. X#endif /* !defined lint */
  605. X
  606. Xextern int    qsort();
  607. X
  608. X#if !defined TRUE
  609. X#define TRUE    1
  610. X#define FALSE    0
  611. X#endif /* !defined TRUE */
  612. X
  613. Xtypedef struct {
  614. X    int    c_special;
  615. X    int    c_tophalf;
  616. X    int    c_catcode;
  617. X    int    c_vfindex;
  618. X    int    c_ftindex;
  619. X    char    c_ntname[3];
  620. X} catinfo;
  621. X
  622. Xstatic catinfo    cattbl[] = {
  623. X    /*    SPECIAL    TOPHALF    CATCODE    VFINDEX    FTINDEX    NTNAME    */
  624. X    {    -1,    -1,    -1,    -1,    32,    " " },
  625. X    {    -1,    -1,    -1,    -1,    32,    "\\ " },
  626. X    {    FALSE,    TRUE,    37,    33,    33,    "!" },
  627. X    {    TRUE,    FALSE,    24,    34,    34,    "\"" },
  628. X    {    TRUE,    TRUE,    31,    35,    35,    "#" },
  629. X    {    FALSE,    TRUE,    45,    36,    36,    "$" },
  630. X    {    FALSE,    FALSE,    43,    37,    37,    "%" },
  631. X    {    FALSE,    FALSE,    40,    38,    38,    "&" },
  632. X    {    FALSE,    FALSE,    26,    39,    39,    "'" },
  633. X    {    TRUE,    TRUE,    28,    39,    146,    "\\'" },
  634. X    {    FALSE,    TRUE,    26,    40,    40,    "(" },
  635. X    {    FALSE,    TRUE,    27,    41,    41,    ")" },
  636. X    {    FALSE,    TRUE,    18,    42,    42,    "*" },
  637. X    {    TRUE,    TRUE,    39,    57,    228,    "**" },
  638. X    {    FALSE,    TRUE,    35,    43,    43,    "+" },
  639. X    {    FALSE,    FALSE,    39,    44,    44,    "," },
  640. X    {    FALSE,    FALSE,    32,    45,    45,    "-" },
  641. X    {    FALSE,    TRUE,    19,    4,    136,    "\\-" },
  642. X    {    TRUE,    TRUE,    21,    8,    205,    "+-" },
  643. X    {    TRUE,    FALSE,    28,    52,    199,    "<-" },
  644. X    {    FALSE,    FALSE,    36,    46,    46,    "." },
  645. X    {    FALSE,    FALSE,    35,    47,    47,    "/" },
  646. X    {    FALSE,    TRUE,    8,    48,    48,    "0" },
  647. X    {    FALSE,    TRUE,    9,    49,    49,    "1" },
  648. X    {    FALSE,    TRUE,    10,    50,    50,    "2" },
  649. X    {    FALSE,    FALSE,    30,    18,    134,    "12" },
  650. X    {    FALSE,    TRUE,    11,    51,    51,    "3" },
  651. X    {    FALSE,    TRUE,    12,    52,    52,    "4" },
  652. X    {    FALSE,    FALSE,    28,    17,    133,    "14" },
  653. X    {    FALSE,    FALSE,    38,    19,    135,    "34" },
  654. X    {    FALSE,    TRUE,    13,    53,    53,    "5" },
  655. X    {    FALSE,    TRUE,    14,    54,    54,    "6" },
  656. X    {    FALSE,    TRUE,    15,    55,    55,    "7" },
  657. X    {    FALSE,    TRUE,    16,    56,    56,    "8" },
  658. X    {    FALSE,    TRUE,    17,    57,    57,    "9" },
  659. X    {    FALSE,    TRUE,    34,    58,    58,    ":" },
  660. X    {    FALSE,    FALSE,    19,    59,    59,    ";" },
  661. X    {    TRUE,    TRUE,    3,    60,    60,    "<" },
  662. X    {    FALSE,    TRUE,    32,    61,    61,    "=" },
  663. X    {    TRUE,    FALSE,    63,    49,    195,    "~=" },
  664. X    {    TRUE,    TRUE,    22,    9,    192,    "<=" },
  665. X    {    TRUE,    TRUE,    25,    51,    197,    "!=" },
  666. X    {    TRUE,    TRUE,    24,    48,    193,    "==" },
  667. X    {    TRUE,    TRUE,    23,    10,    191,    ">=" },
  668. X    {    TRUE,    TRUE,    1,    62,    62,    ">" },
  669. X    {    TRUE,    TRUE,    44,    53,    198,    "->" },
  670. X    {    FALSE,    TRUE,    39,    63,    63,    "?" },
  671. X    {    TRUE,    FALSE,    18,    64,    64,    "@" },
  672. X    {    FALSE,    TRUE,    3,    65,    65,    "A" },
  673. X    {    FALSE,    TRUE,    3,    65,    65,    "*A" },
  674. X    {    FALSE,    FALSE,    61,    66,    66,    "B" },
  675. X    {    FALSE,    FALSE,    61,    66,    66,    "*B" },
  676. X    {    FALSE,    FALSE,    56,    67,    67,    "C" },
  677. X    {    TRUE,    TRUE,    2,    78,    180,    "*C" },
  678. X    {    FALSE,    FALSE,    60,    68,    68,    "D" },
  679. X    {    TRUE,    FALSE,    60,    68,    177,    "*D" },
  680. X    {    FALSE,    FALSE,    58,    69,    69,    "E" },
  681. X    {    FALSE,    FALSE,    58,    69,    69,    "*E" },
  682. X    {    FALSE,    TRUE,    1,    70,    70,    "F" },
  683. X    {    TRUE,    FALSE,    45,    85,    185,    "*F" },
  684. X    {    FALSE,    FALSE,    53,    71,    71,    "G" },
  685. X    {    TRUE,    FALSE,    53,    67,    176,    "*G" },
  686. X    {    FALSE,    FALSE,    48,    72,    72,    "H" },
  687. X    {    TRUE,    FALSE,    46,    72,    178,    "*H" },
  688. X    {    FALSE,    FALSE,    54,    73,    73,    "I" },
  689. X    {    FALSE,    FALSE,    54,    73,    73,    "*I" },
  690. X    {    FALSE,    TRUE,    5,    74,    74,    "J" },
  691. X    {    FALSE,    TRUE,    7,    75,    75,    "K" },
  692. X    {    FALSE,    TRUE,    7,    75,    75,    "*K" },
  693. X    {    FALSE,    FALSE,    51,    76,    76,    "L" },
  694. X    {    TRUE,    FALSE,    51,    75,    179,    "*L" },
  695. X    {    FALSE,    FALSE,    50,    77,    77,    "M" },
  696. X    {    FALSE,    FALSE,    50,    77,    77,    "*M" },
  697. X    {    FALSE,    FALSE,    49,    78,    78,    "N" },
  698. X    {    FALSE,    FALSE,    49,    78,    78,    "*N" },
  699. X    {    FALSE,    FALSE,    47,    79,    79,    "O" },
  700. X    {    FALSE,    FALSE,    47,    79,    79,    "*O" },
  701. X    {    FALSE,    FALSE,    55,    80,    80,    "P" },
  702. X    {    TRUE,    FALSE,    55,    80,    181,    "*P" },
  703. X    {    FALSE,    FALSE,    45,    81,    81,    "Q" },
  704. X    {    TRUE,    FALSE,    34,    87,    186,    "*Q" },
  705. X    {    FALSE,    FALSE,    52,    82,    82,    "R" },
  706. X    {    FALSE,    FALSE,    55,    80,    80,    "*R" },
  707. X    {    FALSE,    FALSE,    62,    83,    83,    "S" },
  708. X    {    TRUE,    FALSE,    62,    82,    182,    "*S" },
  709. X    {    FALSE,    FALSE,    46,    84,    84,    "T" },
  710. X    {    FALSE,    FALSE,    46,    84,    84,    "*T" },
  711. X    {    FALSE,    TRUE,    6,    85,    85,    "U" },
  712. X    {    TRUE,    TRUE,    6,    84,    184,    "*U" },
  713. X    {    FALSE,    FALSE,    57,    86,    86,    "V" },
  714. X    {    FALSE,    TRUE,    4,    87,    87,    "W" },
  715. X    {    TRUE,    FALSE,    47,    88,    187,    "*W" },
  716. X    {    FALSE,    TRUE,    2,    88,    88,    "X" },
  717. X    {    FALSE,    TRUE,    2,    88,    88,    "*X" },
  718. X    {    FALSE,    FALSE,    63,    89,    89,    "Y" },
  719. X    {    FALSE,    FALSE,    48,    72,    72,    "*Y" },
  720. X    {    FALSE,    FALSE,    59,    90,    90,    "Z" },
  721. X    {    FALSE,    FALSE,    59,    90,    90,    "*Z" },
  722. X    {    FALSE,    TRUE,    28,    91,    91,    "[" },
  723. X    {    TRUE,    FALSE,    33,    92,    92,    "\\" },
  724. X    {    FALSE,    TRUE,    29,    93,    93,    "]" },
  725. X    {    TRUE,    TRUE,    30,    94,    94,    "^" },
  726. X    {    -1,    -1,    -1,    -1,    150,    "\\^" },
  727. X    {    TRUE,    FALSE,    32,    95,    95,    "_" },
  728. X    {    FALSE,    FALSE,    24,    96,    96,    "`" },
  729. X    {    TRUE,    TRUE,    29,    96,    147,    "\\`" },
  730. X    {    FALSE,    FALSE,    21,    97,    97,    "a" },
  731. X    {    TRUE,    FALSE,    19,    55,    201,    "da" },
  732. X    {    TRUE,    TRUE,    5,    28,    207,    "ca" },
  733. X    {    TRUE,    FALSE,    21,    97,    152,    "*a" },
  734. X    {    TRUE,    TRUE,    28,    39,    146,    "aa" },
  735. X    {    TRUE,    FALSE,    30,    54,    200,    "ua" },
  736. X    {    TRUE,    TRUE,    29,    96,    147,    "ga" },
  737. X    {    FALSE,    FALSE,    10,    98,    98,    "b" },
  738. X    {    TRUE,    TRUE,    15,    23,    235,    "rb" },
  739. X    {    TRUE,    TRUE,    40,    91,    210,    "ib" },
  740. X    {    TRUE,    TRUE,    12,    21,    233,    "lb" },
  741. X    {    TRUE,    FALSE,    10,    98,    153,    "*b" },
  742. X    {    TRUE,    FALSE,    56,    26,    208,    "sb" },
  743. X    {    FALSE,    FALSE,    23,    99,    99,    "c" },
  744. X    {    TRUE,    TRUE,    8,    19,    242,    "rc" },
  745. X    {    TRUE,    TRUE,    45,    56,    144,    "sc" },
  746. X    {    TRUE,    TRUE,    18,    18,    241,    "lc" },
  747. X    {    TRUE,    FALSE,    11,    110,    165,    "*c" },
  748. X    {    FALSE,    FALSE,    9,    100,    100,    "d" },
  749. X    {    TRUE,    FALSE,    59,    121,    213,    "pd" },
  750. X    {    TRUE,    FALSE,    9,    100,    155,    "*d" },
  751. X    {    TRUE,    TRUE,    37,    89,    225,    "dd" },
  752. X    {    FALSE,    FALSE,    25,    101,    101,    "e" },
  753. X    {    TRUE,    FALSE,    25,    101,    156,    "*e" },
  754. X    {    FALSE,    TRUE,    30,    11,    142,    "de" },
  755. X    {    FALSE,    FALSE,    12,    102,    102,    "f" },
  756. X    {    TRUE,    TRUE,    17,    16,    239,    "lf" },
  757. X    {    TRUE,    TRUE,    16,    17,    240,    "rf" },
  758. X    {    TRUE,    FALSE,    13,    117,    172,    "*f" },
  759. X    {    FALSE,    TRUE,    22,    3,    139,    "ff" },
  760. X    {    TRUE,    FALSE,    36,    1,    212,    "if" },
  761. X    {    FALSE,    FALSE,    37,    103,    103,    "g" },
  762. X    {    TRUE,    FALSE,    37,    99,    154,    "*g" },
  763. X    {    FALSE,    TRUE,    31,    12,    143,    "dg" },
  764. X    {    FALSE,    TRUE,    33,    15,    221,    "rg" },
  765. X    {    FALSE,    FALSE,    1,    104,    104,    "h" },
  766. X    {    TRUE,    FALSE,    2,    104,    159,    "*h" },
  767. X    {    TRUE,    FALSE,    40,    4,    226,    "rh" },
  768. X    {    TRUE,    TRUE,    32,    30,    227,    "lh" },
  769. X    {    FALSE,    FALSE,    6,    105,    105,    "i" },
  770. X    {    TRUE,    FALSE,    6,    105,    160,    "*i" },
  771. X    {    TRUE,    FALSE,    52,    45,    194,    "mi" },
  772. X    {    FALSE,    TRUE,    25,    9,    140,    "Fi" },
  773. X    {    FALSE,    TRUE,    20,    1,    137,    "fi" },
  774. X    {    TRUE,    TRUE,    20,    47,    204,    "di" },
  775. X    {    TRUE,    TRUE,    41,    93,    231,    "ci" },
  776. X    {    FALSE,    FALSE,    13,    106,    106,    "j" },
  777. X    {    FALSE,    FALSE,    15,    107,    107,    "k" },
  778. X    {    TRUE,    FALSE,    15,    106,    161,    "*k" },
  779. X    {    TRUE,    TRUE,    14,    25,    237,    "rk" },
  780. X    {    TRUE,    TRUE,    11,    24,    236,    "lk" },
  781. X    {    FALSE,    FALSE,    5,    108,    108,    "l" },
  782. X    {    FALSE,    TRUE,    24,    10,    141,    "Fl" },
  783. X    {    FALSE,    TRUE,    21,    2,    138,    "fl" },
  784. X    {    TRUE,    TRUE,    4,    14,    149,    "sl" },
  785. X    {    TRUE,    FALSE,    5,    107,    162,    "*l" },
  786. X    {    TRUE,    TRUE,    43,    43,    220,    "pl" },
  787. X    {    TRUE,    FALSE,    32,    95,    148,    "ul" },
  788. X    {    FALSE,    FALSE,    4,    109,    109,    "m" },
  789. X    {    FALSE,    TRUE,    40,    13,    145,    "fm" },
  790. X    {    TRUE,    FALSE,    4,    108,    163,    "*m" },
  791. X    {    FALSE,    FALSE,    18,    6,    131,    "em" },
  792. X    {    FALSE,    FALSE,    3,    110,    110,    "n" },
  793. X    {    TRUE,    FALSE,    49,    6,    190,    "rn" },
  794. X    {    TRUE,    FALSE,    3,    109,    164,    "*n" },
  795. X    {    FALSE,    FALSE,    27,    111,    111,    "o" },
  796. X    {    FALSE,    TRUE,    43,    14,    222,    "co" },
  797. X    {    TRUE,    TRUE,    7,    29,    215,    "no" },
  798. X    {    TRUE,    TRUE,    33,    31,    219,    "mo" },
  799. X    {    TRUE,    FALSE,    27,    111,    166,    "*o" },
  800. X    {    FALSE,    FALSE,    17,    112,    112,    "p" },
  801. X    {    TRUE,    FALSE,    17,    112,    167,    "*p" },
  802. X    {    TRUE,    FALSE,    38,    2,    211,    "ip" },
  803. X    {    TRUE,    FALSE,    57,    27,    209,    "sp" },
  804. X    {    TRUE,    FALSE,    58,    50,    196,    "ap" },
  805. X    {    FALSE,    FALSE,    34,    113,    113,    "q" },
  806. X    {    TRUE,    FALSE,    1,    119,    174,    "*q" },
  807. X    {    TRUE,    FALSE,    26,    61,    202,    "eq" },
  808. X    {    FALSE,    TRUE,    44,    8,    130,    "sq" },
  809. X    {    FALSE,    FALSE,    29,    114,    114,    "r" },
  810. X    {    TRUE,    FALSE,    43,    40,    214,    "gr" },
  811. X    {    TRUE,    FALSE,    61,    11,    188,    "sr" },
  812. X    {    TRUE,    FALSE,    22,    124,    230,    "or" },
  813. X    {    TRUE,    FALSE,    29,    113,    168,    "*r" },
  814. X    {    TRUE,    TRUE,    38,    90,    223,    "br" },
  815. X    {    FALSE,    FALSE,    8,    115,    115,    "s" },
  816. X    {    TRUE,    FALSE,    8,    114,    169,    "*s" },
  817. X    {    TRUE,    FALSE,    54,    13,    216,    "is" },
  818. X    {    TRUE,    FALSE,    50,    12,    189,    "ts" },
  819. X    {    TRUE,    FALSE,    35,    7,    229,    "bs" },
  820. X    {    TRUE,    TRUE,    35,    122,    218,    "es" },
  821. X    {    FALSE,    FALSE,    2,    116,    116,    "t" },
  822. X    {    TRUE,    TRUE,    13,    22,    234,    "rt" },
  823. X    {    FALSE,    TRUE,    23,    16,    224,    "ct" },
  824. X    {    TRUE,    TRUE,    9,    20,    232,    "lt" },
  825. X    {    TRUE,    FALSE,    31,    115,    170,    "*t" },
  826. X    {    TRUE,    FALSE,    39,    3,    217,    "pt" },
  827. X    {    FALSE,    FALSE,    14,    117,    117,    "u" },
  828. X    {    TRUE,    FALSE,    48,    5,    206,    "cu" },
  829. X    {    FALSE,    TRUE,    38,    7,    129,    "bu" },
  830. X    {    TRUE,    TRUE,    19,    42,    203,    "mu" },
  831. X    {    FALSE,    FALSE,    22,    5,    132,    "ru" },
  832. X    {    TRUE,    FALSE,    14,    116,    171,    "*u" },
  833. X    {    FALSE,    FALSE,    31,    118,    118,    "v" },
  834. X    {    TRUE,    TRUE,    10,    15,    238,    "bv" },
  835. X    {    FALSE,    FALSE,    33,    119,    119,    "w" },
  836. X    {    TRUE,    FALSE,    41,    120,    175,    "*w" },
  837. X    {    FALSE,    FALSE,    11,    120,    120,    "x" },
  838. X    {    TRUE,    FALSE,    23,    118,    173,    "*x" },
  839. X    {    FALSE,    FALSE,    41,    121,    121,    "y" },
  840. X    {    FALSE,    FALSE,    32,    45,    128,    "hy" },
  841. X    {    TRUE,    FALSE,    12,    103,    158,    "*y" },
  842. X    {    FALSE,    FALSE,    7,    122,    122,    "z" },
  843. X    {    TRUE,    FALSE,    7,    102,    157,    "*z" },
  844. X    {    TRUE,    TRUE,    26,    123,    123,    "{" },
  845. X    {    FALSE,    TRUE,    41,    124,    124,    "|" },
  846. X    {    -1,    -1,    -1,    -1,    127,    "\\|" },
  847. X    {    TRUE,    TRUE,    27,    125,    125,    "}" },
  848. X    {    TRUE,    TRUE,    34,    126,    126,    "~" },
  849. X    {    -1,    -1,    -1,    -1,    0,    "" }
  850. X};
  851. X
  852. X#if !defined NVPC
  853. X#define NVPC    256        /* Number of Values Per Character */
  854. X#endif /* !defined NVPC */
  855. X
  856. Xstatic const catinfo *    code2cip[2][2][CAT_MAX_FLASH + 1];
  857. Xstatic const catinfo *    char2cip[NVPC];
  858. Xstatic int        didinit;
  859. X
  860. Xstatic void
  861. Xtblinit()
  862. X{
  863. X    const catinfo *        acip;
  864. X    const catinfo *        bcip;
  865. X    int            i;
  866. X    int            c;
  867. X
  868. X    if (didinit)
  869. X        return;
  870. X    for (acip = cattbl; acip->c_ntname[0] != '\0'; ++acip) {
  871. X        if ((c = acip->c_ntname[1]) == '\0')
  872. X            c = acip->c_ntname[0];
  873. X        if (char2cip[(unsigned char) c] == NULL)
  874. X            char2cip[(unsigned char) c] = acip;
  875. X        if (acip->c_catcode <= 0)
  876. X            continue;
  877. X        bcip = code2cip[acip->c_special]
  878. X            [acip->c_tophalf]
  879. X            [acip->c_catcode];
  880. X        if (bcip != NULL && (bcip->c_ntname[1] == '\0' ||
  881. X            (acip->c_ntname[1] != '\0' &&
  882. X            acip->c_ntname[1] == '\\')))
  883. X                continue;
  884. X        code2cip[acip->c_special]
  885. X            [acip->c_tophalf]
  886. X            [acip->c_catcode] = acip;
  887. X    }
  888. X    for (i = 0; i < NVPC; ++i)
  889. X        if (char2cip[i] == NULL)
  890. X            char2cip[i] = acip;
  891. X    didinit = TRUE;
  892. X}
  893. X
  894. Xstatic const catinfo *
  895. Xntn2cip(name)
  896. Xchar *    name;
  897. X{
  898. X    const catinfo *    cip;
  899. X    int        c;
  900. X
  901. X    if (!didinit)
  902. X        tblinit();
  903. X    if (name == NULL)
  904. X        return NULL;
  905. X    if (name[1] == '\0')
  906. X        return char2cip[(unsigned char) name[0]];
  907. X    if (name[0] == '\\' && name[1] == '(')
  908. X        name += 2;
  909. X    if (name[0] == '\0')
  910. X        return NULL;
  911. X    if ((c = name[1]) == '\0')
  912. X        c = name[0];
  913. X    else if (name[2] != '\0')
  914. X        return NULL;
  915. X    cip = char2cip[(unsigned char) c];
  916. X    while (cip->c_ntname[0] != '\0')
  917. X        if (cip->c_ntname[0] == name[0] &&
  918. X            cip->c_ntname[1] == name[1])
  919. X                return cip;
  920. X        else    ++cip;
  921. X    return NULL;
  922. X}
  923. X
  924. Xint
  925. Xntn2vfi(name)
  926. Xchar * const    name;
  927. X{
  928. X    const catinfo *    cip;
  929. X
  930. X    return ((cip = ntn2cip(name)) == NULL) ? -1 : cip->c_vfindex;
  931. X}
  932. X
  933. Xint
  934. Xntn2fti(name)
  935. Xchar * const    name;
  936. X{
  937. X    const catinfo *    cip;
  938. X
  939. X    return ((cip = ntn2cip(name)) == NULL) ? -1 : cip->c_ftindex;
  940. X}
  941. X
  942. Xconst char *
  943. Xfti2ntn(fti)
  944. Xint const    fti;
  945. X{
  946. X    catinfo *    cip;
  947. X
  948. X    for (cip = cattbl; ; ++cip)
  949. X        if (cip->c_ntname[0] == '\0')
  950. X            return NULL;
  951. X        else if (cip->c_ftindex == fti)
  952. X            return cip->c_ntname;
  953. X}
  954. X
  955. Xint
  956. Xntnons(name)
  957. Xchar * const    name;
  958. X{
  959. X    const catinfo *    cip;
  960. X
  961. X    return ((cip = ntn2cip(name)) == NULL) ? -1 : cip->c_special;
  962. X}
  963. X
  964. Xint
  965. Xntnonr(name)
  966. Xchar * const    name;
  967. X{
  968. X    const catinfo *    cip;
  969. X
  970. X    return ((cip = ntn2cip(name)) == NULL) ? -1 : !cip->c_special;
  971. X}
  972. X
  973. X/*
  974. X** Now here's something we hope you'll really like. . .
  975. X*/
  976. X
  977. Xextern char *    malloc();
  978. Xextern char *    realloc();
  979. X
  980. Xstatic int    curfont = 0;        /* current font */
  981. Xstatic long    horizontal = -16;    /* horizontal position */
  982. Xstatic long    vertical = 0    ;    /* vertical position */
  983. Xstatic int    escape_forward = TRUE;    /* should escape forward */
  984. Xstatic int    lead_forward = TRUE;    /* should lead forward */
  985. Xstatic int    tophalf = FALSE;    /* TRUE if top half of font is wanted */
  986. Xstatic int    true_point_size = 10;
  987. X
  988. Xstatic void
  989. Xcatinit()
  990. X{
  991. X    escape_forward = TRUE;
  992. X    lead_forward = TRUE;
  993. X    tophalf = FALSE;
  994. X    curfont = 0;
  995. X    true_point_size = 10;    /* troff default */
  996. X    horizontal = -16;
  997. X}
  998. X
  999. Xtypedef struct {
  1000. X    long    horizontal;
  1001. X    long    vertical;
  1002. X    char    size;
  1003. X    char    fontname[3];
  1004. X    char    charname[3];
  1005. X} memory;
  1006. X
  1007. Xstatic int
  1008. Xmcomp(avp, bvp)
  1009. Xvoid * const    avp;
  1010. Xvoid * const    bvp;
  1011. X{
  1012. X    const memory * const    amp = (const memory *) avp;
  1013. X    const memory * const    bmp = (const memory *) bvp;
  1014. X    long            diff = amp->horizontal - bmp->horizontal;
  1015. X
  1016. X    if (diff == 0) {
  1017. X        diff = amp->size - bmp->size;
  1018. X        if (diff == 0)
  1019. X            return 0;
  1020. X    }
  1021. X    return (diff > 0) ? 1 : -1;
  1022. X}
  1023. X
  1024. Xstatic char     fontnicks[8][3] = {
  1025. X    "R",
  1026. X    "",
  1027. X    "I",
  1028. X    "",
  1029. X    "B",
  1030. X    "",
  1031. X    "S",
  1032. X    "",
  1033. X};
  1034. X
  1035. Xstatic int
  1036. Xdoflash(catcode, outp, dosort)
  1037. Xint const    catcode;
  1038. Xint (* const    outp)();
  1039. Xint const    dosort;
  1040. X{
  1041. X    const catinfo *    cip;
  1042. X    memory *    mp;
  1043. X    static memory *    memories;
  1044. X    static int    memused;
  1045. X    static int    memavail;
  1046. X    static memory    zm;
  1047. X
  1048. X    if (fontnicks[curfont][0] == 'S' && fontnicks[curfont][1] == '\0')
  1049. X        cip = code2cip[TRUE][tophalf][catcode];
  1050. X    else    cip = code2cip[FALSE][tophalf][catcode];
  1051. X    if (!dosort)
  1052. X        if (catcode <= 0)
  1053. X            return 0;
  1054. X        else    return ((*outp)(cip->c_ntname, horizontal, vertical,
  1055. X                true_point_size, fontnicks[curfont]) == 0) ?
  1056. X                    0 : -1;
  1057. X    /*
  1058. X    ** Flush if appropriate.
  1059. X    */
  1060. X    if (memused > 0 && (catcode <= 0 || vertical != memories[0].vertical)) {
  1061. X        int    i;
  1062. X
  1063. X        (void) qsort((char *) memories, memused,
  1064. X            sizeof *memories, mcomp);
  1065. X        for (i = 0; i < memused; ++i) {
  1066. X            mp = &memories[i];
  1067. X            if ((*outp)(mp->charname,
  1068. X                mp->horizontal, mp->vertical,
  1069. X                mp->size, mp->fontname) != 0)
  1070. X                    return -1;
  1071. X        }
  1072. X        memused = 0;
  1073. X    }
  1074. X    /*
  1075. X    ** Remember if appropriate.
  1076. X    */
  1077. X    if (catcode <= 0)
  1078. X        return 0;
  1079. X    if (memused >= memavail) {
  1080. X        if (memavail++ == 0)
  1081. X            memories = (memory *) malloc(sizeof *memories);
  1082. X        else    memories = (memory *) realloc((char *) memories,
  1083. X                (unsigned) (memavail * sizeof *memories));
  1084. X        if (memories == NULL) {
  1085. X            memavail = 0;
  1086. X            return -1;
  1087. X        }
  1088. X        memories[memused] = zm;
  1089. X    }
  1090. X    mp = &memories[memused];
  1091. X    mp->horizontal = horizontal;
  1092. X    mp->vertical = vertical;
  1093. X    mp->size = true_point_size;
  1094. X    mp->fontname[0] = fontnicks[curfont][0];
  1095. X    mp->fontname[1] = fontnicks[curfont][1];
  1096. X    mp->charname[0] = cip->c_ntname[0];
  1097. X    mp->charname[1] = cip->c_ntname[1];
  1098. X    ++memused;
  1099. X    return 0;
  1100. X}
  1101. X
  1102. Xint
  1103. Xcatsup(inp, outp, dosort, skipinit)
  1104. Xint (* const    inp)();
  1105. Xint (* const    outp)();
  1106. Xint const    dosort;
  1107. Xint const    skipinit;
  1108. X{
  1109. X    int    c;
  1110. X    int    i;
  1111. X
  1112. X    if (inp == NULL || outp == NULL ||
  1113. X        (dosort != TRUE && dosort != FALSE) ||
  1114. X        (skipinit != TRUE && skipinit != FALSE))
  1115. X            return -1;
  1116. X    if (!skipinit) {
  1117. X        catinit();
  1118. X        vertical = 0;
  1119. X    }
  1120. X    tblinit();
  1121. X    while ((c = (*inp)()) >= 0) {
  1122. X        if (CAT_IS_FLASH(c)) {
  1123. X            if (doflash(c, outp, dosort) != 0)
  1124. X                return -1;
  1125. X        } else if (CAT_IS_ESCAPE(c)) {
  1126. X            i = CAT_ESCAPE(c);
  1127. X            if (escape_forward)
  1128. X                horizontal += i;
  1129. X            else {
  1130. X                horizontal -= i;
  1131. X                if (horizontal < 0)
  1132. X                    horizontal = 0;
  1133. X            }
  1134. X        } else if (CAT_IS_LEADING(c)) {
  1135. X            i = CAT_LEAD(c);
  1136. X            if (lead_forward)
  1137. X                vertical += i;
  1138. X            else    vertical -= i;
  1139. X        } else if (CAT_IS_SIZE_CHANGE(c)) {
  1140. X            i = CAT_SIZE_CHANGE(c);
  1141. X            if (CAT_IS_DOUBLE_TO_SINGLE(true_point_size, i))
  1142. X                horizontal += CAT_LENSE_COMPENSATION;
  1143. X            else if (CAT_IS_SINGLE_TO_DOUBLE(true_point_size, i)) {
  1144. X                horizontal -= CAT_LENSE_COMPENSATION;
  1145. X                if (horizontal < 0)
  1146. X                    horizontal = 0;
  1147. X            }
  1148. X            true_point_size = i;
  1149. X        } else switch (c) {
  1150. X            case CAT_INITIALIZE:
  1151. X                catinit();
  1152. X                break;
  1153. X            case CAT_UPPER_RAIL:
  1154. X                curfont |= CAT_RAIL;
  1155. X                break;
  1156. X            case CAT_LOWER_RAIL:
  1157. X                curfont &= ~CAT_RAIL;
  1158. X                break;
  1159. X            case CAT_UPPER_MAGAZINE:
  1160. X                curfont |= CAT_MAGAZINE;
  1161. X                break;
  1162. X            case CAT_LOWER_MAGAZINE:
  1163. X                curfont &= ~CAT_MAGAZINE;
  1164. X                break;
  1165. X            case CAT_TILT_UP:
  1166. X                curfont |= CAT_TILT;
  1167. X                break;
  1168. X            case CAT_TILT_DOWN:
  1169. X                curfont &= ~CAT_TILT;
  1170. X                break;
  1171. X            case CAT_UPPER_FONT:
  1172. X                tophalf = TRUE;
  1173. X                break;
  1174. X            case CAT_LOWER_FONT:
  1175. X                tophalf = FALSE;
  1176. X                break;
  1177. X            case CAT_ESCAPE_FORWARD:
  1178. X                escape_forward = TRUE;
  1179. X                break;
  1180. X            case CAT_ESCAPE_BACKWARD:
  1181. X                escape_forward = FALSE;
  1182. X                break;
  1183. X            case CAT_LEAD_FORWARD:
  1184. X                lead_forward = TRUE;
  1185. X                break;
  1186. X            case CAT_LEAD_BACKWARD:
  1187. X                lead_forward = FALSE;
  1188. X                break;
  1189. X            case CAT_STOP:
  1190. X                break;    /* ? */
  1191. X            default:
  1192. X                return -1;
  1193. X        }
  1194. X    }
  1195. X    if (doflash(0, outp, dosort) != 0)
  1196. X        return -1;
  1197. X    return 0;
  1198. X}
  1199. END_OF_FILE
  1200. if test 15726 -ne `wc -c <'catsup.c'`; then
  1201.     echo shar: \"'catsup.c'\" unpacked with wrong size!
  1202. fi
  1203. # end of 'catsup.c'
  1204. fi
  1205. if test -f 'testfile' -a "${1}" != "-c" ; then 
  1206.   echo shar: Will not clobber existing file \"'testfile'\"
  1207. else
  1208. echo shar: Extracting \"'testfile'\" \(10005 characters\)
  1209. sed "s/^X//" >'testfile' <<'END_OF_FILE'
  1210. X'\" @(#)testfile    4.1
  1211. X'\" Troff test data
  1212. X.po 0
  1213. X.ll 8i
  1214. X.de 1i
  1215. X.sp 1i
  1216. X..
  1217. X.wh -1i 1i
  1218. X.wh 0 1i
  1219. X.nf
  1220. XSpecial characters in NROFF/TROFF User's Manual Table II order
  1221. X.ta .7i +.7i +.7i +.7i
  1222. XRoman    \fIItalic\fP    \fBBold\fP    Input    Character
  1223. XChar    \fIChar\fP    \fBChar\fP    Name     Name
  1224. X\&'    \fI'\fP    \fB'\fP    '    close quote
  1225. X`    \fI`\fP    \fB`\fP    `    open quote
  1226. X\(em    \fI\(em\fP    \fB\(em\fP    \e(em    3/4 Em dash
  1227. X\(hy    \fI\(hy\fP    \fB\(hy\fP    \e(hy    hyphen or
  1228. X-    \fI-\fP    \fB-\fP    -    hyphen
  1229. X\-    \fI\-\fP    \fB\-\fP    \e-    current font minus
  1230. X\(bu    \fI\(bu\fP    \fB\(bu\fP    \e(bu    bullet
  1231. X\(sq    \fI\(sq\fP    \fB\(sq\fP    \e(sq    square
  1232. X\(ru    \fI\(ru\fP    \fB\(ru\fP    \e(ru    rule
  1233. X\(14    \fI\(14\fP    \fB\(14\fP    \e(14    1/4
  1234. X\(12    \fI\(12\fP    \fB\(12\fP    \e(12    1/2
  1235. X\(34    \fI\(34\fP    \fB\(34\fP    \e(34    3/4
  1236. X\(fi    \fI\(fi\fP    \fB\(fi\fP    \e(fi    fi (ligature)
  1237. X\(fl    \fI\(fl\fP    \fB\(fl\fP    \e(fl    fl (ligature)
  1238. X\(ff    \fI\(ff\fP    \fB\(ff\fP    \e(ff    ff (ligature)
  1239. X\(Fi    \fI\(Fi\fP    \fB\(Fi\fP    \e(Fi    ffi (ligature)
  1240. X\(Fl    \fI\(Fl\fP    \fB\(Fl\fP    \e(Fl    ffl (ligature)
  1241. X\(de    \fI\(de\fP    \fB\(de\fP    \e(de    degree
  1242. X\(dg    \fI\(dg\fP    \fB\(dg\fP    \e(dg    dagger
  1243. X\(fm    \fI\(fm\fP    \fB\(fm\fP    \e(fm    foot mark
  1244. X\(ct    \fI\(ct\fP    \fB\(ct\fP    \e(ct    cent sign
  1245. X\(rg    \fI\(rg\fP    \fB\(rg\fP    \e(rg    registered
  1246. X\(co    \fI\(co\fP    \fB\(co\fP    \e(co    copyright
  1247. X\(pl    \fI\(pl\fP    \fB\(pl\fP    \e(pl    math plus
  1248. X\(mi    \fI\(mi\fP    \fB\(mi\fP    \e(mi    math minus
  1249. X\(eq    \fI\(eq\fP    \fB\(eq\fP    \e(eq    math equal
  1250. X\(**    \fI\(**\fP    \fB\(**\fP    \e(**    math star
  1251. X\(sc    \fI\(sc\fP    \fB\(sc\fP    \e(sc    section
  1252. X\(aa    \fI\(aa\fP    \fB\(aa\fP    \e(aa    acute accent
  1253. X\(ga    \fI\(ga\fP    \fB\(ga\fP    \e(ga    grave accent
  1254. X\(ul    \fI\(ul\fP    \fB\(ul\fP    \e(ul    underrule
  1255. X\(sl    \fI\(sl\fP    \fB\(sl\fP    \e(sl    slash (matching backslash)
  1256. X\(*a    \fI\(*a\fP    \fB\(*a\fP    \e(*a    alpha
  1257. X\(*b    \fI\(*b\fP    \fB\(*b\fP    \e(*b    beta
  1258. X\(*g    \fI\(*g\fP    \fB\(*g\fP    \e(*g    gamma
  1259. X\(*d    \fI\(*d\fP    \fB\(*d\fP    \e(*d    delta
  1260. X\(*e    \fI\(*e\fP    \fB\(*e\fP    \e(*e    epsilon
  1261. X\(*z    \fI\(*z\fP    \fB\(*z\fP    \e(*z    zeta
  1262. X\(*y    \fI\(*y\fP    \fB\(*y\fP    \e(*y    eta
  1263. X\(*h    \fI\(*h\fP    \fB\(*h\fP    \e(*h    theta
  1264. X\(*i    \fI\(*i\fP    \fB\(*i\fP    \e(*i    iota
  1265. X\(*k    \fI\(*k\fP    \fB\(*k\fP    \e(*k    kappa
  1266. X\(*l    \fI\(*l\fP    \fB\(*l\fP    \e(*l    lambda
  1267. X\(*m    \fI\(*m\fP    \fB\(*m\fP    \e(*m    mu
  1268. X\(*n    \fI\(*n\fP    \fB\(*n\fP    \e(*n    nu
  1269. X\(*c    \fI\(*c\fP    \fB\(*c\fP    \e(*c    xi
  1270. X\(*o    \fI\(*o\fP    \fB\(*o\fP    \e(*o    omicron
  1271. X\(*p    \fI\(*p\fP    \fB\(*p\fP    \e(*p    pi
  1272. X\(*r    \fI\(*r\fP    \fB\(*r\fP    \e(*r    rho
  1273. X\(*s    \fI\(*s\fP    \fB\(*s\fP    \e(*s    sigma
  1274. X\(ts    \fI\(ts\fP    \fB\(ts\fP    \e(ts    terminal sigma
  1275. X\(*t    \fI\(*t\fP    \fB\(*t\fP    \e(*t    tau
  1276. X\(*u    \fI\(*u\fP    \fB\(*u\fP    \e(*u    upsilon
  1277. X\(*f    \fI\(*f\fP    \fB\(*f\fP    \e(*f    phi
  1278. X\(*x    \fI\(*x\fP    \fB\(*x\fP    \e(*x    chi
  1279. X\(*q    \fI\(*q\fP    \fB\(*q\fP    \e(*q    psi
  1280. X\(*w    \fI\(*w\fP    \fB\(*w\fP    \e(*w    omega
  1281. X\(*A    \fI\(*A\fP    \fB\(*A\fP    \e(*A    Alpha
  1282. X\(*B    \fI\(*B\fP    \fB\(*B\fP    \e(*B    Beta
  1283. X\(*G    \fI\(*G\fP    \fB\(*G\fP    \e(*G    Gamma
  1284. X\(*D    \fI\(*D\fP    \fB\(*D\fP    \e(*D    Delta
  1285. X\(*E    \fI\(*E\fP    \fB\(*E\fP    \e(*E    Epsilon
  1286. X\(*Z    \fI\(*Z\fP    \fB\(*Z\fP    \e(*Z    Zeta
  1287. X\(*Y    \fI\(*Y\fP    \fB\(*Y\fP    \e(*Y    Eta
  1288. X\(*H    \fI\(*H\fP    \fB\(*H\fP    \e(*H    Theta
  1289. X\(*I    \fI\(*I\fP    \fB\(*I\fP    \e(*I    Iota
  1290. X\(*K    \fI\(*K\fP    \fB\(*K\fP    \e(*K    Kappa
  1291. X\(*L    \fI\(*L\fP    \fB\(*L\fP    \e(*L    Lambda
  1292. X\(*M    \fI\(*M\fP    \fB\(*M\fP    \e(*M    Mu
  1293. X\(*N    \fI\(*N\fP    \fB\(*N\fP    \e(*N    Nu
  1294. X\(*C    \fI\(*C\fP    \fB\(*C\fP    \e(*C    Xi
  1295. X\(*O    \fI\(*O\fP    \fB\(*O\fP    \e(*O    Omicron
  1296. X\(*P    \fI\(*P\fP    \fB\(*P\fP    \e(*P    Pi
  1297. X\(*R    \fI\(*R\fP    \fB\(*R\fP    \e(*R    Rho
  1298. X\(*S    \fI\(*S\fP    \fB\(*S\fP    \e(*S    Sigma
  1299. X\(*T    \fI\(*T\fP    \fB\(*T\fP    \e(*T    Tau
  1300. X\(*U    \fI\(*U\fP    \fB\(*U\fP    \e(*U    Upsilon
  1301. X\(*F    \fI\(*F\fP    \fB\(*F\fP    \e(*F    Phi
  1302. X\(*X    \fI\(*X\fP    \fB\(*X\fP    \e(*X    Chi
  1303. X\(*Q    \fI\(*Q\fP    \fB\(*Q\fP    \e(*Q    Psi
  1304. X\(*W    \fI\(*W\fP    \fB\(*W\fP    \e(*W    Omega
  1305. X\(sr    \fI\(sr\fP    \fB\(sr\fP    \e(sr    square root
  1306. X\(rn    \fI\(rn\fP    \fB\(rn\fP    \e(rn    root en extender (over line)
  1307. X\(>=    \fI\(>=\fP    \fB\(>=\fP    \e(>=    >=
  1308. X\(<=    \fI\(<=\fP    \fB\(<=\fP    \e(<=    <=
  1309. X\(==    \fI\(==\fP    \fB\(==\fP    \e(==    identically equal
  1310. X\(~=    \fI\(~=\fP    \fB\(~=\fP    \e(~=    approx =
  1311. X\(ap    \fI\(ap\fP    \fB\(ap\fP    \e(ap    approximates
  1312. X\(!=    \fI\(!=\fP    \fB\(!=\fP    \e(!=    not equal
  1313. X\(->    \fI\(->\fP    \fB\(->\fP    \e(->    right arrow
  1314. X\(<-    \fI\(<-\fP    \fB\(<-\fP    \e(<-    left arrow
  1315. X\(ua    \fI\(ua\fP    \fB\(ua\fP    \e(ua    up arrow
  1316. X\(da    \fI\(da\fP    \fB\(da\fP    \e(da    down arrow
  1317. X\(mu    \fI\(mu\fP    \fB\(mu\fP    \e(mu    multiply
  1318. X\(di    \fI\(di\fP    \fB\(di\fP    \e(di    divide
  1319. X\(+-    \fI\(+-\fP    \fB\(+-\fP    \e(+-    plus-minus
  1320. X\(cu    \fI\(cu\fP    \fB\(cu\fP    \e(cu    cup (union)
  1321. X\(ca    \fI\(ca\fP    \fB\(ca\fP    \e(ca    cap (intersection)
  1322. X\(sb    \fI\(sb\fP    \fB\(sb\fP    \e(sb    subset of
  1323. X\(sp    \fI\(sp\fP    \fB\(sp\fP    \e(sp    superset of
  1324. X\(ib    \fI\(ib\fP    \fB\(ib\fP    \e(ib    improper subset
  1325. X\(ip    \fI\(ip\fP    \fB\(ip\fP    \e(ip    improper superset
  1326. X\(if    \fI\(if\fP    \fB\(if\fP    \e(if    infinity
  1327. X\(pd    \fI\(pd\fP    \fB\(pd\fP    \e(pd    partial derivative
  1328. X\(gr    \fI\(gr\fP    \fB\(gr\fP    \e(gr    gradient
  1329. X\(no    \fI\(no\fP    \fB\(no\fP    \e(no    not
  1330. X\(is    \fI\(is\fP    \fB\(is\fP    \e(is    integral sign
  1331. X\(pt    \fI\(pt\fP    \fB\(pt\fP    \e(pt    proportional to
  1332. X\(es    \fI\(es\fP    \fB\(es\fP    \e(es    empty set
  1333. X\(mo    \fI\(mo\fP    \fB\(mo\fP    \e(mo    member of
  1334. X\(br    \fI\(br\fP    \fB\(br\fP    \e(br    box vertical rule
  1335. X\(dd    \fI\(dd\fP    \fB\(dd\fP    \e(dd    double dagger
  1336. X\(rh    \fI\(rh\fP    \fB\(rh\fP    \e(rh    right hand
  1337. X\(lh    \fI\(lh\fP    \fB\(lh\fP    \e(lh    left hand
  1338. X\(bs    \fI\(bs\fP    \fB\(bs\fP    \e(bs    Bell System logo (typesetter-dependent)
  1339. X\(or    \fI\(or\fP    \fB\(or\fP    \e(or    or
  1340. X\(ci    \fI\(ci\fP    \fB\(ci\fP    \e(ci    circle
  1341. X\(lt    \fI\(lt\fP    \fB\(lt\fP    \e(lt    left top of big curly bracket
  1342. X\(lb    \fI\(lb\fP    \fB\(lb\fP    \e(lb    left bottom
  1343. X\(rt    \fI\(rt\fP    \fB\(rt\fP    \e(rt    right top
  1344. X\(rb    \fI\(rb\fP    \fB\(rb\fP    \e(rb    right bot
  1345. X\(lk    \fI\(lk\fP    \fB\(lk\fP    \e(lk    left center of big curly bracket
  1346. X\(rk    \fI\(rk\fP    \fB\(rk\fP    \e(rk    right center of big curly bracket
  1347. X\(bv    \fI\(bv\fP    \fB\(bv\fP    \e(bv    bold vertical
  1348. X\(lf    \fI\(lf\fP    \fB\(lf\fP    \e(lf    left floor (left bottom of big square bracket)
  1349. X\(rf    \fI\(rf\fP    \fB\(rf\fP    \e(rf    right floor (right bottom)
  1350. X\(lc    \fI\(lc\fP    \fB\(lc\fP    \e(lc    left ceiling (left top)
  1351. X\(rc    \fI\(rc\fP    \fB\(rc\fP    \e(rc    right ceiling (right top)
  1352. X\fR
  1353. XThe usual suspects:
  1354. X\fR
  1355. X  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
  1356. X@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \e ] ^ _
  1357. X` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
  1358. X\fI
  1359. X  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
  1360. X@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \e ] ^ _
  1361. X` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
  1362. X\fB
  1363. X  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
  1364. X@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \e ] ^ _
  1365. X` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
  1366. X\fR
  1367. X\s8 \
  1368. X\b'\(br\(br\(br' \b'\(bv\(bv\(bv' \
  1369. X\b'\(lc\(lf' \b'\(rc\(rf' \b'\(lt\(lb' \b'\(rt\(rb' \
  1370. X\b'\(lc\(bv\(lf' \b'\(lt\(lk\(lb' \b'\(lt\(bv\(lb' \
  1371. X\b'\(rc\(bv\(rf' \b'\(rt\(rk\(rb' \b'\(rt\(bv\(rb' \
  1372. X\s0 \
  1373. X\s10 \
  1374. X\b'\(br\(br\(br' \b'\(bv\(bv\(bv' \
  1375. X\b'\(lc\(lf' \b'\(rc\(rf' \b'\(lt\(lb' \b'\(rt\(rb' \
  1376. X\b'\(lc\(bv\(lf' \b'\(lt\(lk\(lb' \b'\(lt\(bv\(lb' \
  1377. X\b'\(rc\(bv\(rf' \b'\(rt\(rk\(rb' \b'\(rt\(bv\(rb' \
  1378. X\s0 \
  1379. X\s12 \
  1380. X\b'\(br\(br\(br' \b'\(bv\(bv\(bv' \
  1381. X\b'\(lc\(lf' \b'\(rc\(rf' \b'\(lt\(lb' \b'\(rt\(rb' \
  1382. X\b'\(lc\(bv\(lf' \b'\(lt\(lk\(lb' \b'\(lt\(bv\(lb' \
  1383. X\b'\(rc\(bv\(rf' \b'\(rt\(rk\(rb' \b'\(rt\(bv\(rb' \
  1384. X\s0 \
  1385. X\(em8, 10, & 12 brackets
  1386. X
  1387. X.ps 8
  1388. X.vs 8
  1389. X8/8 root ens, uls, and rus: X_X_X_ a\(rua\(rua\(ru \(sr\(rn \(br\z\(rn_\(br
  1390. X8/8 root ens, uls, and rus: \(rnX\(rnX\(rnX
  1391. X.ps
  1392. X.vs
  1393. X
  1394. X.ps 10
  1395. X.vs 10
  1396. X10/10 root ens, uls, and rus: X_X_X_ a\(rua\(rua\(ru \(sr\(rn \(br\z\(rn_\(br
  1397. X10/10 root ens, uls, and rus: \(rnX\(rnX\(rnX
  1398. X.ps
  1399. X.vs
  1400. X
  1401. X.ps 12
  1402. X.vs 12
  1403. X12/12 root ens, uls, and rus: X_X_X_ a\(rua\(rua\(ru \(sr\(rn \(br\z\(rn_\(br
  1404. X12/12 root ens, uls, and rus: \(rnX\(rnX\(rnX
  1405. X.ps
  1406. X.vs
  1407. X
  1408. X8, 10 & 12 point repeats: \
  1409. X\s8\(lh\(lh\(lh \(rh\(rh\(rh \(bs\(bs\(bs\s0 \
  1410. X\s10\(lh\(lh\(lh \(rh\(rh\(rh \(bs\(bs\(bs\s0 \
  1411. X\s12\(lh\(lh\(lh \(rh\(rh\(rh \(bs\(bs\(bs\s0
  1412. X.bp
  1413. XOverstrikes:
  1414. X.ta .6i +.6i +.6i +.6i +.6i +.6i +.6i +.6i +.6i +.6i
  1415. X        \e`A    ^A    \e`E    ^E    "E    ^I    "I
  1416. X                        \e`U    ^U    -L
  1417. X        \e'Y    \e'y        ,C    ,c    ~N    ~n
  1418. X                -L    =Y
  1419. X    ^a    ^e    ^o    ^u    \e'a    \e'e    \e'o    \e'u
  1420. X    \e`a    \e`e    \e`o    \e`u    "a    "e    "o    "u
  1421. X    \e(deA    ^i    /O    AE    \e(dea    \e'i    /o    ae
  1422. X    "A    \e`i    "O    "U    \e'E    "i        ^O
  1423. X    \e'A    ~A    ~a    -D    -d    \e'I    \e`I    \e'O
  1424. X    \e`O    ~O    ~o            \e'U    "Y    "y
  1425. X    IJ    ij    Rx    Th    th    TM    ..
  1426. X                <<        >>
  1427. X    /L    /l    OE    oe
  1428. X\fR        \o|\`A|    \o|^A|    \o|\`E|    \o|^E|    \o|"E|    \o|^I|    \o|"I|
  1429. X                        \o|\`U|    \o|^U|    \o|-L|
  1430. X        \o|\'Y|    \o|\'y|        \o|,C|    \o|,c|    \o|~N|    \o|~n|
  1431. X                \o|-L|    \o|=Y|
  1432. X    \o|^a|    \o|^e|    \o|^o|    \o|^u|    \o|\'a|    \o|\'e|    \o|\'o|    \o|\'u|
  1433. X    \o|\`a|    \o|\`e|    \o|\`o|    \o|\`u|    \o|"a|    \o|"e|    \o|"o|    \o|"u|
  1434. X    \o|\(deA|    \o|^i|    \o|/O|    \o|AE|    \o|\(dea|    \o|\'i|    \o|/o|    \o|ae|
  1435. X    \o|"A|    \o|\`i|    \o|"O|    \o|"U|    \o|\'E|    \o|"i|        \o|^O|
  1436. X    \o|\'A|    \o|~A|    \o|~a|    \o|-D|    \o|-d|    \o|\'I|    \o|\`I|    \o|\'O|
  1437. X    \o|\`O|    \o|~O|    \o|~o|            \o|\'U|    \o|"Y|    \o|"y|
  1438. X    \o|IJ|    \o|ij|    \o|Rx|    \o|Th|    \o|th|    \o|TM|    \o|..|
  1439. X                \o|<<|        \o|>>|
  1440. X    \o|/L|    \o|/l|    \o|OE|    \o|oe|
  1441. X\fI        \o|\`A|    \o|^A|    \o|\`E|    \o|^E|    \o|"E|    \o|^I|    \o|"I|
  1442. X                        \o|\`U|    \o|^U|    \o|-L|
  1443. X        \o|\'Y|    \o|\'y|        \o|,C|    \o|,c|    \o|~N|    \o|~n|
  1444. X                \o|-L|    \o|=Y|
  1445. X    \o|^a|    \o|^e|    \o|^o|    \o|^u|    \o|\'a|    \o|\'e|    \o|\'o|    \o|\'u|
  1446. X    \o|\`a|    \o|\`e|    \o|\`o|    \o|\`u|    \o|"a|    \o|"e|    \o|"o|    \o|"u|
  1447. X    \o|\(deA|    \o|^i|    \o|/O|    \o|AE|    \o|\(dea|    \o|\'i|    \o|/o|    \o|ae|
  1448. X    \o|"A|    \o|\`i|    \o|"O|    \o|"U|    \o|\'E|    \o|"i|        \o|^O|
  1449. X    \o|\'A|    \o|~A|    \o|~a|    \o|-D|    \o|-d|    \o|\'I|    \o|\`I|    \o|\'O|
  1450. X    \o|\`O|    \o|~O|    \o|~o|            \o|\'U|    \o|"Y|    \o|"y|
  1451. X    \o|IJ|    \o|ij|    \o|Rx|    \o|Th|    \o|th|    \o|TM|    \o|..|
  1452. X                \o|<<|        \o|>>|
  1453. X    \o|/L|    \o|/l|    \o|OE|    \o|oe|
  1454. X\fB        \o|\`A|    \o|^A|    \o|\`E|    \o|^E|    \o|"E|    \o|^I|    \o|"I|
  1455. X                        \o|\`U|    \o|^U|    \o|-L|
  1456. X        \o|\'Y|    \o|\'y|        \o|,C|    \o|,c|    \o|~N|    \o|~n|
  1457. X                \o|-L|    \o|=Y|
  1458. X    \o|^a|    \o|^e|    \o|^o|    \o|^u|    \o|\'a|    \o|\'e|    \o|\'o|    \o|\'u|
  1459. X    \o|\`a|    \o|\`e|    \o|\`o|    \o|\`u|    \o|"a|    \o|"e|    \o|"o|    \o|"u|
  1460. X    \o|\(deA|    \o|^i|    \o|/O|    \o|AE|    \o|\(dea|    \o|\'i|    \o|/o|    \o|ae|
  1461. X    \o|"A|    \o|\`i|    \o|"O|    \o|"U|    \o|\'E|    \o|"i|        \o|^O|
  1462. X    \o|\'A|    \o|~A|    \o|~a|    \o|-D|    \o|-d|    \o|\'I|    \o|\`I|    \o|\'O|
  1463. X    \o|\`O|    \o|~O|    \o|~o|            \o|\'U|    \o|"Y|    \o|"y|
  1464. X    \o|IJ|    \o|ij|    \o|Rx|    \o|Th|    \o|th|    \o|TM|    \o|..|
  1465. X                \o|<<|        \o|>>|
  1466. X    \o|/L|    \o|/l|    \o|OE|    \o|oe|
  1467. X.bp
  1468. X\fR
  1469. XFont size samples:
  1470. X.vs 36
  1471. X\s6 6\s0\
  1472. X\s7 7\s0\
  1473. X\s8 8\s0\
  1474. X\s9 9\s0\
  1475. X\s10 10\s0\
  1476. X\s11 11\s0\
  1477. X\s12 12\s0\
  1478. X\s14 14\s0\
  1479. X\s16 16\s0\
  1480. X\s18 18\s0\
  1481. X\s20 20\s0\
  1482. X\s22 22\s0\
  1483. X\s24 24\s0\
  1484. X\s28 28\s0\
  1485. X\s36 36\s0
  1486. X.vs
  1487. END_OF_FILE
  1488. if test 10005 -ne `wc -c <'testfile'`; then
  1489.     echo shar: \"'testfile'\" unpacked with wrong size!
  1490. fi
  1491. # end of 'testfile'
  1492. fi
  1493. if test -f 'tlc.c' -a "${1}" != "-c" ; then 
  1494.   echo shar: Will not clobber existing file \"'tlc.c'\"
  1495. else
  1496. echo shar: Extracting \"'tlc.c'\" \(36238 characters\)
  1497. sed "s/^X//" >'tlc.c' <<'END_OF_FILE'
  1498. X#include "ansic.h"
  1499. XID(elsieid, "@(#)tlc.c    4.1")
  1500. X
  1501. Xextern int        getopt();
  1502. Xextern char *        optarg;
  1503. Xextern int        optind;
  1504. X
  1505. X#ifndef BUFSIZ
  1506. X#define BUFSIZ        1024
  1507. X#endif /* !defined BUFSIZ */
  1508. X
  1509. X#ifndef MAXFILES
  1510. X#define MAXFILES    20
  1511. X#endif /* !defined MAXFILES */
  1512. X
  1513. X#ifndef NVPC
  1514. X#define NVPC        256
  1515. X#endif /* !defined NVPC */
  1516. X
  1517. X#ifndef TRUE
  1518. X#define TRUE        1
  1519. X#define FALSE        0
  1520. X#endif /* !defined TRUE */
  1521. X
  1522. X#define NPPI        72    /* Number of Points Per Inch */
  1523. X#define NCHUPI        432    /* Number of C/A/T Horizontal Units Per Inch */
  1524. X#define NCVUPI        144    /* Number of C/A/T Vertical Units Per Inch */
  1525. X#define NCWUPI        NCHUPI    /* Number of C/A/T Width table Units Per Inch */
  1526. X#define CWPS        6    /* C/A/T Width Value Point Size */
  1527. X#define DNIPP        11    /* Default Number of Inches Per Page */
  1528. X#define NI        256    /* Number of troff width table indices */
  1529. X#define MAXPS        36    /* Maxium Point Size */
  1530. X
  1531. Xstatic struct {
  1532. X    const char *    f_fontnick;
  1533. X    char *        f_in;        /* how to get into font */
  1534. X    char *        f_out;        /* how to get out of font */
  1535. X} fontdata[] = {
  1536. X    { "R" },
  1537. X    { "I" },
  1538. X    { "B" },
  1539. X    { "S" }
  1540. X};
  1541. X
  1542. X#define NFONTS    (sizeof fontdata / sizeof fontdata[0])
  1543. X
  1544. X#define fontisx(font, x) (fontdata[font].f_fontnick[0] == (x))
  1545. X#define fontisR(font) (fontisx(font, 'R'))
  1546. X#define fontisI(font) (fontisx(font, 'I'))
  1547. X#define fontisB(font) (fontisx(font, 'B'))
  1548. X#define fontisS(font) (fontisx(font, 'S'))
  1549. X
  1550. X/* Number of C/A/T Vertical Units Per Page */
  1551. X
  1552. Xstatic int        ncvupp = NCVUPI * DNIPP;
  1553. X
  1554. Xstatic float        lwupi;        /* laser width units per inch */
  1555. Xstatic float        lwps;        /* laser width point size */
  1556. Xstatic float        lcpi;        /* laser characters per inch */
  1557. X
  1558. Xstatic char *        sizes;        /* how to get into/out of sizes */
  1559. X
  1560. Xstatic char *        firsts[MAXPS + 1][NFONTS];
  1561. X                    /* for first time font and size seen */
  1562. X
  1563. Xstatic int        lowvalue;
  1564. X
  1565. Xstatic char *        lowstring;
  1566. X
  1567. Xstatic char *        hormove;    /* horizontal move format */
  1568. Xstatic char *        vermove;    /* vertical move format */
  1569. Xstatic char *        enddata;    /* data to send when done */
  1570. Xstatic char *        newpage;    /* data to send for new page */
  1571. Xstatic char *        portrait;    /* to go into portrait mode */
  1572. Xstatic char *        landscape;    /* to go into landscape mode */
  1573. X
  1574. Xstatic int        verunitsperinch;/* printer vertical units per inch */
  1575. X
  1576. Xstatic int        horunitsperinch;/* printer horizontal units per inch */
  1577. X
  1578. Xstatic int        leftmargin;    /* unprintable left margin */
  1579. X
  1580. X/*
  1581. X** Per-"character" data.
  1582. X*/
  1583. X
  1584. Xtypedef struct {
  1585. X    char *    ssname;            /* symbol set name */
  1586. X    char *    inset;            /* how to get into symbol set */
  1587. X    char *    outset;            /* how to get out of symbol set */
  1588. X    char *    data;            /* character-specific data */
  1589. X    int    widths[NFONTS];        /* widths in various fonts */
  1590. X    int    lwidths[NFONTS];    /* LJ widths */
  1591. X    char    waschar;        /* explicitly-set character */
  1592. X} item;
  1593. X
  1594. Xstatic item        items[2 * NI];
  1595. X
  1596. Xstatic int        overstruck[NI];
  1597. X
  1598. Xstatic unsigned char *    overnames[2 * NI];
  1599. X
  1600. X/*
  1601. X** Internal functions.
  1602. X*/
  1603. X
  1604. Xstatic void        LJ_cput();
  1605. Xstatic void        LJ_fdput();
  1606. Xstatic void        LJ_sput();
  1607. Xstatic int        ascends();
  1608. Xstatic char *        checkcp();
  1609. Xstatic void *        checkvp();
  1610. Xstatic int        ctoi();
  1611. Xstatic int        descends();
  1612. Xstatic FILE *        dfopen();
  1613. Xstatic void        disescape();
  1614. Xstatic void        dostrike();
  1615. Xstatic void        dowidth();
  1616. Xstatic char *        ecatalloc();
  1617. Xstatic char *        ecpyalloc();
  1618. Xstatic void *        emalloc();
  1619. Xstatic int        fiswidth();
  1620. Xstatic char *        getline();
  1621. Xstatic char *        icatalloc();
  1622. Xstatic char *        icpyalloc();
  1623. Xstatic void        ifree();
  1624. Xstatic void *        imalloc();
  1625. Xstatic int        inch();
  1626. Xstatic void *        irealloc();
  1627. Xstatic int        linematch();
  1628. Xstatic void        loadinfo();
  1629. Xstatic void        loadsub();
  1630. Xstatic int        lwtocw();
  1631. Xint            main();
  1632. Xstatic const char *    namefor();
  1633. Xstatic int        nametoindex();
  1634. Xstatic int        oscode();
  1635. Xstatic int        osfind();
  1636. Xstatic int        ouch();
  1637. Xstatic const char *    scheck();
  1638. Xstatic int        splitos();
  1639. Xstatic void        swift();
  1640. Xstatic void        tameexit();
  1641. Xstatic void        wild2();
  1642. Xstatic void        wild2exit();
  1643. Xstatic void        wildexit();
  1644. Xstatic void        wildline();
  1645. Xstatic void        wildrexit();
  1646. X
  1647. X/*
  1648. X** External functions.
  1649. X*/
  1650. X
  1651. Xextern int        catsup();
  1652. Xextern const char *    fti2ntn();
  1653. Xextern int        ntn2fti();
  1654. Xextern int        ntnonr();
  1655. Xextern int        ntnons();
  1656. X
  1657. X/*
  1658. X** Messages and exits.
  1659. X*/
  1660. X
  1661. Xstatic const char *    progname;
  1662. X
  1663. Xstatic void
  1664. Xwild2(part1, part2)
  1665. Xconst char * const    part1;
  1666. Xconst char * const    part2;
  1667. X{
  1668. X    (void) fflush(stdout);
  1669. X    /*
  1670. X    ** One space after the colon matches what perror does
  1671. X    ** (although your typing teacher may want a second space).
  1672. X    */
  1673. X    (void) fprintf(stderr, "\n%s: wild", progname);
  1674. X    if (part1 != NULL && *part1 != '\0')
  1675. X        (void) fprintf(stderr, " %s", part1);
  1676. X    if (part2 != NULL && *part2 != '\0')
  1677. X        (void) fprintf(stderr, " %s", part2);
  1678. X    (void) fprintf(stderr, "\n");
  1679. X}
  1680. X
  1681. Xstatic void
  1682. Xwild2exit(string1, string2)
  1683. Xconst char * const    string1;
  1684. Xconst char * const    string2;
  1685. X{
  1686. X    wild2(string1, string2);
  1687. X    exit(EXIT_FAILURE);
  1688. X    /*NOTREACHED*/
  1689. X}
  1690. X
  1691. Xstatic void
  1692. Xwildexit(string)
  1693. Xconst char * const    string;
  1694. X{
  1695. X    wild2exit(string, (char *) NULL);
  1696. X    /*NOTREACHED*/
  1697. X}
  1698. X
  1699. Xstatic void
  1700. Xwildrexit(string)
  1701. Xconst char * const    string;
  1702. X{
  1703. X    wild2exit("result from", string);
  1704. X    /*NOTREACHED*/
  1705. X}
  1706. X
  1707. Xstatic void
  1708. Xtameexit()
  1709. X{
  1710. X    exit(EXIT_SUCCESS);
  1711. X    /*NOTREACHED*/
  1712. X}
  1713. X
  1714. X/*
  1715. X** Memory allocation.
  1716. X*/
  1717. X
  1718. X#ifndef alloc_size_t
  1719. X#define alloc_size_t    unsigned
  1720. X#endif /* !defined alloc_size_t */
  1721. X
  1722. X#ifndef alloc_pointer_t
  1723. X#define alloc_pointer_t char *
  1724. X#endif /* !defined alloc_pointer_t */
  1725. X
  1726. X#ifdef MAL
  1727. X#define NULLMAL(x)    ((x) == NULL || (x) == MAL)
  1728. X#else /* !defined MAL */
  1729. X#define NULLMAL(x)    ((x) == NULL)
  1730. X#endif /* !defined MAL */
  1731. X
  1732. X#define nonzero(n)    (((n) == 0) ? 1 : (n))
  1733. X
  1734. Xstatic void *
  1735. Ximalloc(n)
  1736. Xint const    n;
  1737. X{
  1738. X#ifdef MAL
  1739. X    char *    result;
  1740. X
  1741. X    result = (void *) malloc((alloc_size_t) nonzero(n));
  1742. X    return NULLMAL(result) ? NULL : result;
  1743. X#else /* !defined MAL */
  1744. X    return (void *) malloc((alloc_size_t) nonzero(n));
  1745. X#endif /* !defined MAL */
  1746. X}
  1747. X
  1748. Xstatic void *
  1749. Xirealloc(pointer, size)
  1750. Xvoid * const    pointer;
  1751. Xint const    size;
  1752. X{
  1753. X    if (NULLMAL(pointer))
  1754. X        return imalloc(size);
  1755. X    return (void *) realloc((alloc_pointer_t) pointer,
  1756. X        (alloc_size_t) nonzero(size));
  1757. X}
  1758. X
  1759. Xstatic char *
  1760. Xicatalloc(old, new)
  1761. Xchar * const        old;
  1762. Xconst char * const    new;
  1763. X{
  1764. X    char *    result;
  1765. X    int    oldsize;
  1766. X    int    newsize;
  1767. X
  1768. X    newsize = NULLMAL(new) ? 0 : strlen(new);
  1769. X    if (NULLMAL(old))
  1770. X        oldsize = 0;
  1771. X    else if (newsize == 0)
  1772. X        return old;
  1773. X    else    oldsize = strlen(old);
  1774. X    result = (char *) irealloc((void *) old, oldsize + newsize + 1);
  1775. X    if (result != NULL)
  1776. X        if (NULLMAL(new))
  1777. X            *(result + oldsize) = '\0';
  1778. X        else    (void) strcpy(result + oldsize, new);
  1779. X    return result;
  1780. X}
  1781. X
  1782. Xstatic char *
  1783. Xicpyalloc(string)
  1784. Xconst char * const    string;
  1785. X{
  1786. X    return icatalloc((char *) NULL, string);
  1787. X}
  1788. X
  1789. Xstatic void
  1790. Xifree(p)
  1791. Xvoid * const    p;
  1792. X{
  1793. X    if (!NULLMAL(p))
  1794. X#ifdef USG
  1795. X        free((alloc_pointer_t) p);
  1796. X#endif /* defined USG */
  1797. X#ifndef USG
  1798. X        (void) free((alloc_pointer_t) p);
  1799. X#endif /* !defined USG */
  1800. X}
  1801. X
  1802. Xstatic void *
  1803. Xcheckvp(pointer)
  1804. Xvoid * const    pointer;
  1805. X{
  1806. X    if (pointer == NULL)
  1807. X        wildrexit("allocating memory");
  1808. X    return pointer;
  1809. X}
  1810. X
  1811. Xstatic char *
  1812. Xcheckcp(pointer)
  1813. Xchar * const    pointer;
  1814. X{
  1815. X    if (pointer == NULL)
  1816. X        wildrexit("allocating memory");
  1817. X    return pointer;
  1818. X}
  1819. X
  1820. Xstatic void *
  1821. Xemalloc(size)
  1822. Xint const    size;
  1823. X{
  1824. X    return checkvp(imalloc(size));
  1825. X}
  1826. X
  1827. Xstatic char *
  1828. Xecatalloc(old, new)
  1829. Xchar * const        old;
  1830. Xconst char * const    new;
  1831. X{
  1832. X    return checkcp(icatalloc(old, new));
  1833. X}
  1834. X
  1835. Xstatic char *
  1836. Xecpyalloc(string)
  1837. Xconst char * const    string;
  1838. X{
  1839. X    return checkcp(icpyalloc(string));
  1840. X}
  1841. X
  1842. X/*
  1843. X** Check a format against a string...
  1844. X*/
  1845. X
  1846. Xstatic const char *
  1847. Xscheck(string, format)
  1848. Xconst char * const    string;
  1849. Xconst char * const    format;
  1850. X{
  1851. X    char *        fbuf;
  1852. X    const char *    fp;
  1853. X    char *        tp;
  1854. X    int        c;
  1855. X    const char *    result;
  1856. X    char            dummy;
  1857. X
  1858. X    result = "";
  1859. X    if (string == NULL || format == NULL)
  1860. X        return result;
  1861. X    /*
  1862. X    ** Check for stupid systems that let "9e" match "%f".
  1863. X    ** We only do the easy cases here.
  1864. X    */
  1865. X    {
  1866. X        int    i;
  1867. X
  1868. X        i = strlen(format);
  1869. X        if (i >= 2 && strcmp(&format[i - 2], "%f") == 0) {
  1870. X            i = strlen(string);
  1871. X            if (i > 0 &&
  1872. X                strchr("0123456789", string[i - 1]) == NULL)
  1873. X                    return result;
  1874. X        }
  1875. X    }
  1876. X    fbuf = (char *) imalloc(2 * strlen(format) + 4);
  1877. X    if (fbuf == NULL)
  1878. X        return result;
  1879. X    fp = format;
  1880. X    tp = fbuf;
  1881. X    while ((*tp++ = c = *fp++) != '\0') {
  1882. X        if (c != '%')
  1883. X            continue;
  1884. X        if (*fp == '%') {
  1885. X            *tp++ = *fp++;
  1886. X            continue;
  1887. X        }
  1888. X        *tp++ = '*';
  1889. X        if (*fp == '*')
  1890. X            ++fp;
  1891. X        while (isascii(*fp) && isdigit(*fp))
  1892. X            *tp++ = *fp++;
  1893. X        if (*fp == 'l' || *fp == 'h')
  1894. X            *tp++ = *fp++;
  1895. X        else if (*fp == '[')
  1896. X            do {
  1897. X                *tp++ = *fp++;
  1898. X            } while (*fp != '\0' && *fp != ']');
  1899. X        if ((*tp++ = *fp++) == '\0')
  1900. X            break;
  1901. X    }
  1902. X    *(tp - 1) = '%';
  1903. X    *tp++ = 'c';
  1904. X    *tp = '\0';
  1905. X    if (sscanf(string, fbuf, &dummy) != 1)
  1906. X        result = format;
  1907. X    ifree((void *) fbuf);
  1908. X    return result;
  1909. X}
  1910. X
  1911. X/*
  1912. X** Get [nt]roff names from a file.
  1913. X*/
  1914. X
  1915. Xstatic const char *    sfilename;
  1916. Xstatic int        slinenum;
  1917. X
  1918. Xstatic void
  1919. Xoops(string)
  1920. Xconst char * const    string;
  1921. X{
  1922. X    char    line[132];
  1923. X
  1924. X    (void) sprintf(line, "file \"%s\", line %d: %s\n",
  1925. X        ((sfilename == NULL) ? NULL : sfilename), slinenum, string);
  1926. X    wildexit(line);
  1927. X}
  1928. X
  1929. Xstatic void
  1930. Xgetnames(filename, names)
  1931. Xconst char * const    filename;
  1932. Xchar ** const        names;
  1933. X{
  1934. X    FILE *    fp;
  1935. X    char *    cp;
  1936. X    char *    dp;
  1937. X    int    i;
  1938. X    int    online;
  1939. X    char        line[132];
  1940. X
  1941. X    sfilename = filename;
  1942. X    slinenum = 0;
  1943. X    if (names == NULL)
  1944. X        oops("NULL names argument");
  1945. X    if (filename == NULL)
  1946. X        oops("NULL filename argument");
  1947. X    if ((fp = fopen(filename, "r")) == NULL) {
  1948. X        cp = ecpyalloc(filename);
  1949. X        cp = ecatalloc(cp, ".M");
  1950. X        fp = fopen(cp, "r");
  1951. X        free(cp);
  1952. X        if (fp == NULL)
  1953. X            oops("can't open file");
  1954. X    }
  1955. X    i = 0;
  1956. X    while (fgets(line, sizeof line, fp) == line) {
  1957. X        ++slinenum;
  1958. X        if ((cp = strchr(line, '\n')) == NULL)
  1959. X            oops("line is too long");
  1960. X        *cp = '\t';    /* means all fields are tab terminated */
  1961. X        for (cp = line; *cp != '\0'; ++cp)
  1962. X            if (!isascii(*cp))
  1963. X                oops("non-ASCII character in line");
  1964. X        cp = line;
  1965. X        if (*cp == '#' || *cp == '\0')
  1966. X            continue;
  1967. X        if (i >= NVPC)
  1968. X            oops("too many lines in input");
  1969. X        if (!isspace(*cp))
  1970. X            oops("data line does not begin with space");
  1971. X        for (online = 0; online < 8; ++online) {
  1972. X            while (*cp != '\0' && isspace(*cp))
  1973. X                ++cp;
  1974. X            dp = cp;
  1975. X            while (*dp != '\0' && !isspace(*dp))
  1976. X                ++dp;
  1977. X            if (dp == NULL)
  1978. X                oops("too few fields on line");
  1979. X            *dp = '\0';
  1980. X            names[i++] = (strcmp(cp, "NULL") == 0) ? NULL :
  1981. X                ecpyalloc(cp);
  1982. X            cp = dp + 1;
  1983. X        }
  1984. X        while (isspace(*cp))
  1985. X            ++cp;
  1986. X        if (*cp != '\0')
  1987. X            oops("wrong number of fields on line");
  1988. X    }
  1989. X    if (!feof(fp) || ferror(fp))
  1990. X        oops("wild result reading file");
  1991. X    if (fclose(fp)) {
  1992. X        fp = NULL;
  1993. X        oops("wild result closing file");
  1994. X    }
  1995. X    for ( ; i < NVPC; ++i)
  1996. X        names[i] = NULL;
  1997. X}
  1998. X
  1999. X/*
  2000. X** And now the real work begins...
  2001. X*/
  2002. X
  2003. Xstatic int
  2004. Xfiswidth(font, fti, size)
  2005. Xint const    font;
  2006. Xint const    fti;
  2007. Xint const    size;
  2008. X{
  2009. X    int    w;
  2010. X    int    result;
  2011. X
  2012. X    w = items[fti].widths[font];
  2013. X    result = w * size / CWPS;
  2014. X    if (((w * size) % CWPS) >= (CWPS / 2))
  2015. X        ++result;
  2016. X    return result;
  2017. X}
  2018. X
  2019. Xstatic int        vflag;
  2020. Xstatic int        wflag;
  2021. Xstatic int        xynh;
  2022. X
  2023. Xstatic int
  2024. Xinch()
  2025. X{
  2026. X    return getchar();
  2027. X}
  2028. X
  2029. Xtypedef struct {
  2030. X    int    fti;
  2031. X    long    hor;
  2032. X    long    ver;
  2033. X    int    font;
  2034. X    int    size;
  2035. X} strike;
  2036. X
  2037. Xstatic int
  2038. Xosfind(a, b)
  2039. Xint const    a;
  2040. Xint const    b;
  2041. X{
  2042. X    unsigned char *    ucp;
  2043. X    int            i;
  2044. X
  2045. X    for (i = NI; ; ++i) {
  2046. X        ucp = (unsigned char *) overnames[i];
  2047. X        if (ucp == NULL || *ucp == '\0')
  2048. X            return 0;
  2049. X        if (*ucp == a && *(ucp + 1) == b)
  2050. X            return i;
  2051. X        if (*ucp == b && *(ucp + 1) == a)
  2052. X            return i;
  2053. X    }
  2054. X}
  2055. X
  2056. Xstatic int
  2057. Xoscode(one, two)
  2058. Xstrike    one;
  2059. Xstrike    two;
  2060. X{
  2061. X    strike    three;    /* You're out! */
  2062. X
  2063. X    if (one.ver != two.ver || one.size != two.size)
  2064. X        return 0;
  2065. X    if (one.font != two.font && !fontisS(one.font) && !fontisS(two.font))
  2066. X        return 0;
  2067. X    if (!overstruck[one.fti] || !overstruck[two.fti])
  2068. X        return 0;
  2069. X    if (one.fti == two.fti && one.hor != two.hor)
  2070. X        return 0;
  2071. X    if (one.hor > two.hor) {
  2072. X        three = one;
  2073. X        one = two;
  2074. X        two = three;
  2075. X    }
  2076. X    if ((two.hor - one.hor) >= fiswidth(one.font, one.fti, one.size) / 2)
  2077. X        return 0;
  2078. X    return osfind(one.fti, two.fti);
  2079. X}
  2080. X
  2081. Xstatic int
  2082. Xouch(charname, wchor, wcver, wsize, fontnick)
  2083. Xconst char * const    charname;
  2084. Xlong const        wchor;    /* wanted C/A/T horizontal position */
  2085. Xlong            wcver;    /* wanted C/A/T veritcal position */
  2086. Xint const        wsize;
  2087. Xchar * const        fontnick;
  2088. X{
  2089. X    int    wfont;
  2090. X    int    fti;
  2091. X    int    i;
  2092. X    strike        s;
  2093. X    static strike    ss = { 0, -1, -1, -1, -1 };
  2094. X
  2095. X    fti = ntn2fti(charname);
  2096. X    wcver -= 31;
  2097. X    s.fti = fti;
  2098. X    s.hor = wchor;
  2099. X    s.ver = wcver;
  2100. X    for (wfont = 0; ; ++wfont) {
  2101. X        if (wfont == NFONTS)
  2102. X            wild2exit("font -", fontnick);
  2103. X        if (strcmp(fontnick, fontdata[wfont].f_fontnick) == 0)
  2104. X            break;
  2105. X    }
  2106. X    s.font = wfont;
  2107. X    s.size = wsize;
  2108. X    if ((i = oscode(s, ss)) > 0) {
  2109. X        if (s.hor > ss.hor)
  2110. X            s.hor = ss.hor;
  2111. X        if (fontisS(s.font))
  2112. X            s.font = ss.font;
  2113. X        s.fti = i;
  2114. X        dostrike(s);
  2115. X        ss.fti = 0;
  2116. X    } else {
  2117. X        if (ss.ver != s.ver ||
  2118. X            (s.hor - ss.hor) >=
  2119. X            fiswidth(ss.font, ss.fti, ss.size) / 2) {
  2120. X                dostrike(ss);
  2121. X                ss.fti = 0;
  2122. X        }
  2123. X        if (!overstruck[fti]) {
  2124. X            dostrike(s);
  2125. X        } else {
  2126. X            dostrike(ss);
  2127. X            ss = s;
  2128. X        }
  2129. X    }
  2130. X    return 0;
  2131. X}
  2132. X
  2133. Xstatic const char *    cartridge;
  2134. X
  2135. Xint
  2136. Xmain(argc, argv)
  2137. Xint    argc;
  2138. Xchar *    argv[];
  2139. X{
  2140. X    int    c;
  2141. X    int    nargs;
  2142. X
  2143. X    if ((progname = strrchr(argv[0], '/')) == NULL)
  2144. X        progname = argv[0];
  2145. X    else    ++progname;
  2146. X    while ((c = getopt(argc, argv, "vwx:y:n:h:")) != EOF)
  2147. X        if (c == 'x' || c == 'y' || c == 'n' || c == 'h')
  2148. X            xynh = TRUE;
  2149. X        else if (c == 'v')
  2150. X            vflag = TRUE;
  2151. X        else if (c == 'w')
  2152. X            wflag = TRUE;
  2153. X        else    break;
  2154. X    nargs = argc - optind;
  2155. X    if (c != EOF ||
  2156. X        (vflag && !wflag) ||
  2157. X        nargs != (xynh ? 0 : 1) ||
  2158. X        (nargs == 1 && strcmp(argv[optind], "=") == 0)) {
  2159. X        (void) fprintf(stderr,
  2160. X            "%s: usage is %s [-wv] fontdir < file\n",
  2161. X            progname, progname);
  2162. X        if (nargs == 1 && strcmp(argv[optind], "=") == 0)
  2163. X            tameexit();
  2164. X        else    wildexit("usage");
  2165. X    }
  2166. X    if (!wflag)
  2167. X        if ((c = getchar()) == EOF)
  2168. X            tameexit();
  2169. X        else    (void) ungetc(c, stdin);
  2170. X    if (nargs == 1)
  2171. X        cartridge = argv[optind];
  2172. X    else {
  2173. X        FILE *    fp;
  2174. X        char *    cp;
  2175. X        static char    buf[132];
  2176. X
  2177. X        fp = fopen(".railmag", "r");
  2178. X        if (fp == NULL)
  2179. X            wildrexit("opening .railmag");
  2180. X        if (fgets(buf, sizeof buf, fp) != buf)
  2181. X            wildrexit("reading .railmag");
  2182. X        if (strchr(buf, '\n') == NULL)
  2183. X            wildexit("missing newline in .railmag");
  2184. X        if ((cp = strrchr(buf, '/')) == NULL)
  2185. X            wildexit("missing / in .railmag");
  2186. X        if (fclose(fp))
  2187. X            wildrexit("closing .railmag");
  2188. X        *cp = '\0';
  2189. X        /*
  2190. X        ** Horrid special case.
  2191. X        ** Maybe should check that directory exists.
  2192. X        */
  2193. X        if (strcmp(buf, "/usr/lib/vfont") == 0) {
  2194. X            (void) strcpy(buf, DATADIR);
  2195. X            (void) strcat(buf, "/default");
  2196. X        }
  2197. X        cartridge = buf;
  2198. X    }
  2199. X    loadinfo();
  2200. X    if (wflag) {
  2201. X        dowidth();
  2202. X        tameexit();
  2203. X    }
  2204. X    if (catsup(inch, ouch, TRUE, FALSE) != 0)
  2205. X        wildrexit("catsup");
  2206. X    (void) ouch("", 0L, 0L, 0, "R");    /* to flush */
  2207. X    if (!feof(stdin) || ferror(stdin))
  2208. X        wildrexit("reading standard input");
  2209. X    LJ_sput(enddata);
  2210. X    if (ferror(stdout))
  2211. X        wildrexit("writing");
  2212. X    return 0;
  2213. X}
  2214. X
  2215. X/*
  2216. X** Convert laser width table units to C/A/T width table units
  2217. X*/
  2218. X
  2219. Xstatic int
  2220. Xlwtocw(fti, font, lw)
  2221. Xint const    fti;
  2222. Xint const    font;
  2223. Xint const    lw;
  2224. X{
  2225. X    int    cw;
  2226. X    long    num;
  2227. X    long    den;
  2228. X    static int    prevind;
  2229. X
  2230. X    num = (long) lw * NCWUPI * CWPS;
  2231. X    den = lwupi * lwps;
  2232. X    cw = num / den;
  2233. X    /*
  2234. X    ** Selectively round to ensure that rules meet.
  2235. X    */
  2236. X    if (isascii(fti) && isprint(fti) && fti != '_')
  2237. X        if ((num % den) >= (den / 2))
  2238. X            ++cw;
  2239. X    if (cw > 077) {
  2240. X        if (wflag && fti != prevind) {
  2241. X            (void) fprintf(stderr,
  2242. X"%s: note: char %s, font %s in %s too wide (%d, %d)\n",
  2243. X                progname, fti2ntn(fti),
  2244. X                fontdata[font].f_fontnick, cartridge, lw, cw);
  2245. X            prevind = fti;
  2246. X        }
  2247. X        cw = 077;
  2248. X    }
  2249. X    return cw;
  2250. X}
  2251. X
  2252. Xstatic char *    filenames[MAXFILES];
  2253. Xstatic long    linenums[MAXFILES];
  2254. Xstatic int    lastfid;
  2255. X
  2256. Xstatic void
  2257. Xwildline(message)
  2258. Xconst char * const    message;
  2259. X{
  2260. X    char *    filename;
  2261. X    long    linenum;
  2262. X
  2263. X    if (lastfid >= 0 && lastfid < MAXFILES) {
  2264. X        filename = filenames[lastfid];
  2265. X        linenum = linenums[lastfid];
  2266. X    } else {
  2267. X        filename = NULL;
  2268. X        linenum = -1;
  2269. X    }
  2270. X    (void) fprintf(stderr, "%s: ", progname);
  2271. X    if (filename == NULL)
  2272. X        (void) fprintf(stderr, "file UNKNOWN, ");
  2273. X    else    (void) fprintf(stderr, "file \"%s\", ", filename);
  2274. X    (void) fprintf(stderr, "line %ld: ", linenum);
  2275. X    (void) fprintf(stderr, "wild %s\n",
  2276. X        ((message == NULL) ? "line" : message));
  2277. X    wildexit("information file");
  2278. X}
  2279. X
  2280. Xstatic int
  2281. Xctoi(c)
  2282. Xint const    c;
  2283. X{
  2284. X    const char *    cp;
  2285. X    static const char    digits[] = "0123456789";
  2286. X
  2287. X    cp = strchr(digits, c);
  2288. X    return (cp == NULL) ? -1 : (cp - digits);
  2289. X}
  2290. X
  2291. Xstatic void
  2292. Xdisescape(cp)
  2293. Xchar * const    cp;
  2294. X{
  2295. X    const char *    fromp;
  2296. X    char *        top;
  2297. X    int        c;
  2298. X    int        i;
  2299. X    int        j;
  2300. X
  2301. X    fromp = top = cp;
  2302. X    while ((c = *fromp++) != '\0')
  2303. X        if (c != '\\')
  2304. X            *top++ = c;
  2305. X        else switch ((c = *fromp++)) {
  2306. X            case '\0':    --fromp; *top++ = '\\';    break;
  2307. X            case 'E':    *top++ = '\033';    break;
  2308. X            case 'b':    *top++ = '\b';        break;
  2309. X            case 'f':    *top++ = '\f';        break;
  2310. X            case 'n':    *top++ = '\n';        break;
  2311. X            case 'r':    *top++ = '\r';        break;
  2312. X            case 't':    *top++ = '\t';        break;
  2313. X            case 'v':    *top++ = '\v';        break;
  2314. X            default:
  2315. X                i = ctoi(c);
  2316. X                if (i < 0 || i > 7) {
  2317. X                    *top++ = c;
  2318. X                    break;
  2319. X                }
  2320. X                if ((j = ctoi(*fromp)) >= 0 && j <= 7) {
  2321. X                    ++fromp;
  2322. X                    i = i * 8 + j;
  2323. X                    if ((j = ctoi(*fromp)) >= 0 && j <= 7) {
  2324. X                        ++fromp;
  2325. X                        i = i * 8 + j;
  2326. X                    }
  2327. X                }
  2328. X                *top++ = i;
  2329. X                break;
  2330. X        }
  2331. X    *top = '\0';
  2332. X}
  2333. X
  2334. Xstatic FILE *
  2335. Xdfopen(filename, mode, must)
  2336. Xconst char * const    filename;
  2337. Xconst char * const    mode;
  2338. Xint const        must;
  2339. X{
  2340. X    FILE *    fp;
  2341. X    char *    cp;
  2342. X    char *    dp;
  2343. X    int    fid;
  2344. X    int    pass;
  2345. X
  2346. X    dp = ecpyalloc(cartridge);
  2347. X    for (pass = 1; pass <= 2; ++pass) {
  2348. X        if (pass == 2)
  2349. X            if ((cp = strrchr(dp, '/')) == NULL)
  2350. X                (void) strcpy(dp, ".");
  2351. X            else    *cp = '\0';
  2352. X        cp = ecpyalloc(dp);
  2353. X        cp = ecatalloc(cp, "/");
  2354. X        cp = ecatalloc(cp, filename);
  2355. X        fp = fopen(cp, mode);
  2356. X        if (fp == NULL) {
  2357. X            free(cp);
  2358. X            continue;
  2359. X        }
  2360. X        fid = fileno(fp);
  2361. X        if (fid < 0)
  2362. X            wildexit("negative file descriptor!?");
  2363. X        if (fid >= MAXFILES)
  2364. X            wildexit("large number of files opened");
  2365. X        if (filenames[fid] != NULL)
  2366. X            free(filenames[fid]);
  2367. X        filenames[fid] = cp;
  2368. X        linenums[fid] = 0;
  2369. X        free(dp);
  2370. X        return fp;
  2371. X    }
  2372. X    free(dp);
  2373. X    if (must)
  2374. X        wild2exit("result opening file", filename);
  2375. X    return NULL;
  2376. X}
  2377. X
  2378. Xstatic const char *
  2379. Xnamefor(fp)
  2380. XFILE * const    fp;
  2381. X{
  2382. X    int            fid;
  2383. X    static const char    unknown[] = "UNKNOWN";
  2384. X
  2385. X    if (fp != NULL) {
  2386. X        fid = fileno(fp);
  2387. X        if (fid >= 0 && fid < MAXFILES && filenames[fid] != NULL)
  2388. X            return filenames[fid];
  2389. X    }
  2390. X    return unknown;
  2391. X}
  2392. X
  2393. Xstatic char *
  2394. Xgetline(fp)
  2395. XFILE * const    fp;
  2396. X{
  2397. X    char *    cp;
  2398. X    char *    dp;
  2399. X    static char    line[BUFSIZ];
  2400. X
  2401. X    lastfid = fileno(fp);
  2402. X    for ( ; ; ) {
  2403. X        if (fgets(line, sizeof line, fp) != line) {
  2404. X            if (ferror(fp) || !feof(fp))
  2405. X                wildline("result from reading");
  2406. X            if (fclose(fp))
  2407. X                wildline("result from closing");
  2408. X            return NULL;
  2409. X        }
  2410. X        ++linenums[(int) fileno(fp)];
  2411. X        cp = strchr(line, '\n');
  2412. X        if (cp == NULL)
  2413. X            wildline("long line");
  2414. X        *cp = '\0';
  2415. X        /*
  2416. X        ** Strip comments and trailing space.
  2417. X        */
  2418. X        dp = NULL;
  2419. X        for (cp = line; *cp != '\0'; ++cp)
  2420. X            if (*cp == '#') {
  2421. X                *cp = '\0';
  2422. X                break;
  2423. X            } else if (isascii(*cp) && isspace(*cp)) {
  2424. X                if (dp == NULL)
  2425. X                    dp = cp;
  2426. X            } else {
  2427. X                dp = NULL;
  2428. X                if (*cp == '\\') {
  2429. X                    if (*++cp == '\0')
  2430. X                        break;
  2431. X                }
  2432. X            }
  2433. X        if (dp != NULL)
  2434. X            *dp = '\0';
  2435. X        /*
  2436. X        ** If we've got something. . .
  2437. X        */
  2438. X        if (line[0] != '\0')
  2439. X            return line;
  2440. X    }
  2441. X}
  2442. X
  2443. Xstatic int
  2444. Xsplitos(name, vals)
  2445. Xchar * const    name;
  2446. Xint        vals[2];
  2447. X{
  2448. X    char *    cp;
  2449. X    int    left;
  2450. X    int    right;
  2451. X    int    n;
  2452. X    int    c;
  2453. X
  2454. X    if (name == NULL || *name == '\0')
  2455. X        return -1;
  2456. X    n = 0;
  2457. X    for (cp = name + 1; *cp != '\0'; ++cp) {
  2458. X        if ((right = ntn2fti(cp)) <= 0)
  2459. X            continue;
  2460. X        c = *cp;
  2461. X        *cp = '\0';
  2462. X        left = ntn2fti(name);
  2463. X        *cp = c;
  2464. X        if (left <= 0)
  2465. X            continue;
  2466. X        if (++n > 1)
  2467. X            return -1;
  2468. X        vals[0] = left;
  2469. X        vals[1] = right;
  2470. X    }
  2471. X    return (n == 1) ? 0 : -1;
  2472. X}
  2473. X
  2474. Xstatic int
  2475. Xnametoindex(name)
  2476. Xconst char * const    name;
  2477. X{
  2478. X    int        fti;
  2479. X    int        vals[2];
  2480. X    static int    oi = NI;
  2481. X
  2482. X    if ((fti = ntn2fti(name)) > 0)
  2483. X        return fti;
  2484. X    /*
  2485. X    ** Overstrike mapping?
  2486. X    */
  2487. X    if (splitos(name, vals) != 0) {
  2488. X        char    minibuf[132];
  2489. X
  2490. X        (void) sprintf(minibuf, "character name--\"%s\"", name);
  2491. X        wildline(minibuf);
  2492. X    }
  2493. X    if ((fti = osfind(vals[0], vals[1])) > 0)
  2494. X        return fti;
  2495. X    if (oi >= sizeof items / sizeof items[0])
  2496. X        wildline("large number of overstrikes");
  2497. X    overstruck[vals[0]] = TRUE;
  2498. X    overstruck[vals[1]] = TRUE;
  2499. X    overnames[oi] = (unsigned char *) emalloc(3);
  2500. X    overnames[oi][0] = vals[0];
  2501. X    overnames[oi][1] = vals[1];
  2502. X    overnames[oi][2] = 0;
  2503. X    return oi++;
  2504. X}
  2505. X
  2506. Xstatic int
  2507. Xlinematch(havetype, havecount, wanttype, wantlo, wanthi)
  2508. Xconst char * const    havetype;
  2509. Xint const        havecount;
  2510. Xconst char * const    wanttype;
  2511. Xint const        wantlo;
  2512. Xint const        wanthi;
  2513. X{
  2514. X    if (strcmp(havetype, wanttype) != 0)
  2515. X        return FALSE;
  2516. X    if (havecount < wantlo || havecount > wanthi)
  2517. X        wildline("number of fields");
  2518. X    return TRUE;
  2519. X}
  2520. X
  2521. Xstatic void
  2522. Xloadsub(filename)
  2523. Xconst char * const    filename;
  2524. X{
  2525. X    FILE *    fp;
  2526. X    char *    line;
  2527. X    item *    ip;
  2528. X    int    fti;
  2529. X    int    i;
  2530. X    int    n;
  2531. X    int    font;
  2532. X    int    width;
  2533. X    int        size;
  2534. X    char        t[BUFSIZ];
  2535. X    char        f[9][BUFSIZ];
  2536. X
  2537. X    fp = dfopen(filename, "r", TRUE);
  2538. X    for (i = 0; i < 9; ++i)
  2539. X        f[i][0] = '\0';
  2540. X    while ((line = getline(fp)) != NULL) {
  2541. X        n = sscanf(line, "%s %s %s %s %s %s %s %s",
  2542. X            t, f[2], f[3], f[4],
  2543. X            f[5], f[6], f[7], f[8]);
  2544. X        for (i = 2; i <= n; ++i)
  2545. X            disescape(f[i]);
  2546. X        /*
  2547. X        ** NEWPAGE data
  2548. X        */
  2549. X        if (linematch(t, n, "NEWPAGE", 2, 2)) {
  2550. X            newpage = ecpyalloc(f[2]);
  2551. X            continue;
  2552. X        }
  2553. X        /*
  2554. X        ** PORTRAIT data
  2555. X        */
  2556. X        if (linematch(t, n, "PORTRAIT", 2, 2)) {
  2557. X            portrait = ecpyalloc(f[2]);
  2558. X            continue;
  2559. X        }
  2560. X        /*
  2561. X        ** LANDSCAPE data
  2562. X        */
  2563. X        if (linematch(t, n, "LANDSCAPE", 2, 2)) {
  2564. X            landscape = ecpyalloc(f[2]);
  2565. X            continue;
  2566. X        }
  2567. X        /*
  2568. X        ** DOWNORIENT--always portrait for now.
  2569. X        */
  2570. X        if (linematch(t, n, "DOWNORIENT", 1, 1)) {
  2571. X            LJ_sput(portrait);
  2572. X            continue;
  2573. X        }
  2574. X        /*
  2575. X        ** LEFTMARGIN size
  2576. X        */
  2577. X        if (linematch(t, n, "LEFTMARGIN", 2, 2)) {
  2578. X            if (sscanf(f[2], scheck(f[2], "%d"),
  2579. X                &leftmargin) != 1 || leftmargin < 0)
  2580. X                    wildline("left margin");
  2581. X            continue;
  2582. X        }
  2583. X        /*
  2584. X        ** WIDTHUNITSPERINCH size
  2585. X        */
  2586. X        if (linematch(t, n, "WIDTHUNITSPERINCH", 2, 2)) {
  2587. X            if (sscanf(f[2], scheck(f[2], "%f"), &lwupi) != 1 ||
  2588. X                lwupi <= 0)
  2589. X                    wildline("width units per inch");
  2590. X            continue;
  2591. X        }
  2592. X        /*
  2593. X        ** WIDTHPOINTSIZE size
  2594. X        */
  2595. X        if (linematch(t, n, "WIDTHPOINTSIZE", 2, 2)) {
  2596. X            if (sscanf(f[2], scheck(f[2], "%f"), &lwps) != 1 ||
  2597. X                lwps <= 0)
  2598. X                    wildline("width point size");
  2599. X            continue;
  2600. X        }
  2601. X        /*
  2602. X        ** LOWCHAR value string
  2603. X        */
  2604. X        if (linematch(t, n, "LOWCHAR", 3, 3)) {
  2605. X            if (sscanf(f[2], scheck(f[2], "%d"), &lowvalue) != 1 ||
  2606. X                lowvalue <= 0)
  2607. X                    wildline("low value");
  2608. X            lowstring = ecpyalloc(f[3]);
  2609. X            continue;
  2610. X        }
  2611. X        /*
  2612. X        ** CPI size
  2613. X        */
  2614. X        if (linematch(t, n, "CPI", 2, 2)) {
  2615. X            if (sscanf(f[2], scheck(f[2], "%f"), &lcpi) != 1 ||
  2616. X                lcpi <= 0)
  2617. X                    wildline("CPI");
  2618. X            continue;
  2619. X        }
  2620. X        /*
  2621. X        ** INCLUDE filename
  2622. X        */
  2623. X        if (linematch(t, n, "INCLUDE", 2, 2)) {
  2624. X            loadsub(f[2]);
  2625. X            continue;
  2626. X        }
  2627. X        /*
  2628. X        ** DOWNDATA data
  2629. X        */
  2630. X        if (linematch(t, n, "DOWNDATA", 2, 2)) {
  2631. X            LJ_sput(f[2]);
  2632. X            continue;
  2633. X        }
  2634. X        /*
  2635. X        ** ENDDATA data
  2636. X        */
  2637. X        if (linematch(t, n, "ENDDATA", 2, 2)) {
  2638. X            enddata = ecpyalloc(f[2]);
  2639. X            continue;
  2640. X        }
  2641. X        /*
  2642. X        ** DOWNFILE filename
  2643. X        */
  2644. X        if (linematch(t, n, "DOWNFILE", 2, 2)) {
  2645. X            FILE *    dfp;
  2646. X            char *    cp;
  2647. X            int    c;
  2648. X
  2649. X            cp = ecpyalloc(f[2]);
  2650. X            cp = ecatalloc(cp, ".D");
  2651. X            dfp = dfopen(cp, "r", TRUE);
  2652. X            free(cp);
  2653. X            while ((c = getc(dfp)) != EOF)
  2654. X                LJ_cput(c);
  2655. X            if (ferror(dfp) || !feof(dfp) || fclose(dfp))
  2656. X                wildline("result from downloading");
  2657. X            continue;
  2658. X        }
  2659. X        /*
  2660. X        ** FORGET charname
  2661. X        */
  2662. X        if (linematch(t, n, "FORGET", 2, 2)) {
  2663. X            fti = nametoindex(f[2]);
  2664. X            ip = &items[fti];
  2665. X            ip->ssname = ip->inset =
  2666. X                ip->outset = ip->data = NULL;
  2667. X            ip->waschar = FALSE;
  2668. X            continue;
  2669. X        }
  2670. X        /*
  2671. X        ** UNITSPERINCH horizontal vertical
  2672. X        */
  2673. X        if (linematch(t, n, "UNITSPERINCH", 3, 3)) {
  2674. X            int    hupi;
  2675. X            int    vupi;
  2676. X
  2677. X            if (sscanf(f[2], scheck(f[2], "%d"),
  2678. X                &hupi) != 1 ||
  2679. X                hupi <= 0)
  2680. X                    wildline("horizontal UNITSPERINCH");
  2681. X            if (sscanf(f[2], scheck(f[2], "%d"),
  2682. X                &vupi) != 1 ||
  2683. X                vupi <= 0)
  2684. X                    wildline("vertical UNITSPERINCH");
  2685. X            if (horunitsperinch != 0 &&
  2686. X                (horunitsperinch != hupi ||
  2687. X                verunitsperinch != vupi))
  2688. X                    wildline("repeated UNITSPERINCH");
  2689. X            horunitsperinch = hupi;
  2690. X            verunitsperinch = vupi;
  2691. X            continue;
  2692. X        }
  2693. X        /*
  2694. X        ** MOVES horizontal-move vertical-move
  2695. X        */
  2696. X        if (linematch(t, n, "MOVES", 3, 3)) {
  2697. X            hormove = ecpyalloc(f[2]);
  2698. X            vermove = ecpyalloc(f[3]);
  2699. X            continue;
  2700. X        }
  2701. X        /*
  2702. X        ** FONT name in    out
  2703. X        */
  2704. X        if (linematch(t, n, "FONT", 4, 4)) {
  2705. X            for (font = 0; font < NFONTS; ++font) {
  2706. X                if (strcmp(f[2],
  2707. X                    fontdata[font].f_fontnick) != 0)
  2708. X                        continue;
  2709. X                fontdata[font].f_in = ecpyalloc(f[3]);
  2710. X                fontdata[font].f_out = ecpyalloc(f[4]);
  2711. X                break;
  2712. X            }
  2713. X            if (font == NFONTS)
  2714. X                wildline("unknown font name");
  2715. X            continue;
  2716. X        }
  2717. X        /*
  2718. X        ** SIZES in
  2719. X        */
  2720. X        if (linematch(t, n, "SIZES", 2, 2)) {
  2721. X            sizes = ecatalloc(sizes, f[2]);
  2722. X            continue;
  2723. X        }
  2724. X        /*
  2725. X        ** FIRST pointsize font in
  2726. X        */
  2727. X        if (linematch(t, n, "FIRST", 4, 4)) {
  2728. X            if (sscanf(f[2], scheck(f[2], "%d"), &size) != 1 ||
  2729. X                size < 0 ||
  2730. X                size >= sizeof firsts / sizeof firsts[0])
  2731. X                    wildline("size");
  2732. X            for (i = 0; ; ++i) {
  2733. X                if (i >= NFONTS)
  2734. X                    wildline("font");
  2735. X                if (strcmp(f[3], fontdata[i].f_fontnick) != 0)
  2736. X                    continue;
  2737. X                firsts[size][i] = ecatalloc(firsts[size][i],
  2738. X                    f[4]);
  2739. X                break;
  2740. X            }
  2741. X            continue;
  2742. X        }
  2743. X        /*
  2744. X        ** Need width for rest.
  2745. X        */
  2746. X        if (lwupi == 0)
  2747. X            wildline("missing WIDTHUNITSPERINCH line");
  2748. X        if (lwps == 0)
  2749. X            wildline("missing WIDTHPOINTSIZE line");
  2750. X        if (horunitsperinch == 0 || verunitsperinch == 0)
  2751. X            wildline("missing UNITSPERINCH line");
  2752. X        /*
  2753. X        ** SYMBOLS filename [in [out]]
  2754. X        ** If cpi != 0 and there's no width file,
  2755. X        ** all widths are set to lwupi / lcpi.
  2756. X        */
  2757. X        if (linematch(t, n, "SYMBOLS", 2, 4)) {
  2758. X            FILE *        sfp;
  2759. X            const char *    cp;
  2760. X            char *        template;
  2761. X            char *        names[NI];
  2762. X            char *        rwidths[NI];
  2763. X            char *        iwidths[NI];
  2764. X            char *        bwidths[NI];
  2765. X            int        didr;
  2766. X            int        didib;
  2767. X            char *        ssname;
  2768. X            char *        inset;
  2769. X            char *        outset;
  2770. X
  2771. X            ssname = ecpyalloc(f[2]);
  2772. X            inset = (n <= 2) ? NULL : ecpyalloc(f[3]);
  2773. X            outset = (n <= 3) ? NULL : ecpyalloc(f[4]);
  2774. X            template = ecpyalloc(ssname);
  2775. X            template = ecatalloc(template, ".X");
  2776. X            template[strlen(template) - 1] = 'M';
  2777. X            sfp = dfopen(template, "r", TRUE);
  2778. X            cp = namefor(sfp);
  2779. X            (void) fclose(sfp);
  2780. X            getnames(cp, names);
  2781. X            template[strlen(template) - 1] = 'R';
  2782. X            sfp = dfopen(template, "r", lcpi == 0);
  2783. X            didib = FALSE;
  2784. X            if (sfp == NULL)
  2785. X                didr = FALSE;
  2786. X            else {
  2787. X                didr = TRUE;
  2788. X                cp = namefor(sfp);
  2789. X                (void) fclose(sfp);
  2790. X                getnames(cp, rwidths);
  2791. X
  2792. X                template[strlen(template) - 1] = 'I';
  2793. X                sfp = dfopen(template, "r", FALSE);
  2794. X                if (sfp != NULL) {
  2795. X                    didib = TRUE;
  2796. X                    cp = namefor(sfp);
  2797. X                    (void) fclose(sfp);
  2798. X                    getnames(cp, iwidths);
  2799. X
  2800. X                    template[strlen(template) - 1] = 'B';
  2801. X                    sfp = dfopen(template, "r", TRUE);
  2802. X                    cp = namefor(sfp);
  2803. X                    (void) fclose(sfp);
  2804. X                    getnames(cp, bwidths);
  2805. X                }
  2806. X            }
  2807. X            for (i = 0; i < NI; ++i) {
  2808. X                if (names[i] == NULL)
  2809. X                    continue;
  2810. X                fti = nametoindex(names[i]);
  2811. X                ip = &items[fti];
  2812. X                if (ip->ssname != NULL)
  2813. X                    continue;
  2814. X                ip->ssname = ssname;
  2815. X                ip->inset = inset;
  2816. X                ip->outset = outset;
  2817. X                ip->data = emalloc(2);
  2818. X                ip->data[0] = i;
  2819. X                ip->data[1] = '\0';
  2820. X                for (font = 0; font < NFONTS; ++font) {
  2821. X                    if (!didr)
  2822. X                        width = lwupi / lcpi;
  2823. X                    else {
  2824. X                        cp = rwidths[i];
  2825. X                        if (didib)
  2826. X                            if (fontisB(font))
  2827. X                                cp = bwidths[i];
  2828. X                            else if (fontisI(font))
  2829. X                                cp = iwidths[i];
  2830. X                        if (cp == NULL)
  2831. X                            width = 0;
  2832. X                        else    width = atoi(cp);
  2833. X                    }
  2834. X                    ip->lwidths[font] = width;
  2835. X                    ip->widths[font] = lwtocw(i, font,
  2836. X                        width);
  2837. X                }
  2838. X            }
  2839. X            continue;
  2840. X        }
  2841. X        /*
  2842. X        ** And last but not least. . .
  2843. X        ** CHAR charname symbolset data [wideas offset]
  2844. X        */
  2845. X        if (linematch(t, n, "CHAR", 4, 6)) {
  2846. X            char *    cp;
  2847. X            int        off;
  2848. X
  2849. X            if (n < 6)
  2850. X                off = 0;
  2851. X            else if (sscanf(f[6], scheck(f[6], "%d"), &off) != 1)
  2852. X                wildline("offset");
  2853. X            fti = nametoindex(f[2]);
  2854. X            ip = &items[fti];
  2855. X            if (n == 4 && ip->ssname == NULL &&
  2856. X                strcmp(f[2], "br") != 0)
  2857. X                    wildline("missing width w/o old width");
  2858. X            if (ip->waschar)
  2859. X                wildline("multiple lines for same CHAR");
  2860. X            ip->waschar = TRUE;
  2861. X            for (i = 0; i < NI; ++i) {
  2862. X                item *    jp;
  2863. X
  2864. X                jp = &items[i];
  2865. X                if (jp->ssname != NULL &&
  2866. X                    strcmp(jp->ssname, f[3]) == 0)
  2867. X                        break;
  2868. X            }
  2869. X            if (i >= NI)
  2870. X                wildline("CHAR symbol set");
  2871. X            ip->ssname = items[i].ssname;
  2872. X            ip->inset = items[i].inset;
  2873. X            ip->outset = items[i].outset;
  2874. X            ip->data = ecpyalloc(f[4]);
  2875. X            if (n == 4)
  2876. X                continue;
  2877. X            for (font = 0; font < NFONTS; ++font) {
  2878. X                int    w;
  2879. X
  2880. X                w = off;
  2881. X                for (cp = f[5]; *cp != '\0'; ++cp) {
  2882. X                    if (items[(int) *cp].ssname == NULL)
  2883. X                        wildline("'wide as' string");
  2884. X                    w += items[(int) *cp].lwidths[font];
  2885. X                }
  2886. X                ip->lwidths[font] = w;
  2887. X                ip->widths[font] = lwtocw(fti, font, w);
  2888. X            }
  2889. X            continue;
  2890. X        }
  2891. X        wildline("line of unknown type");
  2892. X    }
  2893. X}
  2894. X
  2895. Xstatic void
  2896. Xloadinfo()
  2897. X{
  2898. X    item *    ip;
  2899. X    int    i;
  2900. X    int    j;
  2901. X    int    font;
  2902. X
  2903. X    loadsub("table");
  2904. X    if (hormove == NULL || vermove == NULL)
  2905. X        wildexit("missing MOVES line in table");
  2906. X    /*
  2907. X    ** Characters with multiple width table indices
  2908. X    */
  2909. X    i = ntn2fti("ul");
  2910. X    j = '_';
  2911. X    if (items[i].ssname == NULL)
  2912. X        items[i] = items[j];
  2913. X    else if (items[j].ssname == NULL)
  2914. X        items[j] = items[i];
  2915. X    i = ntn2fti("hy");
  2916. X    j = '-';
  2917. X    if (items[i].ssname == NULL)
  2918. X        items[i] = items[j];
  2919. X    else if (items[j].ssname == NULL)
  2920. X        items[j] = items[i];
  2921. X    /*
  2922. X    ** Overstrike widths.
  2923. X    */
  2924. X    for (i = NI; overnames[i] != NULL && overnames[i][0] != '\0'; ++i) {
  2925. X        ip = &items[overnames[i][0]];
  2926. X        for (font = 0; font < NFONTS; ++font)
  2927. X            items[i].widths[font] = ip->widths[font];
  2928. X        ip = &items[overnames[i][1]];
  2929. X        for (font = 0; font < NFONTS; ++font)
  2930. X            if (ip->widths[font] > items[i].widths[font])
  2931. X                items[i].widths[font] = ip->widths[font];
  2932. X    }
  2933. X    if (!vflag)
  2934. X        return;
  2935. X    (void) printf("CHAR[S]\tSYMBOLSET  %c%c%c%c WIDTHS    DATA\n",
  2936. X        *fontdata[0].f_fontnick, *fontdata[1].f_fontnick,
  2937. X        *fontdata[2].f_fontnick, *fontdata[3].f_fontnick);
  2938. X    for (i = 0;
  2939. X        i < NI || (overnames[i] != NULL && overnames[i][0] != '\0');
  2940. X        ++i) {
  2941. X        ip = &items[i];
  2942. X        if (ip->ssname == NULL)
  2943. X            continue;
  2944. X        if (i < NI)
  2945. X            (void) printf("%s", fti2ntn(i));
  2946. X        else    (void) printf("%s %s", fti2ntn((int) overnames[i][0]),
  2947. X                fti2ntn((int) overnames[i][1]));
  2948. X        (void) printf("\t%-9s", ip->ssname);
  2949. X        for (font = 0; font < NFONTS; ++font)
  2950. X            (void) printf("%4d", ip->widths[font]);
  2951. X        (void) printf(" ");
  2952. X        for (j = 0; ip->data[j] != '\0'; ++j) {
  2953. X            int    c;
  2954. X
  2955. X            c = ip->data[j];
  2956. X            if (isascii(c) && isprint(c) && c != ' ')
  2957. X                (void) putchar(c);
  2958. X            else if (c == '\033')
  2959. X                (void) printf("\\E");
  2960. X            else    (void) printf("\\%03o", (unsigned char) c);
  2961. X        }
  2962. X        (void) printf("\n");
  2963. X    }
  2964. X}
  2965. X
  2966. Xstatic void
  2967. XLJ_cput(c)
  2968. Xint const    c;
  2969. X{
  2970. X    if (!wflag)
  2971. X        (void) putchar(c);
  2972. X}
  2973. X
  2974. Xstatic void
  2975. XLJ_sput(s)
  2976. Xconst char *    s;
  2977. X{
  2978. X    int    c;
  2979. X
  2980. X    if (s == NULL)
  2981. X        return;
  2982. X    while ((c = *s++) != '\0')
  2983. X        LJ_cput(c);
  2984. X}
  2985. X
  2986. Xstatic void
  2987. XLJ_fdput(f, d)
  2988. Xconst char * const    f;
  2989. Xint const        d;
  2990. X{
  2991. X/*
  2992. X** 302 / 1000 is log10(2.0) rounded up.
  2993. X** Subtract one for the sign bit;
  2994. X** add one for integer division truncation;
  2995. X** add one more for a minus sign.
  2996. X*/
  2997. X#define INT_STRLEN_MAXIMUM(type) \
  2998. X    ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2)
  2999. X
  3000. X    static char *    buf;
  3001. X    static int    bufsize;
  3002. X    int        wantsize;
  3003. X
  3004. X    wantsize = strlen(f) + INT_STRLEN_MAXIMUM(int) + 1;
  3005. X    if (wantsize > bufsize) {
  3006. X        ifree(buf);
  3007. X        buf = emalloc(wantsize);
  3008. X        bufsize = wantsize;
  3009. X    }
  3010. X    (void) sprintf(buf, f, d);
  3011. X    LJ_sput(buf);
  3012. X}
  3013. X
  3014. Xstatic void
  3015. Xswift(afont, wfont)
  3016. Xint const    afont;
  3017. Xint const    wfont;
  3018. X{
  3019. X    if (afont >= 0)
  3020. X        LJ_sput(fontdata[afont].f_out);
  3021. X    LJ_sput(fontdata[wfont].f_in);
  3022. X}
  3023. X
  3024. Xstatic void
  3025. Xdostrike(s)
  3026. Xstrike    s;
  3027. X{
  3028. X    item *        ip;
  3029. X    static long    achor = -1;
  3030. X    static long    acver = -1;
  3031. X    static int    afont = -1;
  3032. X    static int    asize = -1;
  3033. X    static int    apage = -1;
  3034. X    static item *    curip;
  3035. X    static item *    oldip;
  3036. X    static int    called;
  3037. X
  3038. X    if (s.fti <= 0)
  3039. X        return;
  3040. X    /*
  3041. X    ** First time downloading.
  3042. X    */
  3043. X    if (firsts[s.size][s.font] != NULL) {
  3044. X        FILE *    fp;
  3045. X        char *    cp;
  3046. X        char *    dp;
  3047. X        int    c;
  3048. X
  3049. X        cp = firsts[s.size][s.font];
  3050. X        firsts[s.size][s.font] = NULL;
  3051. X        while ((c = *cp++) != '\0') {
  3052. X            if (c != '<') {
  3053. X                LJ_cput(c);
  3054. X                continue;
  3055. X            }
  3056. X            dp = cp;
  3057. X            while (*dp != '\0' && *dp != '>')
  3058. X                ++dp;
  3059. X            if (*dp == '\0') {
  3060. X                LJ_cput(c);
  3061. X                continue;
  3062. X            }
  3063. X            *dp = '\0';
  3064. X            /*
  3065. X            ** Download the file.
  3066. X            */
  3067. X            if ((fp = fopen(cp, "r")) == NULL)
  3068. X                wild2exit("result opening", cp);
  3069. X            while ((c = getc(fp)) != EOF)
  3070. X                LJ_cput(c);
  3071. X            if (ferror(fp) || !feof(fp) || fclose(fp))
  3072. X                wildexit("result from downloading");
  3073. X            *dp++ = '>';
  3074. X            cp = dp;
  3075. X        }
  3076. X        curip = NULL;    /* to get font reselection */
  3077. X    }
  3078. X    ip = &items[s.fti];
  3079. X    /*
  3080. X    ** Easiest part first.
  3081. X    */
  3082. X    if (curip != NULL && curip->outset != NULL &&
  3083. X        curip->ssname != ip->ssname) {
  3084. X            LJ_sput(curip->outset);
  3085. X            curip = oldip;
  3086. X            oldip = NULL;
  3087. X    }
  3088. X    if (curip == NULL || ip->ssname != curip->ssname) {
  3089. X        LJ_sput(ip->inset);
  3090. X        if (ip->outset != NULL)
  3091. X            oldip = curip;
  3092. X        curip = ip;
  3093. X    }
  3094. X    /*
  3095. X    ** Get to right page; modulate vertical offset.
  3096. X    */
  3097. X    {
  3098. X        int    wpage;
  3099. X
  3100. X        wpage = s.ver / ncvupp;
  3101. X        if (wpage != apage) {
  3102. X
  3103. X            if (called)
  3104. X                LJ_sput(newpage);
  3105. X            apage = wpage;
  3106. X            acver = 0;
  3107. X        }
  3108. X        s.ver %= ncvupp;
  3109. X    }
  3110. X    /*
  3111. X    ** Get to right horizontal place.
  3112. X    */
  3113. X    /*
  3114. X    ** Always position repeated root ens and underlines.
  3115. X    */
  3116. X    {
  3117. X        static int    didindices;
  3118. X        static int    rnindex;
  3119. X        static int    ulindex;
  3120. X        static int    _index;
  3121. X        static int    dotindex;
  3122. X        static int    prev;
  3123. X
  3124. X        if (!didindices) {
  3125. X            didindices = TRUE;
  3126. X            rnindex = ntn2fti("rn");
  3127. X            ulindex = ntn2fti("ul");
  3128. X            _index = ntn2fti("_");
  3129. X            dotindex = ntn2fti(".");
  3130. X        }
  3131. X        if (s.fti == prev &&
  3132. X            (s.fti == rnindex ||
  3133. X            s.fti == ulindex ||
  3134. X            s.fti  == _index ||
  3135. X            s.fti == dotindex))
  3136. X                achor = ~s.hor;
  3137. X        prev = s.fti;
  3138. X    }
  3139. X    if (s.hor != achor) {
  3140. X        long    wlhor;
  3141. X        static long    adjustment;
  3142. X
  3143. X        wlhor = s.hor * horunitsperinch / NCHUPI;
  3144. X        /*
  3145. X        ** Adjust for stupid left margin.
  3146. X        */
  3147. X        if (wlhor < leftmargin)
  3148. X            adjustment = leftmargin;
  3149. X        wlhor += adjustment;
  3150. X        /*
  3151. X        ** Rustproofing.
  3152. X        */
  3153. X        if (wlhor < 0)
  3154. X            wlhor = 0;
  3155. X        LJ_fdput(hormove, (int) wlhor);
  3156. X        achor = s.hor;
  3157. X    }
  3158. X    /*
  3159. X    ** Get to right vertical place.
  3160. X    */
  3161. X    {
  3162. X        long    wlver;
  3163. X
  3164. X        if (s.ver != acver) {
  3165. X            wlver = (long) s.ver * verunitsperinch / NCVUPI;
  3166. X            /*
  3167. X            ** Rustproofing.
  3168. X            */
  3169. X            if (wlver < 0)
  3170. X                wlver = 0;
  3171. X            LJ_fdput(vermove, (int) wlver);
  3172. X            acver = s.ver;
  3173. X        }
  3174. X    }
  3175. X    /*
  3176. X    ** If haven't already changed font. . .
  3177. X    */
  3178. X    if (afont != s.font) {
  3179. X        swift(afont, s.font);
  3180. X        afont = s.font;
  3181. X    }
  3182. X    if (asize != s.size) {
  3183. X        LJ_fdput(sizes, s.size);
  3184. X        asize = s.size;
  3185. X    }
  3186. X    /*
  3187. X    ** Quote if necessary.
  3188. X    */
  3189. X    if (ip->data != NULL && ip->data[0] != 0 && ip->data[1] == 0 &&
  3190. X        lowvalue != 0 && ip->data[0] < lowvalue)
  3191. X            LJ_sput(lowstring);
  3192. X    /*
  3193. X    ** Finally send out the data.
  3194. X    */
  3195. X    if (ip->data != NULL)
  3196. X        LJ_sput(ip->data);
  3197. X    else if (isascii(s.fti) && isprint(s.fti))
  3198. X        LJ_cput(s.fti);
  3199. X    else    LJ_cput('\177'); /* make this settable? */
  3200. X    /*
  3201. X    ** Update horizontal position.
  3202. X    */
  3203. X    achor += fiswidth(s.font, s.fti, s.size);
  3204. X    called = TRUE;
  3205. X}
  3206. X
  3207. X/*
  3208. X** The stuff below is used only when generating width tables for use with troff.
  3209. X*/
  3210. X
  3211. Xstatic int
  3212. Xascends(name)
  3213. Xconst char *    name;
  3214. X{
  3215. X    if (name[1] == '\0')
  3216. X        return isdigit(name[0]) || isupper(name[0]) ||
  3217. X            strchr("bdfhijklt", name[0]) != 0;
  3218. X    switch (*name++) {
  3219. X        case '*': return strchr("bdzhlcfqGDHLCPSUFQW", *name) != 0;
  3220. X        case 'f': return strchr("ilf", *name) != 0;
  3221. X        case 'F': return strchr("il", *name) != 0;
  3222. X        case 'g': return *name == 'r';
  3223. X    }
  3224. X    return FALSE;
  3225. X}
  3226. X
  3227. Xstatic int
  3228. Xdescends(name)
  3229. Xconst char * const    name;
  3230. X{
  3231. X    if (name[1] == '\0')
  3232. X        return strchr("Qgjpqy", name[0]) != 0;
  3233. X    if (name[0] == '*')
  3234. X        return strchr("bgzymcrfxq", name[1]) != 0;
  3235. X    return strcmp(name, "ts") == 0;
  3236. X}
  3237. X
  3238. Xstatic void
  3239. Xdowidth()
  3240. X{
  3241. X    FILE *        fp;
  3242. X    char *        cp;
  3243. X    const char *    name;
  3244. X    item *        ip;
  3245. X    int        font;
  3246. X    int        j;
  3247. X    int        w;
  3248. X
  3249. X    for (font = 0; font < NFONTS; ++font) {
  3250. X        cp = ecpyalloc("ft");
  3251. X        cp = ecatalloc(cp, fontdata[font].f_fontnick);
  3252. X        fp = dfopen(cp, "w", TRUE);
  3253. X        free(cp);
  3254. X        for (j = 0; j < 256; ++j) {
  3255. X            if ((name = fti2ntn(j)) == NULL) {
  3256. X                (void) putc(0, fp);
  3257. X                continue;
  3258. X            }
  3259. X            if (fontisS(font) ? ntnonr(name) : ntnons(name)) {
  3260. X                (void) putc(0, fp);
  3261. X                continue;
  3262. X            }
  3263. X            if (strcmp(name, "\\^") == 0) 
  3264. X                w = (NCHUPI * CWPS) / (NPPI * 12); /* 1/12 em */
  3265. X            else if (strcmp(name, "\\|") == 0)
  3266. X                w = (NCHUPI * CWPS) / (NPPI * 6); /* 1/6 em */
  3267. X            else {
  3268. X                ip = &items[j];
  3269. X                if (ip->ssname == NULL) {
  3270. X                    (void) putc(0, fp);
  3271. X                    continue;
  3272. X                }
  3273. X                w = ip->widths[font];
  3274. X                if (ascends(name))
  3275. X                    w |= 0200;
  3276. X                if (descends(name))
  3277. X                    w |= 0100;
  3278. X            }
  3279. X            (void) putc(w, fp);
  3280. X        }
  3281. X        if (ferror(fp) || fclose(fp))
  3282. X            wildline("result writing");
  3283. X    }
  3284. X}
  3285. END_OF_FILE
  3286. if test 36238 -ne `wc -c <'tlc.c'`; then
  3287.     echo shar: \"'tlc.c'\" unpacked with wrong size!
  3288. fi
  3289. # end of 'tlc.c'
  3290. fi
  3291. echo shar: End of archive 2 \(of 2\).
  3292. cp /dev/null ark2isdone
  3293. MISSING=""
  3294. for I in 1 2 ; do
  3295.     if test ! -f ark${I}isdone ; then
  3296.     MISSING="${MISSING} ${I}"
  3297.     fi
  3298. done
  3299. if test "${MISSING}" = "" ; then
  3300.     echo You have unpacked both archives.
  3301.     rm -f ark[1-9]isdone
  3302. else
  3303.     echo You still need to unpack the following archives:
  3304.     echo "        " ${MISSING}
  3305. fi
  3306. ##  End of shell archive.
  3307. exit 0
  3308.