print.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <ctype.h>
  6. #include "grap.h"
  7. #include "y.tab.h"
  8. double margin = MARGIN; /* extra space around edges */
  9. extern double frame_ht, frame_wid, ticklen;
  10. extern int just, sizeop, tick_dir;
  11. extern double sizexpr, lab_up, lab_rt;
  12. char graphname[50] = "Graph";
  13. char graphpos[200] = "";
  14. void print(void) /* arrange final output */
  15. {
  16. FILE *fd;
  17. Obj *p, *dfp;
  18. int c;
  19. double dx, dy, xfac, yfac;
  20. if (tfd != NULL) {
  21. fclose(tfd); /* end the temp file */
  22. tfd = stdout;
  23. }
  24. if ((p=lookup("margin",0)) != NULL)
  25. margin = p->fval;
  26. if (frame_ht < 0) /* wasn't set explicitly, so use default */
  27. frame_ht = getvar(lookup("frameht", 0));
  28. if (frame_wid < 0)
  29. frame_wid = getvar(lookup("framewid", 0));
  30. dfp = NULL;
  31. for (p = objlist; p; p = p->next) {
  32. dprintf("print: name = <%s>, type = %d\n", p->name, p->type);
  33. if (p->type == NAME) {
  34. Point pt, pt1;
  35. pt = p->pt;
  36. pt1 = p->pt1;
  37. fprintf(tfd, "\t# %s %g .. %g, %g .. %g\n",
  38. p->name, pt.x, pt1.x, pt.y, pt1.y);
  39. if (p->log & XFLAG) {
  40. if (pt.x <= 0.0)
  41. ERROR "can't take log of x coord %g", pt.x FATAL;
  42. logit(pt.x);
  43. logit(pt1.x);
  44. }
  45. if (p->log & YFLAG) {
  46. if (pt.y <= 0.0)
  47. ERROR "can't take log of y coord %g", pt.y FATAL;
  48. logit(pt.y);
  49. logit(pt1.y);
  50. }
  51. if (!(p->coord & XFLAG)) {
  52. dx = pt1.x - pt.x;
  53. pt.x -= margin * dx;
  54. pt1.x += margin * dx;
  55. }
  56. if (!(p->coord & YFLAG)) {
  57. dy = pt1.y - pt.y;
  58. pt.y -= margin * dy;
  59. pt1.y += margin * dy;
  60. }
  61. if (autoticks && strcmp(p->name, dflt_coord) == 0) {
  62. p->pt = pt;
  63. p->pt1 = pt1;
  64. if (p->log & XFLAG) {
  65. p->pt.x = pow(10.0, pt.x);
  66. p->pt1.x = pow(10.0, pt1.x);
  67. }
  68. if (p->log & YFLAG) {
  69. p->pt.y = pow(10.0, pt.y);
  70. p->pt1.y = pow(10.0, pt1.y);
  71. }
  72. dfp = setauto();
  73. }
  74. dx = pt1.x - pt.x;
  75. dy = pt1.y - pt.y;
  76. xfac = dx > 0 ? frame_wid/dx : frame_wid/2;
  77. yfac = dy > 0 ? frame_ht/dy : frame_ht/2;
  78. fprintf(tfd, "define xy_%s @ ", p->name);
  79. if (dx > 0)
  80. fprintf(tfd, "\t(($1)-(%g))*%g", pt.x, xfac);
  81. else
  82. fprintf(tfd, "\t%g", xfac);
  83. if (dy > 0)
  84. fprintf(tfd, ", (($2)-(%g))*%g @\n", pt.y, yfac);
  85. else
  86. fprintf(tfd, ", %g @\n", yfac);
  87. fprintf(tfd, "define x_%s @ ", p->name);
  88. if (dx > 0)
  89. fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.x, xfac);
  90. else
  91. fprintf(tfd, "\t%g @\n", xfac);
  92. fprintf(tfd, "define y_%s @ ", p->name);
  93. if (dy > 0)
  94. fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.y, yfac);
  95. else
  96. fprintf(tfd, "\t%g @\n", yfac);
  97. }
  98. }
  99. if (codegen)
  100. frame();
  101. if (codegen && autoticks && dfp)
  102. do_autoticks(dfp);
  103. if ((fd = fopen(tempfile, "r")) != NULL) {
  104. while ((c = getc(fd)) != EOF)
  105. putc(c, tfd);
  106. fclose(fd);
  107. }
  108. tfd = NULL;
  109. }
  110. void endstat(void) /* clean up after each statement */
  111. {
  112. just = sizeop = 0;
  113. lab_up = lab_rt = 0.0;
  114. sizexpr = 0.0;
  115. nnum = 0;
  116. ntick = 0;
  117. tside = 0;
  118. tick_dir = OUT;
  119. ticklen = TICKLEN;
  120. }
  121. void graph(char *s) /* graph statement */
  122. {
  123. char *p, *os;
  124. int c;
  125. if (codegen) {
  126. fprintf(stdout, "%s: [\n", graphname);
  127. print(); /* pump out previous graph */
  128. fprintf(stdout, "\n] %s\n", graphpos);
  129. reset();
  130. }
  131. if (s) {
  132. dprintf("into graph with <%s>\n", s);
  133. opentemp();
  134. os = s;
  135. while ((c = *s) == ' ' || c == '\t')
  136. s++;
  137. if (c == '\0')
  138. ERROR "no name on graph statement" WARNING;
  139. if (!isupper(s[0]))
  140. ERROR "graph name %s must be capitalized", s WARNING;
  141. for (p=graphname; (c = *s) != ' ' && c != '\t' && c != '\0'; )
  142. *p++ = *s++;
  143. *p = '\0';
  144. strcpy(graphpos, s);
  145. dprintf("graphname = <%s>, graphpos = <%s>\n", graphname, graphpos);
  146. free(os);
  147. }
  148. }
  149. void setup(void) /* done at each .G1 */
  150. {
  151. static int firstG1 = 0;
  152. reset();
  153. opentemp();
  154. frame_ht = frame_wid = -1; /* reset in frame() */
  155. ticklen = getvar(lookup("ticklen", 0));
  156. if (firstG1++ == 0)
  157. do_first();
  158. codegen = synerr = 0;
  159. strcpy(graphname, "Graph");
  160. strcpy(graphpos, "");
  161. }
  162. void do_first(void) /* done at first .G1: definitions, etc. */
  163. {
  164. extern int lib;
  165. extern char *lib_defines;
  166. static char buf[50], buf1[50]; /* static because pbstr uses them */
  167. FILE *fp;
  168. extern int getpid(void);
  169. sprintf(buf, "define pid /%d/\n", getpid());
  170. pbstr(buf);
  171. if (lib != 0) {
  172. if ((fp = fopen(lib_defines, "r")) != NULL) {
  173. sprintf(buf1, "copy \"%s\"\n", lib_defines);
  174. pbstr(buf1);
  175. fclose(fp);
  176. } else {
  177. fprintf(stderr, "grap warning: can't open %s\n", lib_defines);
  178. }
  179. }
  180. }
  181. void reset(void) /* done at each "graph ..." statement */
  182. {
  183. Obj *p, *np, *deflist;
  184. extern int tlist, toffside, autodir;
  185. curr_coord = dflt_coord;
  186. ncoord = auto_x = 0;
  187. autoticks = LEFT|BOT;
  188. autodir = 0;
  189. tside = tlist = toffside = 0;
  190. tick_dir = OUT;
  191. margin = MARGIN;
  192. deflist = NULL;
  193. for (p = objlist; p; p = np) {
  194. np = p->next;
  195. if (p->type == DEFNAME || p->type == VARNAME) {
  196. p->next = deflist;
  197. deflist = p;
  198. } else {
  199. free(p->name);
  200. freeattr(p->attr);
  201. free((char *) p);
  202. }
  203. }
  204. objlist = deflist;
  205. }
  206. void opentemp(void)
  207. {
  208. if (tfd != NULL)
  209. fclose(tfd);
  210. if (tfd != stdout) {
  211. if (tfd != NULL)
  212. fclose(tfd);
  213. if ((tfd = fopen(tempfile, "w")) == NULL) {
  214. fprintf(stderr, "grap: can't open %s\n", tempfile);
  215. exit(1);
  216. }
  217. }
  218. }