No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / groff / src / preproc / grn / hdb.cpp
blob8ac9f5b347ad3ed835fd775a14c593ade3cfaf83
1 /* $NetBSD$ */
3 /* Last non-groff version: hdb.c 1.8 (Berkeley) 84/10/20
5 * Copyright -C- 1982 Barry S. Roitblat
7 * This file contains database routines for the hard copy programs of the
8 * gremlin picture editor.
9 */
11 #include "gprint.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
16 #include "errarg.h"
17 #include "error.h"
19 #define MAXSTRING 128
20 #define MAXSTRING_S "127"
22 /* imports from main.cpp */
24 extern int linenum; /* current line number in input file */
25 extern char gremlinfile[]; /* name of file currently reading */
26 extern int SUNFILE; /* TRUE if SUN gremlin file */
27 extern int compatibility_flag; /* TRUE if in compatibility mode */
28 extern void savebounds(double x, double y);
30 /* imports from hpoint.cpp */
32 extern POINT *PTInit();
33 extern POINT *PTMakePoint(double x, double y, POINT ** pplist);
36 int DBGetType(register char *s);
40 * This routine returns a pointer to an initialized database element which
41 * would be the only element in an empty list.
43 ELT *
44 DBInit()
46 return ((ELT *) NULL);
47 } /* end DBInit */
51 * This routine creates a new element with the specified attributes and
52 * links it into database.
54 ELT *
55 DBCreateElt(int type,
56 POINT * pointlist,
57 int brush,
58 int size,
59 char *text,
60 ELT **db)
62 register ELT *temp;
64 temp = (ELT *) malloc(sizeof(ELT));
65 temp->nextelt = *db;
66 temp->type = type;
67 temp->ptlist = pointlist;
68 temp->brushf = brush;
69 temp->size = size;
70 temp->textpt = text;
71 *db = temp;
72 return (temp);
73 } /* end CreateElt */
77 * This routine reads the specified file into a database and returns a
78 * pointer to that database.
80 ELT *
81 DBRead(register FILE *file)
83 register int i;
84 register int done; /* flag for input exhausted */
85 register double nx; /* x holder so x is not set before orienting */
86 int type; /* element type */
87 ELT *elist; /* pointer to the file's elements */
88 POINT *plist; /* pointer for reading in points */
89 char string[MAXSTRING], *txt;
90 double x, y; /* x and y are read in point coords */
91 int len, brush, size;
92 int lastpoint;
94 SUNFILE = FALSE;
95 elist = DBInit();
96 (void) fscanf(file, "%" MAXSTRING_S "s%*[^\n]\n", string);
97 if (strcmp(string, "gremlinfile")) {
98 if (strcmp(string, "sungremlinfile")) {
99 error("`%1' is not a gremlin file", gremlinfile);
100 return (elist);
102 SUNFILE = TRUE;
105 (void) fscanf(file, "%d%lf%lf\n", &size, &x, &y);
106 /* ignore orientation and file positioning point */
108 done = FALSE;
109 while (!done) {
110 /* if (fscanf(file,"%" MAXSTRING_S "s\n", string) == EOF) */
111 /* I changed the scanf format because the element */
112 /* can have two words (e.g. CURVE SPLINE) */
113 if (fscanf(file, "\n%" MAXSTRING_S "[^\n]%*[^\n]\n", string) == EOF) {
114 error("`%1', error in file format", gremlinfile);
115 return (elist);
118 type = DBGetType(string); /* interpret element type */
119 if (type < 0) { /* no more data */
120 done = TRUE;
121 } else {
122 #ifdef UW_FASTSCAN
123 (void) xscanf(file, &x, &y); /* always one point */
124 #else
125 (void) fscanf(file, "%lf%lf\n", &x, &y); /* always one point */
126 #endif /* UW_FASTSCAN */
127 plist = PTInit(); /* NULL point list */
130 * Files created on the SUN have point lists terminated by a line
131 * containing only an asterik ('*'). Files created on the AED have
132 * point lists terminated by the coordinate pair (-1.00 -1.00).
134 if (TEXT(type)) { /* read only first point for TEXT elements */
135 nx = xorn(x, y);
136 y = yorn(x, y);
137 (void) PTMakePoint(nx, y, &plist);
138 savebounds(nx, y);
140 #ifdef UW_FASTSCAN
141 while (xscanf(file, &x, &y));
142 #else
143 lastpoint = FALSE;
144 do {
145 fgets(string, MAXSTRING, file);
146 if (string[0] == '*') { /* SUN gremlin file */
147 lastpoint = TRUE;
148 } else {
149 (void) sscanf(string, "%lf%lf", &x, &y);
150 if ((x == -1.00 && y == -1.00) && (!SUNFILE))
151 lastpoint = TRUE;
152 else {
153 if (compatibility_flag)
154 savebounds(xorn(x, y), yorn(x, y));
157 } while (!lastpoint);
158 #endif /* UW_FASTSCAN */
159 } else { /* not TEXT element */
160 #ifdef UW_FASTSCAN
161 do {
162 nx = xorn(x, y);
163 y = yorn(x, y);
164 (void) PTMakePoint(nx, y, &plist);
165 savebounds(nx, y);
166 } while (xscanf(file, &x, &y));
167 #else
168 lastpoint = FALSE;
169 while (!lastpoint) {
170 nx = xorn(x, y);
171 y = yorn(x, y);
172 (void) PTMakePoint(nx, y, &plist);
173 savebounds(nx, y);
175 fgets(string, MAXSTRING, file);
176 if (string[0] == '*') { /* SUN gremlin file */
177 lastpoint = TRUE;
178 } else {
179 (void) sscanf(string, "%lf%lf", &x, &y);
180 if ((x == -1.00 && y == -1.00) && (!SUNFILE))
181 lastpoint = TRUE;
184 #endif /* UW_FASTSCAN */
186 (void) fscanf(file, "%d%d\n", &brush, &size);
187 (void) fscanf(file, "%d", &len); /* text length */
188 (void) getc(file); /* eat blank */
189 txt = (char *) malloc((unsigned) len + 1);
190 for (i = 0; i < len; ++i) { /* read text */
191 int c = getc(file);
192 if (c == EOF)
193 break;
194 txt[i] = c;
196 txt[len] = '\0';
197 (void) DBCreateElt(type, plist, brush, size, txt, &elist);
198 } /* end else */
199 } /* end while not done */ ;
200 return (elist);
201 } /* end DBRead */
205 * Interpret element type in string s.
206 * Old file format consisted of integer element types.
207 * New file format has literal names for element types.
210 DBGetType(register char *s)
212 if (isdigit(s[0]) || (s[0] == '-')) /* old element format or EOF */
213 return (atoi(s));
215 switch (s[0]) {
216 case 'P':
217 return (POLYGON);
218 case 'V':
219 return (VECTOR);
220 case 'A':
221 return (ARC);
222 case 'C':
223 if (s[1] == 'U') {
224 if (s[5] == '\n')
225 return (CURVE);
226 switch (s[7]) {
227 case 'S':
228 return(BSPLINE);
229 case 'E':
230 fprintf(stderr,
231 "Warning: Bezier Curves will be printed as B-Splines\n");
232 return(BSPLINE);
233 default:
234 return(CURVE);
237 switch (s[4]) {
238 case 'L':
239 return (CENTLEFT);
240 case 'C':
241 return (CENTCENT);
242 case 'R':
243 return (CENTRIGHT);
244 default:
245 fatal("unknown element type");
247 case 'B':
248 switch (s[3]) {
249 case 'L':
250 return (BOTLEFT);
251 case 'C':
252 return (BOTCENT);
253 case 'R':
254 return (BOTRIGHT);
255 default:
256 fatal("unknown element type");
258 case 'T':
259 switch (s[3]) {
260 case 'L':
261 return (TOPLEFT);
262 case 'C':
263 return (TOPCENT);
264 case 'R':
265 return (TOPRIGHT);
266 default:
267 fatal("unknown element type");
269 default:
270 fatal("unknown element type");
273 return 0; /* never reached */
276 #ifdef UW_FASTSCAN
278 * Optimization hack added by solomon@crys.wisc.edu, 12/2/86.
279 * A huge fraction of the time was spent reading floating point numbers from
280 * the input file, but the numbers always have the format 'ddd.dd'. Thus
281 * the following special-purpose version of fscanf.
283 * xscanf(f,xp,yp) does roughly what fscanf(f,"%f%f",xp,yp) does except:
284 * -the next piece of input must be of the form
285 * <space>* <digit>*'.'<digit>* <space>* <digit>*'.'<digit>*
286 * -xscanf eats the character following the second number
287 * -xscanf returns 0 for "end-of-data" indication, 1 otherwise, where
288 * end-of-data is signalled by a '*' [in which case the rest of the
289 * line is gobbled], or by '-1.00 -1.00' [but only if !SUNFILE].
292 xscanf(FILE *f,
293 double *xp,
294 double *yp)
296 register int c, i, j, m, frac;
297 int iscale = 1, jscale = 1; /* x = i/scale, y=j/jscale */
299 while ((c = getc(f)) == ' ');
300 if (c == '*') {
301 while ((c = getc(f)) != '\n');
302 return 0;
304 i = m = frac = 0;
305 while (isdigit(c) || c == '.' || c == '-') {
306 if (c == '-') {
307 m++;
308 c = getc(f);
309 continue;
311 if (c == '.')
312 frac = 1;
313 else {
314 if (frac)
315 iscale *= 10;
316 i = 10 * i + c - '0';
318 c = getc(f);
320 if (m)
321 i = -i;
322 *xp = (double) i / (double) iscale;
324 while ((c = getc(f)) == ' ');
325 j = m = frac = 0;
326 while (isdigit(c) || c == '.' || c == '-') {
327 if (c == '-') {
328 m++;
329 c = getc(f);
330 continue;
332 if (c == '.')
333 frac = 1;
334 else {
335 if (frac)
336 jscale *= 10;
337 j = 10 * j + c - '0';
339 c = getc(f);
341 if (m)
342 j = -j;
343 *yp = (double) j / (double) jscale;
344 return (SUNFILE || i != -iscale || j != -jscale);
346 #endif /* UW_FASTSCAN */
348 /* EOF */