home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume31 / jgraph / part06 / token.c < prev   
Encoding:
C/C++ Source or Header  |  1992-07-14  |  7.4 KB  |  397 lines

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