/contrib/groff/src/devices/xditview/parse.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 366 lines · 309 code · 30 blank · 27 comment · 50 complexity · 467aadd827aa1e57c11102ca9f6946f1 MD5 · raw file

  1. /*
  2. * parse.c
  3. *
  4. * parse dvi input
  5. */
  6. #include <X11/Xos.h>
  7. #include <X11/IntrinsicP.h>
  8. #include <X11/StringDefs.h>
  9. #include <stdio.h>
  10. #include <ctype.h>
  11. #include "DviP.h"
  12. static int StopSeen = 0;
  13. static void ParseDrawFunction(DviWidget, char *);
  14. static void ParseDeviceControl(DviWidget);
  15. static void push_env(DviWidget);
  16. static void pop_env(DviWidget);
  17. /* draw.c */
  18. extern int PutCharacter(DviWidget, char *);
  19. extern int PutNumberedCharacter(DviWidget, int);
  20. extern void HorizontalGoto(DviWidget, int);
  21. extern void Word(DviWidget);
  22. extern void VerticalGoto(DviWidget, int);
  23. extern void VerticalMove(DviWidget, int);
  24. extern void FlushCharCache(DviWidget);
  25. extern void Newline(DviWidget);
  26. extern void DrawLine(DviWidget, int, int);
  27. extern void DrawCircle(DviWidget, int);
  28. extern void DrawFilledCircle(DviWidget, int);
  29. extern void DrawEllipse(DviWidget, int, int);
  30. extern void DrawFilledEllipse(DviWidget, int, int);
  31. extern void DrawArc(DviWidget, int, int, int, int);
  32. extern void DrawPolygon(DviWidget, int *, int);
  33. extern void DrawFilledPolygon(DviWidget, int *, int);
  34. extern void DrawSpline(DviWidget, int *, int);
  35. /* Dvi.c */
  36. extern void SetDevice(DviWidget, const char *);
  37. /* page.c */
  38. extern void RememberPagePosition(DviWidget, int);
  39. /* font.c */
  40. extern void SetFontPosition(DviWidget, int, const char *, const char *);
  41. /* lex.c */
  42. extern int GetNumber(DviWidget);
  43. #define HorizontalMove(dw, delta) ((dw)->dvi.state->x += (delta))
  44. int
  45. ParseInput(register DviWidget dw)
  46. {
  47. int n, k;
  48. int c;
  49. char Buffer[BUFSIZ];
  50. int NextPage;
  51. int otherc;
  52. StopSeen = 0;
  53. /*
  54. * make sure some state exists
  55. */
  56. if (!dw->dvi.state)
  57. push_env (dw);
  58. for (;;) {
  59. switch (DviGetC(dw, &c)) {
  60. case '\n':
  61. break;
  62. case ' ': /* when input is text */
  63. case 0: /* occasional noise creeps in */
  64. break;
  65. case '{': /* push down current environment */
  66. push_env(dw);
  67. break;
  68. case '}':
  69. pop_env(dw);
  70. break;
  71. /*
  72. * two motion digits plus a character
  73. */
  74. case '0': case '1': case '2': case '3': case '4':
  75. case '5': case '6': case '7': case '8': case '9':
  76. HorizontalMove(dw, (c-'0')*10 +
  77. DviGetC(dw,&otherc)-'0');
  78. /* fall through */
  79. case 'c': /* single ascii character */
  80. DviGetC(dw,&c);
  81. if (c == ' ')
  82. break;
  83. Buffer[0] = c;
  84. Buffer[1] = '\0';
  85. (void) PutCharacter (dw, Buffer);
  86. break;
  87. case 'C':
  88. GetWord (dw, Buffer, BUFSIZ);
  89. (void) PutCharacter (dw, Buffer);
  90. break;
  91. case 't':
  92. Buffer[1] = '\0';
  93. while (DviGetC (dw, &c) != EOF
  94. && c != ' ' && c != '\n') {
  95. Buffer[0] = c;
  96. HorizontalMove (dw, PutCharacter (dw, Buffer));
  97. }
  98. break;
  99. case 'u':
  100. n = GetNumber(dw);
  101. Buffer[1] = '\0';
  102. while (DviGetC (dw, &c) == ' ')
  103. ;
  104. while (c != EOF && c != ' ' && c != '\n') {
  105. Buffer[0] = c;
  106. HorizontalMove (dw,
  107. PutCharacter (dw, Buffer) + n);
  108. DviGetC (dw, &c);
  109. }
  110. break;
  111. case 'D': /* draw function */
  112. (void) GetLine(dw, Buffer, BUFSIZ);
  113. if (dw->dvi.display_enable)
  114. ParseDrawFunction(dw, Buffer);
  115. break;
  116. case 's': /* ignore fractional sizes */
  117. n = GetNumber(dw);
  118. dw->dvi.state->font_size = n;
  119. break;
  120. case 'f':
  121. n = GetNumber(dw);
  122. dw->dvi.state->font_number = n;
  123. break;
  124. case 'H': /* absolute horizontal motion */
  125. k = GetNumber(dw);
  126. HorizontalGoto(dw, k);
  127. break;
  128. case 'h': /* relative horizontal motion */
  129. k = GetNumber(dw);
  130. HorizontalMove(dw, k);
  131. break;
  132. case 'w': /* word space */
  133. Word (dw);
  134. break;
  135. case 'V':
  136. n = GetNumber(dw);
  137. VerticalGoto(dw, n);
  138. break;
  139. case 'v':
  140. n = GetNumber(dw);
  141. VerticalMove(dw, n);
  142. break;
  143. case 'P': /* new spread */
  144. break;
  145. case 'p': /* new page */
  146. (void) GetNumber(dw);
  147. NextPage = dw->dvi.current_page + 1;
  148. RememberPagePosition(dw, NextPage);
  149. FlushCharCache (dw);
  150. return(NextPage);
  151. case 'N':
  152. n = GetNumber(dw);
  153. PutNumberedCharacter (dw, n);
  154. break;
  155. case 'n': /* end of line */
  156. GetNumber(dw);
  157. GetNumber(dw);
  158. Newline (dw);
  159. HorizontalGoto(dw, 0);
  160. break;
  161. case 'F': /* input files */
  162. case '+': /* continuation of X device control */
  163. case 'm': /* color */
  164. case '#': /* comment */
  165. GetLine(dw, NULL, 0);
  166. break;
  167. case 'x': /* device control */
  168. ParseDeviceControl(dw);
  169. break;
  170. case EOF:
  171. dw->dvi.last_page = dw->dvi.current_page;
  172. FlushCharCache (dw);
  173. return dw->dvi.current_page;
  174. default:
  175. break;
  176. }
  177. }
  178. }
  179. static void
  180. push_env(DviWidget dw)
  181. {
  182. DviState *new_state;
  183. new_state = (DviState *) XtMalloc (sizeof (*new_state));
  184. if (dw->dvi.state)
  185. *new_state = *(dw->dvi.state);
  186. else {
  187. new_state->font_size = 10;
  188. new_state->font_number = 1;
  189. new_state->x = 0;
  190. new_state->y = 0;
  191. }
  192. new_state->next = dw->dvi.state;
  193. dw->dvi.state = new_state;
  194. }
  195. static void
  196. pop_env(DviWidget dw)
  197. {
  198. DviState *old;
  199. old = dw->dvi.state;
  200. dw->dvi.state = old->next;
  201. XtFree ((char *) old);
  202. }
  203. static void
  204. InitTypesetter (DviWidget dw)
  205. {
  206. while (dw->dvi.state)
  207. pop_env (dw);
  208. push_env (dw);
  209. FlushCharCache (dw);
  210. }
  211. #define DRAW_ARGS_MAX 128
  212. static void
  213. ParseDrawFunction(DviWidget dw, char *buf)
  214. {
  215. int v[DRAW_ARGS_MAX];
  216. int i, no_move = 0;
  217. char *ptr;
  218. v[0] = v[1] = v[2] = v[3] = 0;
  219. if (buf[0] == '\0')
  220. return;
  221. ptr = buf+1;
  222. for (i = 0; i < DRAW_ARGS_MAX; i++) {
  223. if (sscanf(ptr, "%d", v + i) != 1)
  224. break;
  225. while (*ptr == ' ')
  226. ptr++;
  227. while (*ptr != '\0' && *ptr != ' ')
  228. ptr++;
  229. }
  230. switch (buf[0]) {
  231. case 'l': /* draw a line */
  232. DrawLine(dw, v[0], v[1]);
  233. break;
  234. case 'c': /* circle */
  235. DrawCircle(dw, v[0]);
  236. break;
  237. case 'C':
  238. DrawFilledCircle(dw, v[0]);
  239. break;
  240. case 'e': /* ellipse */
  241. DrawEllipse(dw, v[0], v[1]);
  242. break;
  243. case 'E':
  244. DrawFilledEllipse(dw, v[0], v[1]);
  245. break;
  246. case 'a': /* arc */
  247. DrawArc(dw, v[0], v[1], v[2], v[3]);
  248. break;
  249. case 'p':
  250. DrawPolygon(dw, v, i);
  251. break;
  252. case 'P':
  253. DrawFilledPolygon(dw, v, i);
  254. break;
  255. case '~': /* wiggly line */
  256. DrawSpline(dw, v, i);
  257. break;
  258. case 't':
  259. dw->dvi.line_thickness = v[0];
  260. break;
  261. case 'f':
  262. if (i > 0 && v[0] >= 0 && v[0] <= DVI_FILL_MAX)
  263. dw->dvi.fill = v[0];
  264. no_move = 1;
  265. break;
  266. default:
  267. #if 0
  268. warning("unknown drawing function %s", buf);
  269. #endif
  270. no_move = 1;
  271. break;
  272. }
  273. if (!no_move) {
  274. if (buf[0] == 'e') {
  275. if (i > 0)
  276. dw->dvi.state->x += v[0];
  277. }
  278. else {
  279. while (--i >= 0) {
  280. if (i & 1)
  281. dw->dvi.state->y += v[i];
  282. else
  283. dw->dvi.state->x += v[i];
  284. }
  285. }
  286. }
  287. }
  288. static void
  289. ParseDeviceControl(DviWidget dw) /* Parse the x commands */
  290. {
  291. char str[20], str1[50];
  292. int c, n;
  293. GetWord (dw, str, 20);
  294. switch (str[0]) { /* crude for now */
  295. case 'T': /* output device */
  296. GetWord (dw, str, 20);
  297. SetDevice (dw, str);
  298. break;
  299. case 'i': /* initialize */
  300. InitTypesetter (dw);
  301. break;
  302. case 't': /* trailer */
  303. break;
  304. case 'p': /* pause -- can restart */
  305. break;
  306. case 's': /* stop */
  307. StopSeen = 1;
  308. return;
  309. case 'r': /* resolution when prepared */
  310. break;
  311. case 'f': /* font used */
  312. n = GetNumber (dw);
  313. GetWord (dw, str, 20);
  314. GetLine (dw, str1, 50);
  315. SetFontPosition (dw, n, str, str1);
  316. break;
  317. case 'H': /* char height */
  318. break;
  319. case 'S': /* slant */
  320. break;
  321. }
  322. while (DviGetC (dw, &c) != '\n') /* skip rest of input line */
  323. if (c == EOF)
  324. return;
  325. return;
  326. }
  327. /*
  328. Local Variables:
  329. c-indent-level: 8
  330. c-continued-statement-offset: 8
  331. c-brace-offset: -8
  332. c-argdecl-indent: 8
  333. c-label-offset: -8
  334. c-tab-always-indent: nil
  335. End:
  336. */