home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume02 / tdp < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  27.5 KB

  1. From mipos3!omepd!littlei!uunet!husc6!necntc!ncoast!allbery Sat Apr  9 17:00:01 PDT 1988
  2. Article 339 of comp.sources.misc:
  3. Path: td2cad!mipos3!omepd!littlei!uunet!husc6!necntc!ncoast!allbery
  4. From: gry@IDA.LiU.SE.UUCP (Goran Rydquist)
  5. Newsgroups: comp.sources.misc
  6. Subject: v02i086: Determine Troff document type
  7. Message-ID: <8804011110.AA05798@mina.liu.se>
  8. Date: 1 Apr 88 11:10:23 GMT
  9. Sender: allbery@ncoast.UUCP
  10. Reply-To: gry@IDA.LiU.SE.UUCP (Goran Rydquist)
  11. Organization: CIS Dept, Univ of Linkoping, Sweden
  12. Lines: 1163
  13. Approved: allbery@ncoast.UUCP
  14. comp.sources.misc: Volume 2, Issue 86
  15. Submitted-By: "Goran Rydquist" <gry@IDA.LiU.SE.UUCP>
  16. Archive-Name: tdp
  17.  
  18. comp.sources.misc: Volume 2, Issue 86
  19. Submitted-By: "Goran Rydquist" <gry@IDA.LiU.SE.UUCP>
  20. Archive-Name: tdp
  21.  
  22. [Sent on April 1; it looks legitimate, but caveat programmer....  ++bsa]
  23.  
  24. The following C code determines the troff document type of its parameters, and
  25. if requested to, executes it. The code is a fast hack (< 6 hours), but has
  26. been found to work quite reliably here for a couple of months. 
  27.  
  28. ---
  29. Goran Rydqvist            gorry@majestix.liu.se
  30. Troskareg. 69:22        seismo!enea!liuida!majestix!gorry
  31. 583 30  Linkoping        Linkoping Institute of Technology
  32. Sweden                Int +46-13213696 / +46-13282494
  33. ---------
  34.  
  35. #! /bin/sh
  36. # This is a shell archive.  Remove anything before this line, then unpack
  37. # it by saving it into a file and typing "sh file".  To overwrite existing
  38. # files, type "sh file -c".  You can also feed this as standard input via
  39. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  40. # will see the following message at the end:
  41. #        "End of shell archive."
  42. # Contents:  README dtp.c dtp.man hash.c hash.h makefile tool.h
  43. # Wrapped by gorry@smidefix on Thu Feb 18 14:36:45 1988
  44. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  45. if test -f README -a "${1}" != "-c" ; then 
  46.   echo shar: Will not over-write existing file \"README\"
  47. else
  48. echo shar: Extracting \"README\" \(97 characters\)
  49. sed "s/^X//" >README <<'END_OF_README'
  50. XSimple instruction on modification of the system can be found
  51. Xat the beginning of the file dtp.c
  52. END_OF_README
  53. if test 97 -ne `wc -c <README`; then
  54.     echo shar: \"README\" unpacked with wrong size!
  55. fi
  56. # end of overwriting check
  57. fi
  58. if test -f dtp.c -a "${1}" != "-c" ; then 
  59.   echo shar: Will not over-write existing file \"dtp.c\"
  60. else
  61. echo shar: Extracting \"dtp.c\" \(14184 characters\)
  62. sed "s/^X//" >dtp.c <<'END_OF_dtp.c'
  63. X/*
  64. X  dtp.c
  65. X
  66. X  Dtp tries to decide the troff document type of the file specified by the
  67. X  file argument. The program recognizes:
  68. X
  69. X  Changes:
  70. X
  71. X  To change the output of the program, change the strcat's in all_done().
  72. X
  73. X  To modify the set of commands that invokes a filter, alter the lists
  74. X  in build_assoc().
  75. X
  76. X  To add a filter:
  77. X      Add a constant XX below.
  78. X    Add a boolean global variable xx below and set it initially to FALSE.
  79. X    Add a char *xx_opt below and update set_filter_opt() appropriately.
  80. X    Add the recognizers in build_assoc() - addassoc("yy", XX);.
  81. X    Add a case XX: xx = TRUE; break; to the switch in getcom().
  82. X    Add a recognizer in all_done() of the form:
  83. X        if (xx) {
  84. X            ADD_PIPE(command, fnameflag);
  85. X        strcat(command, " | xx");
  86. X        add_opt_and_fname(command, xx_opt, &fnameflag);
  87. X        }
  88. X    in the correct position.
  89. X      Recompile.
  90. X
  91. X  Written by:    
  92. X
  93. X  Goran Rydqvist <gorry@majestix.liu.se>
  94. X  */
  95. X
  96. X
  97. X#include <stdio.h>
  98. X#include "tool.h"
  99. X#include "hash.h"
  100. X
  101. X#define STREQ(s1, s2) (!strcmp(s1, s2))
  102. X
  103. X#define EOLN '\n'
  104. X
  105. X#define REFER 1
  106. X#define PIC 2
  107. X#define TBL 3
  108. X#define EQN 4
  109. X#define MS 5
  110. X#define MAN 6
  111. X#define AMBIG 7
  112. X#define ME 8
  113. X#define SWE 9
  114. X#define PSTROFF 10
  115. X#define PLAIN 11        /* Plain troff - no macros */
  116. X
  117. X
  118. XFILE *fp;
  119. X
  120. XBOOL refer    = FALSE;
  121. XBOOL pic    = FALSE;
  122. XBOOL tbl    = FALSE;
  123. XBOOL eqn    = FALSE;
  124. XBOOL ms        = FALSE;
  125. XBOOL me        = FALSE;
  126. XBOOL man    = FALSE;
  127. XBOOL ambig    = FALSE;
  128. XBOOL a_ms    = FALSE;
  129. XBOOL a_me    = FALSE;
  130. XBOOL a_man    = FALSE;
  131. XBOOL iptroff    = FALSE;
  132. XBOOL ditroff    = TRUE;
  133. XBOOL swe    = FALSE;
  134. XBOOL pstroff    = FALSE;
  135. XBOOL plain    = FALSE;
  136. X
  137. XBOOL execute    = FALSE;
  138. X
  139. Xchar *refer_opt      = "";
  140. Xchar *pic_opt      = "";
  141. Xchar *tbl_opt      = "";
  142. Xchar *eqn_opt      = "";
  143. Xchar *troff_opt = "";
  144. Xchar *swe_opt      = "";
  145. X
  146. Xchar *self;
  147. Xchar *fnames = (char *) 0;
  148. Xchar suffix[40];
  149. X
  150. XHASH *assoc;            /* Global hash table object */
  151. X
  152. X
  153. X#define ADD_PIPE(command, flag) if (flag) strcat(command, " | ");
  154. X
  155. Xvoid add_opt_and_fname(command, opt, flag)
  156. Xchar *command, *opt;
  157. Xint *flag;
  158. X{
  159. X    if (opt[0]) {
  160. X    strcat(command, " ");
  161. X    strcat(command, opt);
  162. X    }
  163. X    if (!(*flag)) {
  164. X    strcat(command, " ");
  165. X    strcat(command, fnames);
  166. X    *flag = 1;
  167. X   }
  168. X}
  169. X
  170. X
  171. X/* AI - part of dtp (ha ha). */
  172. Xvoid all_done()
  173. X{
  174. X    char command[100];
  175. X    int fnamesflag;
  176. X    
  177. X    strcpy(command, "");
  178. X    fnamesflag = FALSE;
  179. X    
  180. X    if (!strcmp(suffix, "ms")) {
  181. X    if (man || me)
  182. X        fprintf(stderr, "%s: strange suffix .%s\n", self, suffix);
  183. X    else
  184. X        ms = TRUE;
  185. X    }
  186. X    if (!strcmp(suffix, "me")) {
  187. X    if (man || ms)
  188. X        fprintf(stderr, "%s: strange suffix .%s\n", self, suffix);
  189. X    else
  190. X        me = TRUE;
  191. X    }
  192. X    if (!strcmp(suffix, "man")) {
  193. X    if (ms || me)
  194. X        fprintf(stderr, "%s: strange suffix .%s\n", self, suffix);
  195. X    else
  196. X        man = TRUE;
  197. X    }
  198. X
  199. X    if (a_ms) {
  200. X    ms = a_ms; me = FALSE; man = FALSE;
  201. X    }
  202. X    if (a_me) {
  203. X    me = a_me; ms = FALSE; man = FALSE;
  204. X    }
  205. X    if (a_man) {
  206. X    man = a_man; ms = FALSE; me = FALSE;
  207. X    }
  208. X
  209. X    if (!(ms || me || man) && ambig)
  210. X    fprintf(stderr, "%s: ambigous - use propper suffix .ms, .me, .man\n"
  211. X        , self), exit(1);
  212. X
  213. X    if (swe) {
  214. X    if (pstroff)
  215. X        strcat(command, "swede -Tps");
  216. X    else
  217. X        strcat(command, "swede");
  218. X    add_opt_and_fname(command, swe_opt, &fnamesflag);
  219. X    }
  220. X
  221. X    if (refer) {
  222. X    ADD_PIPE(command, fnamesflag);
  223. X    strcat(command, "refer -e");
  224. X    add_opt_and_fname(command, refer_opt, &fnamesflag);
  225. X    }
  226. X
  227. X    if (pic) {
  228. X    ADD_PIPE(command, fnamesflag);
  229. X    strcat(command, "pic");
  230. X    if (pstroff)
  231. X        strcat(command, " -Tps");
  232. X    strcat(command, " -D");
  233. X    add_opt_and_fname(command, pic_opt, &fnamesflag);
  234. X    }
  235. X
  236. X    if (tbl) {
  237. X    ADD_PIPE(command, fnamesflag);
  238. X    strcat(command, "tbl");
  239. X    add_opt_and_fname(command, tbl_opt, &fnamesflag);    
  240. X    }
  241. X
  242. X    if (eqn) {
  243. X    ADD_PIPE(command, fnamesflag);
  244. X    if (pstroff)
  245. X        strcat(command, "eqn -Tps");
  246. X    else
  247. X        strcat(command, "eqn");
  248. X    add_opt_and_fname(command, eqn_opt, &fnamesflag);    
  249. X    }
  250. X    
  251. X    if (pstroff) {
  252. X    ADD_PIPE(command, fnamesflag);    
  253. X    strcat(command, "pstroff");
  254. X    iptroff = FALSE;
  255. X    ditroff = FALSE;
  256. X    } else if (iptroff) {
  257. X    ADD_PIPE(command, fnamesflag);
  258. X    strcat(command, "iptroff");
  259. X    ditroff = FALSE;
  260. X    }
  261. X    else if (ditroff) {
  262. X    ADD_PIPE(command, fnamesflag);
  263. X    strcat(command, "ditroff");
  264. X    }
  265. X
  266. X    if (ms)
  267. X    strcat(command, " -ms");
  268. X    else if (me)
  269. X    strcat(command, " -me");
  270. X    else if (man)
  271. X    strcat(command, " -man");
  272. X    add_opt_and_fname(command, troff_opt, &fnamesflag);
  273. X
  274. X    if (ditroff) {
  275. X    strcat(command, " > ");
  276. X    strcat(command, self);
  277. X    strcat(command, ".out");
  278. X    }
  279. X    
  280. X    printf("%s\n", command);
  281. X    if (execute)
  282. X    system(command);
  283. X
  284. X    exit(0);
  285. X}
  286. X
  287. X
  288. Xvoid addassoc(key, value)
  289. Xchar *key;
  290. Xint value;
  291. X{
  292. X    inserthentry(assoc, (int) key[0]*256 + (int) key[1], &value, sizeof(int));
  293. X}
  294. X
  295. X
  296. X/* The two-char combinations below are inserted in a hash table. If a line
  297. Xbegins with a '.', the following two characters are checked against these. */
  298. Xvoid build_assoc()
  299. X{
  300. X    /* For refer */
  301. X    addassoc("[ ", REFER);
  302. X    addassoc("] ", REFER);
  303. X
  304. X    /* For pic */
  305. X    addassoc("PS", PIC);
  306. X    addassoc("PE", PIC);
  307. X
  308. X    /* For tbl */
  309. X    addassoc("TS", TBL);
  310. X    addassoc("TE", TBL);
  311. X    
  312. X    /* For eqn */
  313. X    addassoc("EQ", EQN);
  314. X    addassoc("EN", EQN);
  315. X
  316. X    /* For ms */
  317. X    addassoc("1C", MS);
  318. X    addassoc("2C", MS);
  319. X    addassoc("AB", MS);
  320. X    addassoc("AE", MS);
  321. X    addassoc("AI", MS);
  322. X    addassoc("AM", MS);
  323. X    addassoc("AT", MS);
  324. X    addassoc("AU", MS);
  325. X    addassoc("B1", MS);
  326. X    addassoc("B2", MS);
  327. X    addassoc("BX", MS);
  328. X    addassoc("CM", MS);
  329. X    addassoc("CT", MS);
  330. X    addassoc("DA", MS);
  331. X    addassoc("DE", MS);
  332. X    addassoc("DS", MS);
  333. X    addassoc("EF", MS);
  334. X    /* EN, EQ - eqn */
  335. X    addassoc("FE", MS);
  336. X    addassoc("FS", MS);
  337. X    addassoc("KE", MS);
  338. X    addassoc("KF", MS);
  339. X    addassoc("KS", MS);
  340. X    addassoc("LG", MS);
  341. X    addassoc("ND", MS);
  342. X    addassoc("NH", MS);
  343. X    addassoc("NL", MS);
  344. X    addassoc("OF", MS);
  345. X    addassoc("OH", MS);
  346. X    addassoc("P1", MS);
  347. X    addassoc("PT", MS);
  348. X    addassoc("PX", MS);
  349. X    addassoc("QP", MS);
  350. X    addassoc("R ", MS);
  351. X    addassoc("RP", MS);
  352. X    addassoc("TA", MS);
  353. X    /* TE - tbl */
  354. X    addassoc("TL", MS);
  355. X    addassoc("TM", MS);
  356. X    /* TS - tbl */
  357. X    addassoc("UL", MS);
  358. X    addassoc("XA", MS);
  359. X    addassoc("XE", MS);
  360. X    addassoc("XS", MS);
  361. X    addassoc("UL", MS);
  362. X
  363. X    /* For man */
  364. X    /* B ambigous */
  365. X    addassoc("BI", MAN);
  366. X    addassoc("BR", MAN);
  367. X    addassoc("DT", MAN);
  368. X    addassoc("HP", MAN);
  369. X    /* I ambigous */
  370. X    addassoc("IB", MAN);
  371. X    /* IP ambigous */
  372. X    addassoc("IR", MAN);
  373. X    /* LP ambigous */
  374. X    addassoc("PD", MAN);
  375. X    /* PP ambigous */
  376. X    /* RE ambigous */
  377. X    addassoc("RB", MAN);
  378. X    addassoc("RI", MAN);
  379. X    /* RS ambigous */
  380. X    /* SH ambigous */
  381. X    /* SM ambigous */
  382. X    /* TH ambigous */
  383. X    addassoc("TP", MAN);
  384. X
  385. X    /* For me */
  386. X    addassoc("(c", ME);
  387. X    addassoc("(d", ME);
  388. X    addassoc("(f", ME);
  389. X    addassoc("(l", ME);
  390. X    addassoc("(q", ME);
  391. X    addassoc("(x", ME);
  392. X    addassoc("(z", ME);
  393. X    addassoc(")c", ME);
  394. X    addassoc(")d", ME);
  395. X    addassoc(")f", ME);
  396. X    addassoc(")l", ME);
  397. X    addassoc(")q", ME);
  398. X    addassoc(")x", ME);
  399. X    addassoc(")z", ME);
  400. X    addassoc("++", ME);
  401. X    addassoc("+c", ME);
  402. X    addassoc("1c", ME);
  403. X    addassoc("2c", ME);
  404. X    /* EN, EQ - eqn */
  405. X    /* TE, TH, TS - tbl*/
  406. X    addassoc("ac", ME);
  407. X    addassoc("b ", ME);
  408. X    addassoc("ba", ME);
  409. X    addassoc("bc", ME);
  410. X    addassoc("bi", ME);
  411. X    addassoc("bx", ME);
  412. X    addassoc("ef", ME);
  413. X    addassoc("eh", ME);
  414. X    addassoc("fo", ME);
  415. X    addassoc("he", ME);
  416. X    addassoc("hl", ME);
  417. X    addassoc("hx", ME);
  418. X    addassoc("i ", ME);
  419. X    addassoc("ip", ME);
  420. X    addassoc("lp", ME);
  421. X    addassoc("lo", ME);
  422. X    addassoc("np", ME);
  423. X    addassoc("of", ME);
  424. X    addassoc("oh", ME);
  425. X    addassoc("pd", ME);
  426. X    addassoc("pp", ME);
  427. X    addassoc("r ", ME);
  428. X    addassoc("re", ME);
  429. X    addassoc("sc", ME);
  430. X    addassoc("sh", ME);
  431. X    addassoc("sk", ME);
  432. X    addassoc("sz", ME);
  433. X    addassoc("th", ME);
  434. X    addassoc("tp", ME);
  435. X    addassoc("u ", ME);
  436. X    addassoc("uh", ME);
  437. X    addassoc("xp", ME);
  438. X
  439. X    /* For swede */
  440. X    addassoc("SW", SWE);
  441. X    addassoc("SE", SWE);
  442. X
  443. X    /* Ambigous - recognized, but not used */
  444. X    addassoc("B ", AMBIG);
  445. X    addassoc("I ", AMBIG);
  446. X    addassoc("IP", AMBIG);
  447. X    addassoc("LP", AMBIG);
  448. X    addassoc("IX", AMBIG);
  449. X    addassoc("PP", AMBIG);
  450. X    addassoc("RE", AMBIG);
  451. X    addassoc("RS", AMBIG);
  452. X    addassoc("SH", AMBIG);
  453. X    addassoc("SM", AMBIG);
  454. X    addassoc("TH", AMBIG);
  455. X
  456. X    /* For troff */
  457. X    addassoc("ab", PLAIN);
  458. X    addassoc("ad", PLAIN);
  459. X    addassoc("af", PLAIN);
  460. X    addassoc("am", PLAIN);
  461. X    addassoc("as", PLAIN);
  462. X    addassoc("bd", PLAIN);
  463. X    addassoc("bd", PLAIN);
  464. X    addassoc("bp", PLAIN);
  465. X    addassoc("br", PLAIN);
  466. X    addassoc("c2", PLAIN);
  467. X    addassoc("cc", PLAIN);
  468. X    addassoc("ce", PLAIN);
  469. X    addassoc("ch", PLAIN);
  470. X    addassoc("cs", PLAIN);
  471. X    addassoc("cu", PLAIN);
  472. X    addassoc("da", PLAIN);
  473. X    addassoc("de", PLAIN);
  474. X    addassoc("di", PLAIN);
  475. X    addassoc("ds", PLAIN);
  476. X    addassoc("dt", PLAIN);
  477. X    addassoc("ec", PLAIN);
  478. X    addassoc("el", PLAIN);
  479. X    addassoc("em", PLAIN);
  480. X    addassoc("eo", PLAIN);
  481. X    addassoc("ev", PLAIN);
  482. X    addassoc("ex", PLAIN);
  483. X    addassoc("fc", PLAIN);
  484. X    addassoc("fi", PLAIN);
  485. X    addassoc("fl", PLAIN);
  486. X    addassoc("fp", PLAIN);
  487. X    addassoc("ft", PLAIN);
  488. X    addassoc("fz", PLAIN);
  489. X    addassoc("hc", PLAIN);
  490. X    addassoc("hw", PLAIN);
  491. X    addassoc("hy", PLAIN);
  492. X    addassoc("ie", PLAIN);
  493. X    addassoc("if", PLAIN);
  494. X    addassoc("ig", PLAIN);
  495. X    addassoc("in", PLAIN);
  496. X    addassoc("it", PLAIN);
  497. X    addassoc("lc", PLAIN);
  498. X    addassoc("lg", PLAIN);
  499. X    addassoc("ll", PLAIN);
  500. X    addassoc("ls", PLAIN);
  501. X    addassoc("lt", PLAIN);
  502. X    addassoc("mc", PLAIN);
  503. X    addassoc("mk", PLAIN);
  504. X    addassoc("na", PLAIN);
  505. X    addassoc("ne", PLAIN);
  506. X    addassoc("nf", PLAIN);
  507. X    addassoc("nh", PLAIN);
  508. X    addassoc("nm", PLAIN);
  509. X    addassoc("nn", PLAIN);
  510. X    addassoc("nr", PLAIN);
  511. X    addassoc("ns", PLAIN);
  512. X    addassoc("nx", PLAIN);
  513. X    addassoc("os", PLAIN);
  514. X    addassoc("pc", PLAIN);
  515. X    addassoc("pi", PLAIN);
  516. X    addassoc("pm", PLAIN);
  517. X    addassoc("ps", PLAIN);
  518. X    addassoc("pl", PLAIN);
  519. X    addassoc("pn", PLAIN);
  520. X    addassoc("po", PLAIN);
  521. X    addassoc("rd", PLAIN);
  522. X    addassoc("rn", PLAIN);
  523. X    addassoc("rm", PLAIN);
  524. X    addassoc("rr", PLAIN);
  525. X    addassoc("rs", PLAIN);
  526. X    addassoc("rt", PLAIN);
  527. X    addassoc("so", PLAIN);
  528. X    addassoc("sp", PLAIN);
  529. X    addassoc("ss", PLAIN);
  530. X    addassoc("sv", PLAIN);
  531. X    addassoc("ta", PLAIN);
  532. X    addassoc("tc", PLAIN);
  533. X    addassoc("ti", PLAIN);
  534. X    addassoc("tl", PLAIN);
  535. X    addassoc("tm", PLAIN);
  536. X    addassoc("tr", PLAIN);
  537. X    addassoc("uf", PLAIN);
  538. X    addassoc("ul", PLAIN);
  539. X    addassoc("vs", PLAIN);
  540. X    addassoc("wh", PLAIN);
  541. X}
  542. X
  543. X
  544. Xint getcom()
  545. X{
  546. X    register int i;
  547. X    register int *res;
  548. X    register char c1, c2;
  549. X
  550. X    if ((c1 = getc(fp)) != '.')
  551. X    return c1;
  552. X
  553. X    if ((c1 = getc(fp)) == EOF)
  554. X    return EOF;
  555. X    if (c1 == EOLN)
  556. X    return c1;
  557. X
  558. X    if ((c2 = getc(fp)) == EOF)
  559. X    return EOF;
  560. X    if (c2 == EOLN)
  561. X    c2 = ' ';
  562. X
  563. X    i = (int) c1*256 + (int) c2;
  564. X    if (!(res = (int *) lookuphentry(assoc, i)))
  565. X    return;            /* Unknown */
  566. X    
  567. X    switch (*res) {
  568. X      case REFER:
  569. X    refer = TRUE;
  570. X    break;
  571. X      case PIC:
  572. X    pic = TRUE;
  573. X    break;
  574. X      case TBL:
  575. X    tbl = TRUE;
  576. X    break;
  577. X      case EQN:
  578. X    eqn = TRUE;
  579. X    break;
  580. X      case MS:
  581. X    ms = TRUE;
  582. X    break;
  583. X      case ME:
  584. X    me = TRUE;
  585. X    break;
  586. X      case MAN:
  587. X    man = TRUE;
  588. X    break;
  589. X      case AMBIG:
  590. X    ambig = TRUE;
  591. X    break;
  592. X      case SWE:
  593. X    swe = TRUE;
  594. X    break;
  595. X      case PLAIN:
  596. X    plain = TRUE;
  597. X    break;
  598. X      default:
  599. X    printf("getcom: can't happen\n");
  600. X    abort();
  601. X    }
  602. X    return 1;
  603. X}
  604. X
  605. X
  606. X#define FILL(s, argvp) \
  607. X{ \
  608. X    if (STREQ(s, "")) { \
  609. X    s = (char *) malloc(240); \
  610. X    strcpy(s, *++(*argvp)); \
  611. X    } \
  612. X    else { \
  613. X    strcat(s, " "); \
  614. X        strcat(s, *++(*argvp)); \
  615. X    } \
  616. X} \
  617. X
  618. Xvoid set_filter_opt(argcp, argvp)
  619. Xint *argcp;
  620. Xchar ***argvp;
  621. X{
  622. X    (*argvp)++;            /* Step to the filter parameter */
  623. X    (*argcp)--;
  624. X
  625. X    if (STREQ(**argvp, "refer"))
  626. X    FILL(refer_opt, argvp)
  627. X    else if (STREQ(**argvp, "pic"))
  628. X    FILL(pic_opt, argvp)
  629. X    else if (STREQ(**argvp, "tbl"))
  630. X    FILL(tbl_opt, argvp)
  631. X    else if (STREQ(**argvp, "eqn"))
  632. X    FILL(eqn_opt, argvp)
  633. X    else if (STREQ(**argvp, "troff"))
  634. X    FILL(troff_opt, argvp)
  635. X    else if (STREQ(**argvp, "swede"))
  636. X    FILL(swe_opt, argvp)
  637. X    else
  638. X    usage();
  639. X    (*argcp)--;
  640. X}
  641. X
  642. X
  643. Xusage()
  644. X{
  645. X    fprintf(stderr, "Usage: %s [ -aipx -ms -me -man] files\n", self);
  646. X    exit(1);
  647. X}
  648. X
  649. X
  650. Xmain(argc, argv)
  651. Xint argc;
  652. Xchar **argv;
  653. X{
  654. X    int i;
  655. X
  656. X    fnames = (char *) malloc(800);
  657. X    strcpy(fnames, "");
  658. X    
  659. X    assoc = newhash(273);
  660. X    build_assoc();
  661. X
  662. X    self = argv[0];
  663. X
  664. X    argv++;
  665. X    argc--;
  666. X
  667. X    for(; argc-- > 0; argv++)
  668. X    if( argv[0][0] == '-' ) {
  669. X        if (STREQ(argv[0], "-ms")) {
  670. X        a_ms = TRUE; a_me = FALSE; a_man = FALSE;
  671. X        } else if (STREQ(argv[0], "-me")) {
  672. X        a_me = TRUE; a_ms = FALSE; a_man = FALSE; 
  673. X        } else if (STREQ(argv[0], "-man")) {
  674. X        a_man = TRUE; a_ms = FALSE; a_me = FALSE;
  675. X        } else if (STREQ(argv[0], "-a")) {
  676. X        set_filter_opt(&argc, &argv);
  677. X        } else for(i = strlen(argv[0]) - 1; i > 0; i--)
  678. X        switch( argv[0][i] ) {
  679. X          case 'i':
  680. X            iptroff = TRUE;
  681. X            pstroff = FALSE;
  682. X            ditroff = FALSE;
  683. X            break;
  684. X          case 'p':
  685. X            pstroff = TRUE;
  686. X            iptroff = FALSE;
  687. X            ditroff = FALSE;
  688. X            break;
  689. X          case 'x':
  690. X            execute = TRUE;
  691. X            break;
  692. X          default:
  693. X            usage();
  694. X        }
  695. X    }
  696. X    else {
  697. X        if (!STREQ(fnames, ""))
  698. X        strcat(fnames, " ");
  699. X        strcat(fnames, argv[0]);
  700. X        troff_scan(argv[0]);
  701. X    }
  702. X
  703. X    all_done();
  704. X}
  705. X
  706. X
  707. Xtroff_scan(fname)
  708. Xchar *fname;
  709. X{
  710. X    register char c;
  711. X
  712. X    if (fname == (char *) 0)
  713. X    usage();
  714. X    
  715. X    if ((fp = fopen(fname, "r")) == (FILE *) 0) {
  716. X    fprintf(stderr, "%s: %s not found\n", self, fname);
  717. X    exit(1);
  718. X    }
  719. X    
  720. X    sscanf(fname, "%[^.] %1s %s", suffix, suffix, suffix);
  721. X
  722. X    for(;;) {
  723. X    if (getcom() == EOF) break; /* Get a troff command */
  724. X
  725. X    /* Skip to next eoln */
  726. X    for(c = getc(fp); (c != EOLN) && (c != EOF); c = getc(fp));
  727. X    if (c == EOF) break;
  728. X
  729. X    /* Skip eolns */
  730. X    for(c = getc(fp); (c == EOLN) && (c != EOF); c = getc(fp));
  731. X    if (c == EOF) break;
  732. X    ungetc(c, fp);
  733. X    }
  734. X    fclose(fp);
  735. X
  736. X    if ( !(refer || pic || tbl || eqn || ms || man || me || ambig || plain) ) {
  737. X    fprintf(stderr, "%s: %s not troff file\n", self, fname);
  738. X    exit(1);
  739. X    }
  740. X}
  741. END_OF_dtp.c
  742. if test 14184 -ne `wc -c <dtp.c`; then
  743.     echo shar: \"dtp.c\" unpacked with wrong size!
  744. fi
  745. # end of overwriting check
  746. fi
  747. if test -f dtp.man -a "${1}" != "-c" ; then 
  748.   echo shar: Will not over-write existing file \"dtp.man\"
  749. else
  750. echo shar: Extracting \"dtp.man\" \(3073 characters\)
  751. sed "s/^X//" >dtp.man <<'END_OF_dtp.man'
  752. X.TH DTP 1 "27 April 1987"
  753. X.SH NAME
  754. Xdtp \- decide troff document type
  755. X.SH SYNOPSIS
  756. X.B dtp
  757. X[
  758. X.B \-ipxq \-ms \-me \-man
  759. X] [
  760. X.B \-a
  761. X.I "filter argument"
  762. X] \fIfiles
  763. X.SH DESCRIPTION
  764. XDtp tries to decide the troff document type of \fIfiles\fP. A resulting
  765. Xcommand is printed to standard output, including only the filters needed,
  766. Xand possibly a macro package. This is decided from recognized unambigous 
  767. Xcommands/macros in \fIfiles\fP. If nothing in \fIfiles\fP indicates
  768. Xthe macro package, the file suffix is checked \- .ms, .me, .man are recognized.
  769. X.LP
  770. XThe default troff processor is ditroff. When ditroff is used, the
  771. Xoutput is redirected to the file dtp.out. The \-i option changes the troff
  772. Xprocessor to iptroff, and the \-p option changes it to pstroff.
  773. X.SH OPTIONS
  774. X.TP 1i
  775. X.B \-i
  776. XUse iptroff as troff processor instead of ditroff.
  777. X.TP
  778. X.B \-p
  779. XUse pstroff as troff processor.
  780. X.TP
  781. X.B \-x
  782. XExecute the resulting command.
  783. X.TP
  784. X.B \-ms
  785. XForce \-ms as macro package.
  786. X.TP
  787. X.B \-me
  788. XForce \-me.
  789. X.TP
  790. X.B \-man
  791. XForce \-man.
  792. X.TP
  793. X.B \-a \fIfilter argument\fP
  794. XAdd \fIargument\fP to \fIfilter\fP. The refer, swede, pic, tbl, eqn and
  795. Xtroff filters are recognized.
  796. X.SH WHAT IS RECOGNIZED
  797. X.TP 1i
  798. X.B refer \-e 
  799. XThe \-e mode is recognized from .[ and .]
  800. X.TP
  801. X.B swede 
  802. XSwede is a special filter that replaces the special characters {, }, |, [, ], \
  803. X\\ with the Swedish equivalents between .SW and .SE. \-Tps is added 
  804. Xautomatically if pstroff is used as troff processor.
  805. X.TP
  806. X.B pic \-D
  807. XThe undocumented feature of pic \-D is always issued. Pic is recognized
  808. Xfrom .PS and .PE
  809. X.TP
  810. X.B tbl
  811. XTbl is recognized from .TS and .TE
  812. X.TP
  813. X.B eqn
  814. XEqn is recognized from .EQ and .EN
  815. X.TP
  816. X.B \-ms
  817. X .1C .2C .AB .AE .AI .AM .AT .AU .B1 \
  818. X .B2 .BX .CM .CT .DA .DE .DS .EF .FE .FS .KE .KF .KS .LG .ND .NH .NL \
  819. X .OF .OH .P1 .PT .PX .QP .R  .RP .TA .TL .TM .UL .XA .XS .UL
  820. X.TP
  821. X.B \-man
  822. X .BI .BR .DT .HP .IB .IR .PD .RB .RI .TP
  823. X.TP
  824. X.B \-me
  825. X .(c .(d .(f .(l .(q .(x .(z .)c .)d .)f .)l .)q .)x \
  826. X .)z .++ .1c .2c .ac .b  .ba .bc .bi .bx .ef .eh .fo \
  827. X .he .hl .hx .i  .ip .lp .lo .np .of .oh .pd .pp .r \
  828. X .re .sc .sh .sk .sz .th .tp .u  .uh .xp 
  829. X.TP
  830. X.B Ambiguous
  831. X .B .I .IP .LP .IX .PP .RE .RS .SH .SM .TH. \
  832. XThese are not unique to any specific macro package or filter, and causes no
  833. Xselection.
  834. X.TP
  835. X.B Plain Troff
  836. X .ab .ad .af .am .as .bd .bp .br .c2 .cc .ce .ch .cs .cu .da .de .di .ds .dt \
  837. X .ec .el .em .eo .ev .ex .fc .fi .fl .fp .ft .fz .hc .hw .hy .ie .if .ig .in \
  838. X .it .lc .lg .ll .ls .lt .mc .mk .na .ne .nf .nh .nm .nn .nr .ns .nx .os .pc \
  839. X .pi .pm .ps .pl .pn .po .rd .rn .rm .rr .rs .rt .so .sp .ss .sv .ta .tc .ti \
  840. X .tl .tm .tr .uf .ul .vs .wh
  841. X.LP
  842. XIf no filter selection, macro requests or plain troff commands are found, dtp
  843. Xassumes that the formatting request was a mistake, and exits.
  844. X.SH AUTHOR
  845. XG\o"o\(um"ran Rydqvist <gorry@majestix.liu.se>
  846. X.br
  847. XDepartement of Computer and Information Science, Link\o"o\(um"ping, Sweden.
  848. X.SH SEE ALSO
  849. X.I "Formatting Documents on the Sun Workstation"
  850. X.br
  851. Xtroff(1), tbl(1), eqn(1), pic(1), ms(7)
  852. X.SH BUGS
  853. XThe program was written in about six hours \- don't expect to much.
  854. END_OF_dtp.man
  855. if test 3073 -ne `wc -c <dtp.man`; then
  856.     echo shar: \"dtp.man\" unpacked with wrong size!
  857. fi
  858. # end of overwriting check
  859. fi
  860. if test -f hash.c -a "${1}" != "-c" ; then 
  861.   echo shar: Will not over-write existing file \"hash.c\"
  862. else
  863. echo shar: Extracting \"hash.c\" \(3693 characters\)
  864. sed "s/^X//" >hash.c <<'END_OF_hash.c'
  865. X/*
  866. X  hash.c
  867. X
  868. X  Handles bucket hash objects of warying size. Each keyed item consists of
  869. X  an invariant and an arbitrary part.
  870. X
  871. X  Interface:
  872. X
  873. X  A HASH object is declared by: HASH *object;
  874. X
  875. X  HASH *newhash(size)
  876. X  int size;
  877. X  Retrurn a pointer to a new HASH object of size.
  878. X
  879. X  void rmhash(object)
  880. X  HASH *object;
  881. X  Free memory occupied by a HASH object.
  882. X
  883. X  char *lookuphentry(object, key)
  884. X  HASH *object;
  885. X  KEY key;
  886. X  Return a pointer to the data part of a hash entry. Return NIL if no such key.
  887. X
  888. X  BOOL inserthentry(object, key, data, datasize)
  889. X  HASH *object;
  890. X  KEY key;
  891. X  char *data;
  892. X  int datasize;
  893. X  Insert key and data into hash table object. No insertion is performed if key
  894. X  already exists. Returns true if insertion done.
  895. X
  896. X  BOOL rmhentry(object, key)
  897. X  HASH *object;
  898. X  KEY key;
  899. X  Remove a hash entry matching key. Returns true if entry removed.
  900. X
  901. X  HENTRY firsthentry(object)
  902. X  HASH *object;
  903. X  Return the data part of the first key in the hash table object.
  904. X
  905. X  HENTRY nexthentry(object)
  906. X  HASH *object;
  907. X  Return the data part of the ensuing key in the hash table object.
  908. X
  909. X  OBS! A firsthentry() call must precede nexthentry() calls between
  910. X  hashtable manipulation (rmhentry() och inserthentry()).
  911. X
  912. X  */
  913. X
  914. X#include <stdio.h>
  915. X#include <malloc.h>
  916. X#include "tool.h"
  917. X#include "hash.h"
  918. X
  919. X
  920. XHASH *newhash(size)
  921. Xint size;
  922. X{
  923. X    HASH *ht;
  924. X
  925. X    CHKMEM(ht = (HASH *) malloc(sizeof(HASH)), "newhash");
  926. X    ht -> no_buckets = size;
  927. X    ht -> no_inhab = 0;
  928. X    ht -> cur_bucket = 0;
  929. X    ht -> cur_cell = 0;
  930. X    CHKMEM(ht -> thetbl = (HENTRY *) calloc(size, sizeof(HENTRY)), "newhash");
  931. X
  932. X    return ht;
  933. X}
  934. X
  935. X
  936. Xvoid rmhash(object)
  937. XHASH *object;
  938. X{
  939. X    register HENTRY *p, hp, prev;
  940. X
  941. X    for(p = object -> thetbl; object -> no_inhab > 0; p++)
  942. X    for(hp = *p; hp; hp = prev -> next) {
  943. X        prev = hp;
  944. X        free(hp);
  945. X        object -> no_inhab--;
  946. X    }
  947. X
  948. X    free(object -> thetbl);
  949. X    free(object);
  950. X}
  951. X
  952. X
  953. Xchar *lookuphentry(object, key)
  954. XHASH *object;
  955. XKEY key;
  956. X{
  957. X    register HENTRY *p, hp;
  958. X
  959. X    p = object -> thetbl + h(object, key); /* Hash the key */
  960. X    for(hp = *p; hp; hp = hp -> next) /* Follow bucket */
  961. X    if (hp -> key == key)
  962. X        return (hp -> data);
  963. X    return (char *) 0;
  964. X}
  965. X
  966. X
  967. Xvoid mvbytes(p1, p2, n)
  968. Xregister char *p1, *p2;
  969. Xregister int n;
  970. X{
  971. X    for(; n-- > 0; *p1++ = *p2++);
  972. X}
  973. X
  974. X
  975. XBOOL inserthentry(object, key, data, datasize)
  976. XHASH *object;
  977. XKEY key;
  978. Xchar *data;
  979. Xint datasize;
  980. X{
  981. X    register HENTRY *p, hp;
  982. X
  983. X    p = object -> thetbl + h(object, key);
  984. X    for(hp = *p; hp; hp = hp -> next)
  985. X    if (hp -> key == key)
  986. X        return FALSE;
  987. X    CHKMEM(hp = (HENTRY) malloc(sizeof(struct h_cell) + datasize),
  988. X       "inserthentry");
  989. X
  990. X    hp -> key = key;
  991. X    hp -> next = *p;
  992. X    mvbytes(hp -> data, data, datasize);
  993. X    *p = hp;
  994. X
  995. X    return TRUE;
  996. X}
  997. X
  998. X
  999. XBOOL rmhentry(object, key)
  1000. XHASH *object;
  1001. XKEY key;
  1002. X{
  1003. X    register HENTRY *p, hp, prev;
  1004. X
  1005. X    p = object -> thetbl + h(object, key);
  1006. X    for(hp = *p; hp; prev = hp, hp = hp -> next)
  1007. X    if (hp -> key == key) {
  1008. X        if (hp == *p)    /* First bucket is a special case */
  1009. X        *p = hp -> next;
  1010. X        else
  1011. X        prev -> next = hp -> next;
  1012. X        object -> no_inhab--;
  1013. X        free(hp);
  1014. X        return TRUE;
  1015. X    }
  1016. X    
  1017. X    return FALSE;
  1018. X}
  1019. X
  1020. X
  1021. X
  1022. XHENTRY firsthentry(object)
  1023. XHASH *object;
  1024. X{
  1025. X    object -> cur_bucket = 0;
  1026. X    object -> cur_cell = 0;
  1027. X    return nexthentry(object);
  1028. X}
  1029. X
  1030. X
  1031. XHENTRY nexthentry(object)
  1032. Xregister HASH *object;
  1033. X{
  1034. X    register HENTRY *p, hp;
  1035. X    register int i;
  1036. X    
  1037. X    for(;;) {
  1038. X    p = object -> thetbl + object -> cur_bucket;
  1039. X    i = object -> cur_cell;
  1040. X    for(hp = *p; hp; hp = hp -> next, i--)
  1041. X        if( i < 1 ) {
  1042. X        object -> cur_cell++;
  1043. X        return hp;
  1044. X        }
  1045. X    
  1046. X    if (!hp) {
  1047. X        object -> cur_cell = 0;
  1048. X        if (++object -> cur_bucket >= object -> no_buckets)
  1049. X        return (HENTRY) 0;
  1050. X    }
  1051. X    }
  1052. X}
  1053. X
  1054. END_OF_hash.c
  1055. if test 3693 -ne `wc -c <hash.c`; then
  1056.     echo shar: \"hash.c\" unpacked with wrong size!
  1057. fi
  1058. # end of overwriting check
  1059. fi
  1060. if test -f hash.h -a "${1}" != "-c" ; then 
  1061.   echo shar: Will not over-write existing file \"hash.h\"
  1062. else
  1063. echo shar: Extracting \"hash.h\" \(866 characters\)
  1064. sed "s/^X//" >hash.h <<'END_OF_hash.h'
  1065. X/*
  1066. X  hash.h
  1067. X
  1068. X  Include file for hash.c
  1069. X
  1070. X  Synopsis:
  1071. X
  1072. X  #include <stdio.h>
  1073. X  #include "tool.h"
  1074. X  #include "hash.h"
  1075. X  */
  1076. X
  1077. Xtypedef struct {
  1078. X    int no_buckets;        /* Number of buckets */
  1079. X    int no_inhab;        /* Number of inhabitants */
  1080. X    int cur_bucket;        /* Used by first&nexthentry() */
  1081. X    int cur_cell;        /* As for cur_bucket */
  1082. X    struct h_cell **thetbl;    /* The table itself */
  1083. X} HASH;                /* A HASH object */
  1084. X
  1085. Xtypedef int KEY;
  1086. X
  1087. Xtypedef struct h_cell {
  1088. X    KEY key;            /* Hash key */
  1089. X    struct h_cell *next;    /* Next bucket pointer */
  1090. X    char data[1];        /* Data starts here - variable size struct */
  1091. X} *HENTRY;            /* A Hash entry (invariant) */
  1092. X
  1093. X/* Hash function */
  1094. X#define h(object, key) (key % object -> no_buckets)
  1095. X
  1096. X/* Functions */
  1097. XHASH *newhash();
  1098. Xvoid rmhash();
  1099. Xchar *lookuphentry();
  1100. XBOOL inserthentry();
  1101. XBOOL rmhentry();
  1102. XHENTRY firsthentry();
  1103. XHENTRY nexthentry();
  1104. END_OF_hash.h
  1105. if test 866 -ne `wc -c <hash.h`; then
  1106.     echo shar: \"hash.h\" unpacked with wrong size!
  1107. fi
  1108. # end of overwriting check
  1109. fi
  1110. if test -f makefile -a "${1}" != "-c" ; then 
  1111.   echo shar: Will not over-write existing file \"makefile\"
  1112. else
  1113. echo shar: Extracting \"makefile\" \(422 characters\)
  1114. sed "s/^X//" >makefile <<'END_OF_makefile'
  1115. X
  1116. XCFLAGS = -O -pipe
  1117. X
  1118. Xdtp: hash.o dtp.o
  1119. X    cc -o dtp hash.o dtp.o
  1120. X
  1121. Xhash.o: hash.c hash.h tool.h
  1122. Xdtp.o: dtp.c hash.h tool.h
  1123. X
  1124. Xinstall:
  1125. X    strip dtp
  1126. X    cp dtp /usr/local/bin/.
  1127. X    cp dtp.man /usr/man/manl/dtp.l
  1128. X    cp dtp.c /usr/local/src/dtp/.
  1129. X    cp hash.c /usr/local/src/dtp/.
  1130. X    cp hash.h /usr/local/src/dtp/.
  1131. X    cp tool.h /usr/local/src/dtp/.
  1132. X    cp makefile /usr/local/src/dtp/.
  1133. X
  1134. Xclean:
  1135. X    rm dtp *.o #*
  1136. X    mv *~ /usr/majestix/exjobb/gorry/back
  1137. X    
  1138. END_OF_makefile
  1139. if test 422 -ne `wc -c <makefile`; then
  1140.     echo shar: \"makefile\" unpacked with wrong size!
  1141. fi
  1142. # end of overwriting check
  1143. fi
  1144. if test -f tool.h -a "${1}" != "-c" ; then 
  1145.   echo shar: Will not over-write existing file \"tool.h\"
  1146. else
  1147. echo shar: Extracting \"tool.h\" \(503 characters\)
  1148. sed "s/^X//" >tool.h <<'END_OF_tool.h'
  1149. X/*
  1150. X  tool.h
  1151. X
  1152. X  Describes system wide conventions, like pointers and general datatypes etc.
  1153. X
  1154. X  OBS! stdio.h must be included before tool.h if system_failure isn't defined.
  1155. X  */
  1156. X
  1157. X#ifndef system_failure
  1158. X#define system_failure(p) fprintf(stderr, "%s\n", p), abort();
  1159. X#endif
  1160. X
  1161. X#define CHKMEM(p, x) if ( !(p) ) { \
  1162. X              char s[40]; \
  1163. X              strcpy(s, x); \
  1164. X              strcat(s, ": out of memory"); \
  1165. X              system_failure(s); \
  1166. X             }
  1167. X
  1168. X/* Boolean datatype */
  1169. X
  1170. Xtypedef short BOOL;
  1171. X#define FALSE 0
  1172. X#define TRUE (!FALSE)
  1173. END_OF_tool.h
  1174. if test 503 -ne `wc -c <tool.h`; then
  1175.     echo shar: \"tool.h\" unpacked with wrong size!
  1176. fi
  1177. # end of overwriting check
  1178. fi
  1179. echo shar: End of shell archive.
  1180. exit 0
  1181.  
  1182.  
  1183.