source: trunk/Jgraph/token.c @ 418

Last change on this file since 418 was 418, checked in by Nicholas Riley, 13 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.