source: trunk/Jgraph/token.c@ 677

Last change on this file since 677 was 420, checked in by Nicholas Riley, 17 years ago

Jgraph: my changes - ANSIfication, few minor bug fixes; works on OS X 10.5 now

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