source: trunk/Jgraph/token.c@ 418

Last change on this file since 418 was 418, checked in by Nicholas Riley, 16 years ago

Jgraph 8.3 from http://www.cs.utk.edu/~plank/plank/jgraph/jgraph.tar.gz

File size: 7.7 KB
Line 
1/*
2 * $Source: /tmp_mnt/n/fs/grad1/jsp/src/jgraph/RCS/token.c,v $
3 * $Revision: 8.3 $
4 * $Date: 92/11/30 11:42:42 $
5 * $Author: jsp $
6 */
7
8#include <math.h>
9#include <stdio.h>
10
11#ifdef LCC
12#include <stdlib.h>
13#endif
14
15#ifdef VMS
16#include <stdlib.h>
17#include <redexp.VMS>
18#endif
19
20#include "list.h"
21
22#define CNULL ((char *)0)
23
24typedef struct iostack {
25 struct iostack *flink;
26 struct iostack *blink;
27 char *filename;
28 FILE *stream;
29 int oldcharvalid;
30 char oldchar;
31 char pipe;
32 int line;
33} *Iostack;
34
35static char INPUT[1000];
36static int getnew = 1;
37static char oldchar = '\0';
38static oldcharvalid = 0;
39static char pipe = 0;
40static int eof = 0;
41static int init = 0;
42static Iostack stack;
43static char real_eof = EOF;
44
45static FILE *IOSTREAM;
46static char FILENAME[300];
47static int line = 1;
48
49#ifdef VMS
50/* On VMS, there are no popen() and pclose(), so we provide dummies here. */
51FILE *popen(command, type)
52char *command, *type;
53{
54 return(NULL);
55}
56int pclose(stream)
57FILE *stream;
58{
59 return(-1);
60}
61#endif /*VMS*/
62
63set_input_file(s)
64char *s;
65{
66 FILE *f;
67 Iostack n;
68
69 if (init == 0) {
70 stack = (Iostack) make_list(sizeof(struct iostack));
71 if (s == CNULL) {
72 IOSTREAM = stdin;
73 strcpy(FILENAME, "<stdin>");
74 } else {
75 IOSTREAM = fopen(s, "r");
76 if (IOSTREAM == NULL) {
77 fprintf(stderr, "Error: cannot open file \"%s\"\n", s);
78 exit(1);
79 }
80 strcpy(FILENAME, s);
81 }
82 init = 1;
83 } else {
84 n = (Iostack) get_node(stack);
85 n->stream = NULL;
86 n->filename = (char *) malloc (sizeof(char)*(strlen(s)+2));
87 strcpy(n->filename, s);
88 n->oldchar = oldchar;
89 n->oldcharvalid = oldcharvalid;
90 n->pipe = pipe;
91 n->line = line;
92 insert(n, stack->flink);
93 }
94}
95
96error_header()
97{
98 fprintf(stderr, "%s,%d: ", FILENAME, line);
99}
100
101int gettokenchar()
102{
103 if (oldcharvalid == 0) oldchar = getc(IOSTREAM);
104 oldcharvalid = 0;
105 if (oldchar == '\n') line++;
106 return oldchar;
107}
108
109ungettokenchar()
110{
111 oldcharvalid = 1;
112 if (oldchar == '\n') line--;
113}
114
115int gettoken(s)
116char *s;
117{
118 int i;
119 char c;
120
121 for (c = gettokenchar();
122 c == ' ' || c == '\t' || c == '\n';
123 c = gettokenchar()) ;
124 for (i = 0;
125 c != real_eof && c != ' ' && c != '\t' && c != '\n';
126 c = gettokenchar()) {
127 s[i++] = c;
128 }
129 s[i] = '\0';
130 ungettokenchar();
131 return i;
132}
133
134get_comment()
135{
136 if (eof) return;
137 while (1) {
138 if (gettoken(INPUT) == 0) return;
139 else if (strcmp(INPUT, "(*") == 0)
140 get_comment();
141 else if (strcmp(INPUT, "*)") == 0)
142 return;
143 }
144}
145
146static int iostackempty()
147{
148 return (first(stack) == nil(stack));
149}
150
151static push_iostack(p)
152int p;
153{
154 Iostack n;
155
156 n = (Iostack) get_node(stack);
157 n->stream = IOSTREAM;
158 n->filename = (char *) malloc (sizeof(char)*(strlen(FILENAME)+2));
159 n->oldchar = oldchar;
160 n->oldcharvalid = oldcharvalid;
161 n->pipe = pipe;
162 n->line = line;
163 strcpy(n->filename, FILENAME);
164 insert(n, stack);
165 if (p) {
166 IOSTREAM = (FILE *) popen(INPUT, "r");
167 } else {
168 IOSTREAM = fopen(INPUT, "r");
169 }
170 pipe = p;
171 line = 1;
172 if (IOSTREAM == NULL) {
173 error_header();
174 fprintf(stderr, "Include file \"%s\" does not exist\n", INPUT);
175 exit(1);
176 }
177 strcpy(FILENAME, INPUT);
178}
179
180static pop_iostack()
181{
182 Iostack n;
183
184 fflush(IOSTREAM);
185 if (pipe) {
186 if (pclose(IOSTREAM)) {
187 /*error_header();
188 fprintf(stderr, "\n\nPipe returned a non-zero error code.\n");
189 exit(1); */
190 }
191 } else {
192 fclose(IOSTREAM);
193 }
194 n = last(stack);
195 if (n->stream == NULL) {
196 n->stream = fopen(n->filename, "r");
197 if (n->stream == NULL) {
198 fprintf(stderr, "Error: cannot open file \"%s\"\n", n->stream);
199 exit(1);
200 }
201 }
202 IOSTREAM = n->stream;
203 strcpy(FILENAME, n->filename);
204 free(n->filename);
205 pipe = n->pipe;
206 line = n->line;
207 oldchar = n->oldchar;
208 oldcharvalid = n->oldcharvalid;
209 delete_item(n);
210 free_node(n, stack);
211}
212
213static nexttoken()
214{
215 if (eof) return;
216 if (getnew) {
217 while (1) {
218 if (gettoken(INPUT) == 0) {
219 if (iostackempty()) {
220 eof = 1;
221 getnew = 0;
222 return;
223 } else {
224 pop_iostack();
225 }
226 } else if (strcmp(INPUT, "(*") == 0) {
227 get_comment();
228 } else if (strcmp(INPUT, "include") == 0) {
229 if (gettoken(INPUT) == 0) {
230 error_header();
231 fprintf(stderr, "Empty include statement\n");
232 exit(1);
233 } else {
234 push_iostack(0);
235 }
236 } else if (strcmp(INPUT, "shell") == 0) {
237#ifdef VMS
238 fprintf(stderr, "No shell option on VMS, sorry.\n");
239 exit(1);
240#endif /*VMS*/
241 if (gettoken(INPUT) == 0 || strcmp(INPUT, ":") != 0) {
242 error_header();
243 fprintf(stderr, "'shell' must be followed by ':'\n");
244 exit(1);
245 }
246 if (getsystemstring() == 0) {
247 fprintf(stderr, "Empty shell statement\n");
248 exit(1);
249 }
250 push_iostack(1);
251 } else {
252 getnew = 1;
253 return;
254 }
255 }
256 }
257 getnew = 1;
258 return;
259}
260
261int getstring(s)
262char *s;
263{
264 nexttoken();
265 if (eof) return 0;
266 strcpy(s, INPUT);
267 return 1;
268}
269
270int getint(i)
271int *i;
272{
273 int j;
274
275 nexttoken();
276 if (eof) return 0;
277 *i = atoi(INPUT);
278 if (*i == 0) {
279 for (j = 0; INPUT[j] != '\0'; j++)
280 if (INPUT[j] != '0') return 0;
281 }
282 return 1;
283}
284
285int getfloat(f)
286float *f;
287{
288 int j;
289
290 nexttoken();
291 if (eof) return 0;
292 *f = (float) atof(INPUT);
293 if (*f == 0.0) {
294 for (j = 0; INPUT[j] == '-'; j++);
295 while (INPUT[j] == '0') j++;
296 if (INPUT[j] == '.') j++;
297 while (INPUT[j] == '0') j++;
298 if (INPUT[j] == 'e' || INPUT[j] == 'E') {
299 j++;
300 if (INPUT[j] == '+' || INPUT[j] == '-') j++;
301 while (INPUT[j] == '0') j++;
302 }
303 return (INPUT[j] == '\0');
304 } else return 1;
305}
306
307static char *new_printable_text(s)
308char *s;
309{
310 char *new_s;
311 int to_pad, i, j;
312
313 to_pad = 0;
314 for (i = 0; s[i] != '\0'; i++) {
315 if (s[i] == '\\' || s[i] == ')' || s[i] == '(') {
316 to_pad++;
317 }
318 }
319
320 j = sizeof(char) * (i + to_pad + 2);
321 if ((j % 8) != 0) j += 8 - j % 8;
322 new_s = (char *) malloc (j);
323 j = 0;
324 for (i = 0; s[i] != '\0'; i++) {
325 if (s[i] == '\\' || s[i] == ')' || s[i] == '(') {
326 new_s[j++] = '\\';
327 }
328 new_s[j++] = s[i];
329 }
330 new_s[j] = '\0'; /* added: tie off -hdd */
331 return new_s;
332}
333
334char *getmultiline()
335{
336 char c;
337 int i, j, done, len, started;
338 char *out_str;
339
340 if (getnew == 0) return CNULL;
341
342 c = gettokenchar();
343 if (c == real_eof) {
344 ungettokenchar();
345 return CNULL;
346 }
347 done = 0;
348 started = 0;
349 while (!done) {
350 i = 0;
351 for (c = gettokenchar(); c != real_eof && c != '\n'; c = gettokenchar()) {
352 INPUT[i++] = c;
353 }
354 INPUT[i] = '\0';
355 if (!started) {
356 out_str = (char *) malloc (sizeof(char)*(i+1));
357 strcpy(out_str, INPUT);
358 len = i;
359 started = 1;
360 } else {
361 out_str = (char *) realloc(out_str, (len + i + 3) * sizeof(char));
362 sprintf(&(out_str[len]), "\n%s", INPUT);
363 len += i+1;
364 }
365 if (c == '\n' && len != 0 && out_str[len-1] == '\\') {
366 len--;
367 } else {
368 done = 1;
369 }
370 }
371 ungettokenchar();
372 return out_str;
373}
374
375char *getlabel()
376{
377 char c;
378 char *txt, *new;
379 int i;
380
381 txt = getmultiline();
382 if (txt == CNULL) return CNULL;
383 new = new_printable_text(txt);
384 free(txt);
385 return new;
386}
387
388int getsystemstring()
389{
390 char c;
391 int i;
392 int done;
393
394 if (getnew == 0) return 0;
395
396 c = gettokenchar();
397 if (c == real_eof) {
398 ungettokenchar();
399 return 0;
400 }
401 i = 0;
402 done = 0;
403 while (!done) {
404 for (c = gettokenchar(); c != real_eof && c != '\n'; c = gettokenchar()) {
405 INPUT[i++] = c;
406 }
407 if (c == '\n' && i > 0 && INPUT[i-1] == '\\') {
408 INPUT[i++] = '\n';
409 } else {
410 done = 1;
411 }
412 }
413 ungettokenchar();
414 INPUT[i] = '\0';
415 return 1;
416}
417
418rejecttoken()
419{
420 getnew = 0;
421}
Note: See TracBrowser for help on using the repository browser.