[BACK]Return to interpreter.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Diff for /src/usr.bin/mg/interpreter.c between version 1.10 and 1.11

version 1.10, 2021/03/20 19:39:30 version 1.11, 2021/03/21 12:56:16
Line 20 
Line 20 
  * like:   * like:
  *   *
  * 1. Give multiple arguments to a function that usually would accept only one:   * 1. Give multiple arguments to a function that usually would accept only one:
  * (find-file a.txt b.txt. c.txt)   * (find-file "a.txt" "b.txt" "c.txt")
  *   *
  * 2. Define a single value variable:   * 2. Define a single value variable:
  * (define myfile d.txt)   * (define myfile "d.txt")
  *   *
  * 3. Define a list:   * 3. Define a list:
  * (define myfiles(list e.txt f.txt))   * (define myfiles(list "e.txt" "f.txt"))
  *   *
  * 4. Use the previously defined variable or list:   * 4. Use the previously defined variable or list:
  * (find-file myfiles)   * (find-file myfiles)
Line 35 
Line 35 
  * 1. multiline parsing - currently only single lines supported.   * 1. multiline parsing - currently only single lines supported.
  * 2. parsing for '(' and ')' throughout whole string and evaluate correctly.   * 2. parsing for '(' and ')' throughout whole string and evaluate correctly.
  * 3. conditional execution.   * 3. conditional execution.
  * 4. deal with quotes around a string: "x x"   * 4. deal with special characters in a string: "x\" x" etc
  * 5. oh so many things....   * 5. do symbol names need more complex regex patterns? A-Za-z- at the moment.
    * 6. oh so many things....
  * [...]   * [...]
  * n. implement user definable functions.   * n. implement user definable functions.
    *
  */   */
 #include <sys/queue.h>  #include <sys/queue.h>
 #include <regex.h>  #include <regex.h>
Line 95 
Line 97 
         char            *p, *valp, *endp = NULL, *regs;          char            *p, *valp, *endp = NULL, *regs;
         char             expbuf[BUFSIZE], tmpbuf[BUFSIZE];          char             expbuf[BUFSIZE], tmpbuf[BUFSIZE];
         int              ret, pctr, fndstart, expctr, blkid, fndchr, fndend;          int              ret, pctr, fndstart, expctr, blkid, fndchr, fndend;
           int              inquote;
   
         pctr = fndstart = expctr = fndchr = fndend = 0;          pctr = fndstart = expctr = fndchr = fndend = inquote = 0;
         blkid = 1;          blkid = 1;
         /*          /*
          * Check for blocks of code with opening and closing ().           * Check for blocks of code with opening and closing ().
Line 116 
Line 119 
                 return(dobeep_msg("Empty lists not supported at moment"));                  return(dobeep_msg("Empty lists not supported at moment"));
         regs = "[(]+[\t ]*[(]+";          regs = "[(]+[\t ]*[(]+";
         if (doregex(regs, funstr))          if (doregex(regs, funstr))
                 return(dobeep_msg("Multiple left parantheses found"));                  return(dobeep_msg("Multiple consecutive left parantheses "\
                       "found."));
         /*          /*
          * load expressions into a list called 'expentry', to be processd           * load expressions into a list called 'expentry', to be processd
          * when all are obtained.           * when all are obtained.
Line 131 
Line 135 
                                 else                                  else
                                         *endp = '\0';                                          *endp = '\0';
                                 e1->par2 = 1;                                  e1->par2 = 1;
                                 if ((e1->exp = strndup(valp, BUFSIZE)) == NULL)                                  if ((e1->exp = strndup(valp, BUFSIZE)) ==
                                       NULL) {
                                           cleanup();
                                         return(dobeep_msg("strndup error"));                                          return(dobeep_msg("strndup error"));
                                   }
                         }                          }
                         if ((e1 = malloc(sizeof(struct expentry))) == NULL)                          if ((e1 = malloc(sizeof(struct expentry))) == NULL) {
                                   cleanup();
                                 return (dobeep_msg("malloc Error"));                                  return (dobeep_msg("malloc Error"));
                           }
                         SLIST_INSERT_HEAD(&exphead, e1, eentry);                          SLIST_INSERT_HEAD(&exphead, e1, eentry);
                         e1->exp = NULL;                          e1->exp = NULL;
                         e1->expctr = ++expctr;                          e1->expctr = ++expctr;
Line 147 
Line 156 
                         endp = NULL;                          endp = NULL;
                         pctr++;                          pctr++;
                 } else if (*p == ')') {                  } else if (*p == ')') {
                           if (inquote == 1) {
                                   cleanup();
                                   return(dobeep_msg("Opening and closing quote "\
                                       "char error"));
                           }
                         if (endp == NULL)                          if (endp == NULL)
                                 *p = '\0';                                  *p = '\0';
                         else                          else
                                 *endp = '\0';                                  *endp = '\0';
                         if ((e1->exp = strndup(valp, BUFSIZE)) == NULL)                          if ((e1->exp = strndup(valp, BUFSIZE)) == NULL) {
                                   cleanup();
                                 return(dobeep_msg("strndup error"));                                  return(dobeep_msg("strndup error"));
                           }
                         fndstart = 0;                          fndstart = 0;
                         pctr--;                          pctr--;
                 } else if (*p != ' ' && *p != '\t') {                  } else if (*p != ' ' && *p != '\t') {
Line 160 
Line 176 
                                 valp = p;                                  valp = p;
                                 fndchr = 1;                                  fndchr = 1;
                         }                          }
                           if (*p == '"') {
                                   if (inquote == 0)
                                           inquote = 1;
                                   else
                                           inquote = 0;
                           }
                         fndend = 0;                          fndend = 0;
                         endp = NULL;                          endp = NULL;
                 } else if (fndend == 0 && (*p == ' ' || *p == '\t')) {                  } else if (fndend == 0 && (*p == ' ' || *p == '\t')) {
Line 167 
Line 189 
                         fndend = 1;                          fndend = 1;
                         endp = p;                          endp = p;
                 } else if (*p == '\t') /* need to check not between "" */                  } else if (*p == '\t') /* need to check not between "" */
                         *p = ' ';                          if (inquote == 0)
                                   *p = ' ';
                 if (pctr == 0)                  if (pctr == 0)
                         blkid++;                          blkid++;
                 p++;                  p++;
         }          }
         expbuf[0] = tmpbuf[0] = '\0';  
   
           if (pctr != 0) {
                   cleanup();
                   return(dobeep_msg("Opening and closing parentheses error"));
           }
         /*          /*
          * Join expressions together for the moment, to progess.           * Join expressions together for the moment, to progess.
          * This needs to be totally redone and           * This needs to be totally redone and
          * iterate in-to-out, evaluating as we go. Eventually.           * iterate in-to-out, evaluating as we go. Eventually.
          */           */
           expbuf[0] = tmpbuf[0] = '\0';
         SLIST_FOREACH(e1, &exphead, eentry) {          SLIST_FOREACH(e1, &exphead, eentry) {
                 if (strlcpy(tmpbuf, expbuf, sizeof(tmpbuf)) >= sizeof(tmpbuf))                  if (strlcpy(tmpbuf, expbuf, sizeof(tmpbuf)) >= sizeof(tmpbuf))
                         return (dobeep_msg("strlcpy error"));                          return (dobeep_msg("strlcpy error"));
Line 195 
Line 222 
                 mglog_misc("exp|%s|\n", e1->exp);                  mglog_misc("exp|%s|\n", e1->exp);
 #endif  #endif
         }          }
         if (pctr != 0) {  
                 clearexp();  
                 return(dobeep_msg("Opening and closing parentheses error"));  
         }  
   
         ret = parseexp(expbuf);          ret = parseexp(expbuf);
         clearexp();          if (ret == FALSE)
                   cleanup();
           else
                   clearexp();     /* leave lists but remove expressions */
   
         return (ret);          return (ret);
 }  }
   
 /*  /*
  * At the moment, only paring list defines. Much more to do.   * At the moment, only parsing list defines. Much more to do.
    * Also only use basic chars for symbol names like ones found in
    * mg functions.
  */   */
 static int  static int
 parseexp(char *funstr)  parseexp(char *funstr)
Line 216 
Line 244 
   
         /* Does the line have a list 'define' like: */          /* Does the line have a list 'define' like: */
         /* (define alist(list 1 2 3 4)) */          /* (define alist(list 1 2 3 4)) */
         regs = "^define[ ]+.*[ ]+list[ ]+.*[ ]*";          regs = "^define[ ]+[A-Za-z-]+[ ]+list[ ]+.*[ ]*";
         if (doregex(regs, funstr))          if (doregex(regs, funstr))
                 return(foundvar(funstr));                  return(foundvar(funstr));
   
         /* Does the line have a incorrect variable 'define' like: */          /* Does the line have a incorrect variable 'define' like: */
         /* (define i y z) */          /* (define i y z) */
         regs = "^define[ ]+.*[ ]+.*[ ]+.*$";          regs = "^define[ ]+[A-Za-z-]+[ ]+.*[ ]+.*$";
         if (doregex(regs, funstr))          if (doregex(regs, funstr))
                 return(dobeep_msg("Invalid use of define."));                  return(dobeep_msg("Invalid use of define."));
   
         /* Does the line have a single variable 'define' like: */          /* Does the line have a single variable 'define' like: */
         /* (define i 0) */          /* (define i 0) */
         regs = "^define[ ]+.*[ ]+.*$";          regs = "^define[ ]+[A-Za-z-]+[ ]+.*$";
         if (doregex(regs, funstr))          if (doregex(regs, funstr))
                 return(foundvar(funstr));                  return(foundvar(funstr));
   
Line 250 
Line 278 
         char     excbuf[BUFSIZE], argbuf[BUFSIZE];          char     excbuf[BUFSIZE], argbuf[BUFSIZE];
         char     contbuf[BUFSIZE], varbuf[BUFSIZE];          char     contbuf[BUFSIZE], varbuf[BUFSIZE];
         char    *cmdp = NULL, *argp, *fendp = NULL, *endp, *p, *v, *s = " ";          char    *cmdp = NULL, *argp, *fendp = NULL, *endp, *p, *v, *s = " ";
           char    *regs;
         int      spc, numparams, numspc;          int      spc, numparams, numspc;
         int      inlist, sizof, fin;          int      inlist, sizof, fin, inquote;
   
           /* mg function name regex */
         if (doregex("^[A-Za-z-]+$", funstr))          if (doregex("^[A-Za-z-]+$", funstr))
                 return(excline(funstr));                  return(excline(funstr));
   
Line 277 
Line 307 
                 return (dobeep_msg("strlcpy error"));                  return (dobeep_msg("strlcpy error"));
         argp = argbuf;          argp = argbuf;
         numspc = spc = 1; /* initially fake a space so we find first argument */          numspc = spc = 1; /* initially fake a space so we find first argument */
         inlist = fin = 0;          inlist = fin = inquote = 0;
   
         for (p = argbuf; *p != '\0'; p++) {          for (p = argbuf; *p != '\0'; p++) {
                 if (*(p + 1) == '\0')                  if (*(p + 1) == '\0')
                         fin = 1;                          fin = 1;
   
                 if (*p != ' ') {                  if (*p != ' ') {
                           if (*p == '"') {
                                   if (inquote == 1)
                                           inquote = 0;
                                   else
                                           inquote = 1;
                           }
                         if (spc == 1)                          if (spc == 1)
                                 argp = p;                                  argp = p;
                         spc = 0;                          spc = 0;
                 }                  }
                 if (*p == ' ' || fin) {                  if ((*p == ' ' && inquote == 0) || fin) {
                         if (spc == 1)                          if (spc == 1)
                                 continue;                                  continue;
   
                         if (*p == ' ') {                          if (*p == ' ') {
                                 *p = '\0';      /* terminate arg string */                                  *p = '\0';              /* terminate arg string */
                         }                          }
                         endp = p + 1;                          endp = p + 1;
                         excbuf[0] = '\0';                          excbuf[0] = '\0';
Line 301 
Line 337 
                         contbuf[0] = '\0';                          contbuf[0] = '\0';
                         sizof = sizeof(varbuf);                          sizof = sizeof(varbuf);
                         v = varbuf;                          v = varbuf;
                         if (isvar(&argp, &v, sizof)) {                          regs = "[\"]+.*[\"]+";
                           if (doregex(regs, argp))
                                   ;                       /* found quotes */
                           else if (isvar(&argp, &v, sizof)) {
                                 (void)(strlcat(varbuf, " ",                                  (void)(strlcat(varbuf, " ",
                                     sizof) >= sizof);                                      sizof) >= sizof);
   
Line 312 
Line 351 
   
                                 (void)(strlcat(varbuf, contbuf,                                  (void)(strlcat(varbuf, contbuf,
                                     sizof) >= sizof);                                      sizof) >= sizof);
   
                                 (void)(strlcpy(argbuf, varbuf,                                  argbuf[0] = ' ';
                                   argbuf[1] = '\0';
                                   (void)(strlcat(argbuf, varbuf,
                                     sizof) >= sizof);                                      sizof) >= sizof);
   
                                 p = argp = argbuf;                                  p = argp = argbuf;
                                 while (*p != ' ') {  
                                         if (*p == '\0')  
                                                 break;  
                                         p++;  
                                 }  
                                 *p = '\0';  
                                 spc = 1;                                  spc = 1;
                                 fin = 0;                                  fin = 0;
                         }                                  continue;
                           } else
                                   return (dobeep_msgs("Var not found:", argp));
   
                         if (strlcpy(excbuf, cmdp, sizeof(excbuf))                          if (strlcpy(excbuf, cmdp, sizeof(excbuf))
                             >= sizeof(excbuf))                              >= sizeof(excbuf))
                                 return (dobeep_msg("strlcpy error"));                                  return (dobeep_msg("strlcpy error"));
Line 348 
Line 386 
         return (TRUE);          return (TRUE);
 }  }
   
   
 /*  /*
  * Is an item a value or a variable?   * Is an item a value or a variable?
  */   */
Line 371 
Line 408 
         return (FALSE);          return (FALSE);
 }  }
   
   
 /*  /*
  * The define string _must_ adhere to the regex in parsexp().   * The define string _must_ adhere to the regex in parsexp().
  * This is not the correct way to do parsing but it does highlight   * This is not the correct way to do parsing but it does highlight
Line 385 
Line 421 
         char            *p, *vnamep, *vendp = NULL, *valp;          char            *p, *vnamep, *vendp = NULL, *valp;
         int              spc;          int              spc;
   
           /* vars names can't start with these. */
           /* char *spchrs = "+-.#";       */
   
         p = strstr(defstr, " ");        /* move to first ' ' char.    */          p = strstr(defstr, " ");        /* move to first ' ' char.    */
         vnamep = skipwhite(p);          /* find first char of var name. */          vnamep = skipwhite(p);          /* find first char of var name. */
         vendp = vnamep;          vendp = vnamep;
   
         /* now find the end of the list name */          /* now find the end of the list name */
Line 455 
Line 494 
  * Finished with buffer evaluation, so clean up any vars.   * Finished with buffer evaluation, so clean up any vars.
  * Perhaps keeps them in mg even after use,...   * Perhaps keeps them in mg even after use,...
  */   */
 int  static int
 clearvars(void)  clearvars(void)
 {  {
         struct varentry *v1 = NULL;          struct varentry *v1 = NULL;
Line 485 
Line 524 
                 free(e1);                  free(e1);
         }          }
         return;          return;
   }
   
   /*
    * Cleanup before leaving.
    */
   void
   cleanup(void)
   {
           clearexp();
           clearvars();
 }  }
   
 /*  /*

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11