source: trunk/Jgraph/token.c @ 420

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

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

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#include <string.h>
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';
39static int oldcharvalid = 0;
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
64void set_input_file(char *s)
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
95void error_header()
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
108void ungettokenchar()
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
133void get_comment()
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
150static void push_iostack(int p)
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
178static void pop_iostack()
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) {
196      fprintf(stderr, "Error: cannot open file \"%s\"\n", n->filename);
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
211int getsystemstring(void);
212
213static void 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}
259
260int getstring(char *s)
261{
262  nexttoken();
263  if (eof) return 0;
264  strcpy(s, INPUT);
265  return 1;
266}
267
268int getint(int *i)
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
282int getfloat(float *f)
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;
333  int i, done, len, started;
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
412void rejecttoken(void)
413{
414  getnew = 0;
415}
Note: See TracBrowser for help on using the repository browser.