]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/pic/main.c
rio, kbdfs: increase read buffer for high latency kbdfs support
[plan9front.git] / sys / src / cmd / pic / main.c
1 #include        <stdio.h>
2 #include        <signal.h>
3 #include        <stdlib.h>
4 #include        <string.h>
5 #include        "pic.h"
6 #include        "y.tab.h"
7
8 char    *version = "version July 5, 1993";
9
10 obj     **objlist = 0;          /* store the elements here */
11 int     nobjlist = 0;           /* size of objlist array */
12 int     nobj    = 0;
13
14 Attr    *attr;  /* attributes stored here as collected */
15 int     nattrlist = 0;
16 int     nattr   = 0;    /* number of entries in attr_list */
17
18 Text    *text   = 0;    /* text strings stored here as collected */
19 int     ntextlist = 0;          /* size of text[] array */
20 int     ntext   = 0;
21 int     ntext1  = 0;    /* record ntext here on entry to each figure */
22
23 double  curx    = 0;
24 double  cury    = 0;
25
26 int     hvmode  = R_DIR;        /* R => join left to right, D => top to bottom, etc. */
27
28 int     codegen = 0;    /* 1=>output for this picture; 0=>no output */
29 char    *PEstring;      /* "PS" or "PE" picked up by lexer */
30
31 double  deltx   = 6;    /* max x value in output, for scaling */
32 double  delty   = 6;    /* max y value in output, for scaling */
33 int     dbg     = 0;
34 int     lineno  = 0;
35 char    *filename       = "-";
36 int     synerr  = 0;
37 int     anyerr  = 0;    /* becomes 1 if synerr ever 1 */
38 char    *cmdname;
39
40 double  xmin    = 30000;        /* min values found in actual data */
41 double  ymin    = 30000;
42 double  xmax    = -30000;       /* max */
43 double  ymax    = -30000;
44
45 void    fpecatch(int);
46 void    getdata(void), setdefaults(void);
47 void    setfval(char *, double);
48 int     getpid(void);
49
50 main(int argc, char *argv[])
51 {
52         char buf[20];
53
54         signal(SIGFPE, fpecatch);
55         cmdname = argv[0];
56         while (argc > 1 && *argv[1] == '-') {
57                 switch (argv[1][1]) {
58                 case 'd':
59                         dbg = atoi(&argv[1][2]);
60                         if (dbg == 0)
61                                 dbg = 1;
62                         fprintf(stderr, "%s\n", version);
63                         break;
64                 case 'V':
65                         fprintf(stderr, "%s\n", version);
66                         return 0;
67                 }
68                 argc--;
69                 argv++;
70         }
71         setdefaults();
72         objlist = (obj **) grow((char *)objlist, "objlist", nobjlist += 1000, sizeof(obj *));
73         text = (Text *) grow((char *)text, "text", ntextlist += 1000, sizeof(Text));
74         attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));
75
76         sprintf(buf, "/%d/", getpid());
77         pushsrc(String, buf);
78         definition("pid");
79
80         curfile = infile;
81         pushsrc(File, curfile->fname);
82         if (argc <= 1) {
83                 curfile->fin = stdin;
84                 curfile->fname = tostring("-");
85                 getdata();
86         } else
87                 while (argc-- > 1) {
88                         if ((curfile->fin = fopen(*++argv, "r")) == NULL) {
89                                 fprintf(stderr, "%s: can't open %s\n", cmdname, *argv);
90                                 exit(1);
91                         }
92                         curfile->fname = tostring(*argv);
93                         getdata();
94                         fclose(curfile->fin);
95                         free(curfile->fname);
96                 }
97         return anyerr;
98 }
99
100 void fpecatch(int n)
101 {
102         ERROR "floating point exception %d", n FATAL;
103 }
104
105 char *grow(char *ptr, char *name, int num, int size)    /* make array bigger */
106 {
107         char *p;
108
109         if (ptr == NULL)
110                 p = malloc(num * size);
111         else
112                 p = realloc(ptr, num * size);
113         if (p == NULL)
114                 ERROR "can't grow %s to %d", name, num * size FATAL;
115         return p;
116 }
117
118 static struct {
119         char *name;
120         double val;
121         short scalable;         /* 1 => adjust when "scale" changes */
122 } defaults[] ={
123         "scale", SCALE, 1,
124         "lineht", HT, 1,
125         "linewid", HT, 1,
126         "moveht", HT, 1,
127         "movewid", HT, 1,
128         "dashwid", HT10, 1,
129         "boxht", HT, 1,
130         "boxwid", WID, 1,
131         "circlerad", HT2, 1,
132         "arcrad", HT2, 1,
133         "ellipseht", HT, 1,
134         "ellipsewid", WID, 1,
135         "arrowht", HT5, 1,
136         "arrowwid", HT10, 1,
137         "arrowhead", 2, 0,              /* arrowhead style */
138         "textht", 0.0, 1,               /* 6 lines/inch is also a useful value */
139         "textwid", 0.0, 1,
140         "maxpsht", MAXHT, 0,
141         "maxpswid", MAXWID, 0,
142         "fillval", 0.7, 0,              /* gray value for filling boxes */
143         NULL, 0, 0
144 };
145
146 void setdefaults(void)  /* set default sizes for variables like boxht */
147 {
148         int i;
149         YYSTYPE v;
150
151         for (i = 0; defaults[i].name != NULL; i++) {
152                 v.f = defaults[i].val;
153                 makevar(tostring(defaults[i].name), VARNAME, v);
154         }
155 }
156
157 void resetvar(void)     /* reset variables listed */
158 {
159         int i, j;
160
161         if (nattr == 0) {       /* none listed, so do all */
162                 setdefaults();
163                 return;
164         }
165         for (i = 0; i < nattr; i++) {
166                 for (j = 0; defaults[j].name != NULL; j++)
167                         if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) {
168                                 setfval(defaults[j].name, defaults[j].val);
169                                 free(attr[i].a_val.p);
170                                 break;
171                         }
172         }
173 }
174
175 void checkscale(char *s)        /* if s is "scale", adjust default variables */
176 {
177         int i;
178         double scale;
179
180         if (strcmp(s, "scale") == 0) {
181                 scale = getfval("scale");
182                 for (i = 1; defaults[i].name != NULL; i++)
183                         if (defaults[i].scalable)
184                                 setfval(defaults[i].name, defaults[i].val * scale);
185         }
186 }
187
188 void getdata(void)
189 {
190         char *p, buf[1000], buf1[100];
191         int ln;
192         void reset(void), openpl(char *), closepl(char *), print(void);
193         int yyparse(void);
194
195         curfile->lineno = 0;
196         printlf(1, curfile->fname);
197         while (fgets(buf, sizeof buf, curfile->fin) != NULL) {
198                 curfile->lineno++;
199                 if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') {
200                         for (p = &buf[3]; *p == ' '; p++)
201                                 ;
202                         if (*p++ == '<') {
203                                 Infile svfile;
204                                 svfile = *curfile;
205                                 sscanf(p, "%s", buf1);
206                                 if ((curfile->fin=fopen(buf1, "r")) == NULL)
207                                         ERROR "can't open %s", buf1 FATAL;
208                                 curfile->fname = tostring(buf1);
209                                 getdata();
210                                 fclose(curfile->fin);
211                                 free(curfile->fname);
212                                 *curfile = svfile;
213                                 printlf(curfile->lineno, curfile->fname);
214                                 continue;
215                         }
216                         reset();
217                         yyparse();
218                         anyerr += synerr;
219                         deltx = (xmax - xmin) / getfval("scale");
220                         delty = (ymax - ymin) / getfval("scale");
221                         if (buf[3] == ' ') {    /* next things are wid & ht */
222                                 if (sscanf(&buf[4],"%lf %lf", &deltx, &delty) < 2)
223                                         delty = deltx * (ymax-ymin) / (xmax-xmin);
224                                 /* else {
225                                 /*      double xfac, yfac; */
226                                 /*      xfac = deltx / (xmax-xmin);
227                                 /*      yfac = delty / (ymax-ymin);
228                                 /*      if (xfac <= yfac)
229                                 /*              delty = xfac * (ymax-ymin);
230                                 /*      else
231                                 /*              deltx = yfac * (xmax-xmin);
232                                 /*}
233                                 */
234                         }
235                         dprintf("deltx = %g, delty = %g\n", deltx, delty);
236                         if (codegen && !synerr) {
237                                 openpl(&buf[3]);        /* puts out .PS, with ht & wid stuck in */
238                                 printlf(curfile->lineno+1, NULL);
239                                 print();        /* assumes \n at end */
240                                 closepl(PEstring);      /* does the .PE/F */
241                                 free(PEstring);
242                         }
243                         printlf(curfile->lineno+1, NULL);
244                         fflush(stdout);
245                 } else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') {
246                         if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) {
247                                 free(curfile->fname);
248                                 printlf(curfile->lineno = ln, curfile->fname = tostring(buf1));
249                         } else
250                                 printlf(curfile->lineno = ln, NULL);
251                 } else
252                         fputs(buf, stdout);
253         }
254 }
255
256 void reset(void)
257 {
258         obj *op;
259         int i;
260         extern int nstack;
261         extern  void freesymtab(struct symtab *);
262
263         for (i = 0; i < nobj; i++) {
264                 op = objlist[i];
265                 if (op->o_type == BLOCK)
266                         freesymtab(op->o_symtab);
267                 free((char *)objlist[i]);
268         }
269         nobj = 0;
270         nattr = 0;
271         for (i = 0; i < ntext; i++)
272                 if (text[i].t_val)
273                         free(text[i].t_val);
274         ntext = ntext1 = 0;
275         codegen = synerr = 0;
276         nstack = 0;
277         curx = cury = 0;
278         PEstring = 0;
279         hvmode = R_DIR;
280         xmin = ymin = 30000;
281         xmax = ymax = -30000;
282 }