1
0

n2.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * n2.c
  11. *
  12. * output, cleanup
  13. */
  14. #include "tdef.h"
  15. #include "fns.h"
  16. #include "ext.h"
  17. #include <setjmp.h>
  18. #ifdef STRICT
  19. /* not in ANSI or POSIX */
  20. FILE* popen(char*, char*);
  21. #endif
  22. extern jmp_buf sjbuf;
  23. int toolate;
  24. int error;
  25. char obuf[2*BUFSIZ];
  26. char *obufp = obuf;
  27. /* pipe command structure; allows redicously long commends for .pi */
  28. struct Pipe {
  29. char *buf;
  30. int tick;
  31. int cnt;
  32. } Pipe;
  33. int xon = 0; /* records if in middle of \X */
  34. int pchar(Tchar i)
  35. {
  36. int j;
  37. static int hx = 0; /* records if have seen HX */
  38. if (hx) {
  39. hx = 0;
  40. j = absmot(i);
  41. if (isnmot(i)) {
  42. if (j > dip->blss)
  43. dip->blss = j;
  44. } else {
  45. if (j > dip->alss)
  46. dip->alss = j;
  47. ralss = dip->alss;
  48. }
  49. return 0;
  50. }
  51. if (ismot(i)) {
  52. pchar1(i);
  53. return 0;
  54. }
  55. switch (j = cbits(i)) {
  56. case 0:
  57. case IMP:
  58. case RIGHT:
  59. case LEFT:
  60. return 0;
  61. case HX:
  62. hx = 1;
  63. return 0;
  64. case XON:
  65. xon++;
  66. break;
  67. case XOFF:
  68. xon--;
  69. break;
  70. case PRESC:
  71. if (!xon && !tflg && dip == &d[0])
  72. j = eschar; /* fall through */
  73. default:
  74. setcbits(i, trtab[j]);
  75. }
  76. if (NROFF & xon) /* rob fix for man2html */
  77. return 0;
  78. pchar1(i);
  79. return 0;
  80. }
  81. void pchar1(Tchar i)
  82. {
  83. int j;
  84. j = cbits(i);
  85. if (dip != &d[0]) {
  86. wbf(i);
  87. dip->op = offset;
  88. return;
  89. }
  90. if (!tflg && !print) {
  91. if (j == '\n')
  92. dip->alss = dip->blss = 0;
  93. return;
  94. }
  95. if (j == FILLER && !xon)
  96. return;
  97. if (tflg) { /* transparent mode, undiverted */
  98. if (print) /* assumes that it's ok to print */
  99. /* OUT "%c", j PUT; /* i.e., is ascii */
  100. outascii(i);
  101. return;
  102. }
  103. if (TROFF && ascii)
  104. outascii(i);
  105. else
  106. ptout(i);
  107. }
  108. void outweird(int k) /* like ptchname() but ascii */
  109. {
  110. char *chn = chname(k);
  111. switch (chn[0]) {
  112. case MBchar:
  113. OUT "%s", chn+1 PUT; /* \n not needed? */
  114. break;
  115. case Number:
  116. OUT "\\N'%s'", chn+1 PUT;
  117. break;
  118. case Troffchar:
  119. if (strlen(chn+1) == 2)
  120. OUT "\\(%s", chn+1 PUT;
  121. else
  122. OUT "\\C'%s'", chn+1 PUT;
  123. break;
  124. default:
  125. OUT " %s? ", chn PUT;
  126. break;
  127. }
  128. }
  129. void outascii(Tchar i) /* print i in best-guess ascii */
  130. {
  131. int j = cbits(i);
  132. /* is this ever called with NROFF set? probably doesn't work at all. */
  133. if (ismot(i))
  134. oput(' ');
  135. else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t')
  136. oput(j);
  137. else if (j == DRAWFCN)
  138. oputs("\\D");
  139. else if (j == HYPHEN)
  140. oput('-');
  141. else if (j == MINUS) /* special pleading for strange encodings */
  142. oputs("\\-");
  143. else if (j == PRESC)
  144. oputs("\\e");
  145. else if (j == FILLER)
  146. oputs("\\&");
  147. else if (j == UNPAD)
  148. oputs("\\ ");
  149. else if (j == OHC) /* this will never occur; stripped out earlier */
  150. oputs("\\%");
  151. else if (j == XON)
  152. oputs("\\X");
  153. else if (j == XOFF)
  154. oputs(" ");
  155. else if (j == LIG_FI)
  156. oputs("fi");
  157. else if (j == LIG_FL)
  158. oputs("fl");
  159. else if (j == LIG_FF)
  160. oputs("ff");
  161. else if (j == LIG_FFI)
  162. oputs("ffi");
  163. else if (j == LIG_FFL)
  164. oputs("ffl");
  165. else if (j == WORDSP) { /* nothing at all */
  166. if (xon) /* except in \X */
  167. oput(' ');
  168. } else
  169. outweird(j);
  170. }
  171. int flusho(void)
  172. {
  173. if (NROFF && !toolate && t.twinit)
  174. fwrite(t.twinit, strlen(t.twinit), 1, ptid);
  175. if (obufp > obuf) {
  176. if (pipeflg && !toolate) {
  177. /* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */
  178. if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL)
  179. ERROR "pipe %s not created.", Pipe.buf WARN;
  180. if (Pipe.buf)
  181. free(Pipe.buf);
  182. }
  183. if (!toolate)
  184. toolate++;
  185. *obufp = 0;
  186. fputs(obuf, ptid);
  187. fflush(ptid);
  188. obufp = obuf;
  189. }
  190. return 1;
  191. }
  192. void caseex(void)
  193. {
  194. done(0);
  195. }
  196. void done(int x)
  197. {
  198. int i;
  199. error |= x;
  200. app = ds = lgf = 0;
  201. if (i = em) {
  202. donef = -1;
  203. eschar = '\\';
  204. em = 0;
  205. if (control(i, 0))
  206. longjmp(sjbuf, 1);
  207. }
  208. if (!nfo)
  209. done3(0);
  210. mflg = 0;
  211. dip = &d[0];
  212. if (woff) /* BUG!!! This isn't set anywhere */
  213. wbf((Tchar)0);
  214. if (pendw)
  215. getword(1);
  216. pendnf = 0;
  217. if (donef == 1)
  218. done1(0);
  219. donef = 1;
  220. ip = 0;
  221. frame = stk;
  222. nxf = frame + 1;
  223. if (!ejf)
  224. tbreak();
  225. nflush++;
  226. eject((Stack *)0);
  227. longjmp(sjbuf, 1);
  228. }
  229. void done1(int x)
  230. {
  231. error |= x;
  232. if (numtabp[NL].val) {
  233. trap = 0;
  234. eject((Stack *)0);
  235. longjmp(sjbuf, 1);
  236. }
  237. if (!ascii)
  238. pttrailer();
  239. done2(0);
  240. }
  241. void done2(int x)
  242. {
  243. ptlead();
  244. if (TROFF && !ascii)
  245. ptstop();
  246. flusho();
  247. done3(x);
  248. }
  249. void done3(int x)
  250. {
  251. error |= x;
  252. flusho();
  253. if (NROFF)
  254. twdone();
  255. if (pipeflg)
  256. pclose(ptid);
  257. exit(error);
  258. }
  259. void edone(int x)
  260. {
  261. frame = stk;
  262. nxf = frame + 1;
  263. ip = 0;
  264. done(x);
  265. }
  266. void casepi(void)
  267. {
  268. int j;
  269. char buf[NTM];
  270. if (Pipe.buf == NULL) {
  271. if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) {
  272. ERROR "No buf space for pipe cmd" WARN;
  273. return;
  274. }
  275. Pipe.tick = 1;
  276. } else
  277. Pipe.buf[Pipe.cnt++] = '|';
  278. getline(buf, NTM);
  279. j = strlen(buf);
  280. if (toolate) {
  281. ERROR "Cannot create pipe to %s", buf WARN;
  282. return;
  283. }
  284. Pipe.cnt += j;
  285. if (j >= NTM +1) {
  286. Pipe.tick++;
  287. if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) {
  288. ERROR "No more buf space for pipe cmd" WARN;
  289. return;
  290. }
  291. }
  292. strcat(Pipe.buf, buf);
  293. pipeflg++;
  294. }