devutf: add unicode aliases for accented characters
[troff.git] / pic / main.c
blob62afbe527de512578926926d0a22e9b45ed29936
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"
8 char *version = "version July 5, 1993";
10 obj **objlist = 0; /* store the elements here */
11 int nobjlist = 0; /* size of objlist array */
12 int nobj = 0;
14 Attr *attr; /* attributes stored here as collected */
15 int nattrlist = 0;
16 int nattr = 0; /* number of entries in attr_list */
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 */
23 double curx = 0;
24 double cury = 0;
26 int hvmode = R_DIR; /* R => join left to right, D => top to bottom, etc. */
28 int codegen = 0; /* 1=>output for this picture; 0=>no output */
29 char *PEstring; /* "PS" or "PE" picked up by lexer */
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;
40 double xmin = 30000; /* min values found in actual data */
41 double ymin = 30000;
42 double xmax = -30000; /* max */
43 double ymax = -30000;
45 void fpecatch(int);
46 void getdata(void), setdefaults(void);
47 void setfval(char *, double);
48 int getpid(void);
50 int main(int argc, char *argv[])
52 char buf[20];
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;
68 argc--;
69 argv++;
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));
76 sprintf(buf, "/%d/", getpid());
77 pushsrc(String, buf);
78 definition("pid");
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);
92 curfile->fname = tostring(*argv);
93 getdata();
94 fclose(curfile->fin);
95 free(curfile->fname);
97 return anyerr;
100 void fpecatch(int n)
102 ERROR "floating point exception %d", n FATAL;
105 char *grow(char *ptr, char *name, int num, int size) /* make array bigger */
107 char *p;
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;
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
146 void setdefaults(void) /* set default sizes for variables like boxht */
148 int i;
149 YYSTYPE v;
151 for (i = 0; defaults[i].name != NULL; i++) {
152 v.f = defaults[i].val;
153 makevar(tostring(defaults[i].name), VARNAME, v);
157 void resetvar(void) /* reset variables listed */
159 int i, j;
161 if (nattr == 0) { /* none listed, so do all */
162 setdefaults();
163 return;
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;
175 void checkscale(char *s) /* if s is "scale", adjust default variables */
177 int i;
178 double scale;
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);
188 void getdata(void)
190 char *p, buf[1000], buf1[100];
191 int ln;
192 void reset(void), openpl(char *), closepl(char *), print(void);
193 int yyparse(void);
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++)
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;
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);
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);
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);
256 void reset(void)
258 obj *op;
259 int i;
260 extern int nstack;
261 extern void freesymtab(struct symtab *);
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]);
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;