home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume2 / tdp < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  27.0 KB

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