Beispiel #1
0
int32
str2words(char *line, char **ptr, int32 max_ptr)
{
    int32 i, n;

    n = 0;                      /* #words found so far */
    i = 0;                      /* For scanning through the input string */
    while (1) {
        /* Skip whitespace before next word */
        while (line[i] && isspace_c(line[i]))
            ++i;
        if (!line[i])
            break;

        if (ptr != NULL && n >= max_ptr) {
            /*
             * Pointer array size insufficient.  Restore NULL chars inserted so far
             * to space chars.  Not a perfect restoration, but better than nothing.
             */
            for (; i >= 0; --i)
                if (line[i] == '\0')
                    line[i] = ' ';

            return -1;
        }

        /* Scan to end of word */
        if (ptr != NULL)
            ptr[n] = line + i;
        ++n;
        while (line[i] && !isspace_c(line[i]))
            ++i;
        if (!line[i])
            break;
        if (ptr != NULL)
            line[i] = '\0';
        ++i;
    }

    return n;
}
Beispiel #2
0
static void parse_simple(const char *fname, kstring_t *id, kstring_t *secret)
{
    kstring_t text = { 0, 0, NULL };
    char *s;
    size_t len;

    FILE *fp = expand_tilde_open(fname, "r");
    if (fp == NULL) return;

    while (kgetline(&text, (kgets_func *) fgets, fp) >= 0)
        kputc(' ', &text);
    fclose(fp);

    s = text.s;
    while (isspace_c(*s)) s++;
    kputsn(s, len = strcspn(s, " \t"), id);

    s += len;
    while (isspace_c(*s)) s++;
    kputsn(s, strcspn(s, " \t"), secret);

    free(text.s);
}
Beispiel #3
0
static void parse_ini(const char *fname, const char *section, ...)
{
    kstring_t line = { 0, 0, NULL };
    int active = 1;  // Start active, so global properties are accepted
    char *s;

    FILE *fp = expand_tilde_open(fname, "r");
    if (fp == NULL) return;

    while (line.l = 0, kgetline(&line, (kgets_func *) fgets, fp) >= 0)
        if (line.s[0] == '[' && (s = strchr(line.s, ']')) != NULL) {
            *s = '\0';
            active = (strcmp(&line.s[1], section) == 0);
        }
        else if (active && (s = strpbrk(line.s, ":=")) != NULL) {
            const char *key = line.s, *value = &s[1], *akey;
            va_list args;

            while (isspace_c(*key)) key++;
            while (s > key && isspace_c(s[-1])) s--;
            *s = '\0';

            while (isspace_c(*value)) value++;
            while (line.l > 0 && isspace_c(line.s[line.l-1]))
                line.s[--line.l] = '\0';

            va_start(args, section);
            while ((akey = va_arg(args, const char *)) != NULL) {
                kstring_t *avar = va_arg(args, kstring_t *);
                if (strcmp(key, akey) == 0) { kputs(value, avar); break; }
            }
            va_end(args);
        }

    fclose(fp);
    free(line.s);
}
Beispiel #4
0
Ipc_Status_t
ipc_get_line (
     char               *str,   /* Text retrieved from IPC channel */
     int                *len,   /* Length of text string */
     Ipc_Wait_t         wait )  /* Select blocking or non-blocking */
     /*
      * Reads one SPICE line from the connection. Strips any control lines
      * which cannot be interpretted by the simulator (e.g. >INQCON) and
      * processes them.  If such a line is read, it is processed and the next
      * line is read.  `ipc_get_line' does not return until a non-interceptable
      * line is read or end of file.
      *
      * If `wait' is IPC_NO_WAIT and there is no data available on the
      * connection, `ipc_get_line' returns IPC_STATUS_NO_DATA. If `wait' is
      * IPC_WAIT, `ipc_get_line' will not return until there is data available
      * or and end of file condition is reached or an error occurs.
      *
      * Intercepts and processes the following commands:
      *    #RETURNI, #MINTIME, #VTRANS,
      *    >PAUSE, >CONT, >STOP, >INQCON, >NETLIST, >ENDNET
      * Other > records are silently ignored.
      *
      * Intercepts old-style .TEMP card generated by MSPICE
      *
      * Returns:
      *    IPC_STATUS_OK                - for successful reads
      *    IPC_STATUS_NO_DATA           - when NO_WAIT and no data available
      *    IPC_STATUS_END_OF_DECK       - at end of deck (>ENDNET seen)
      *    IPC_STATUS_ERROR             - otherwise
      */
{
   Ipc_Status_t status;
   Ipc_Boolean_t need_another = IPC_TRUE;

   do {

      status = ipc_transport_get_line (str, len, wait);
      
      switch (status) {
      case IPC_STATUS_NO_DATA:
      case IPC_STATUS_ERROR:
         need_another = IPC_FALSE;
         break;
      case IPC_STATUS_END_OF_DECK:
         assert (0); /* should never get this from the low-level get-line */
         status = IPC_STATUS_ERROR;
         need_another = IPC_FALSE;
         break;
      case IPC_STATUS_OK:
         /*
          * Got a good line - check to see if it's one of the ones we need to
          * intercept
          */
         if (str[0] == '>') {
            if (kw_match (">STOP", str)) {
               ipc_handle_stop();
            } else if (kw_match (">PAUSE", str)) {
               /* assert (need_another); */
               /*
                * once more around the loop to do a blocking wait for the >CONT
                */
               need_another = IPC_TRUE;
               wait = IPC_WAIT;
            } else if (kw_match (">INQCON", str)) {
               ipc_send_line (">ABRTABL");
               ipc_send_line (">PAUSABL");
               ipc_send_line (">KEEPABL");
               status = ipc_flush ();
               if (IPC_STATUS_OK != status) {
                  need_another = IPC_FALSE;
               }
            } else if (kw_match (">ENDNET", str)) {
               end_of_deck_seen = IPC_TRUE;
               need_another = IPC_FALSE;
               status = IPC_STATUS_END_OF_DECK;
            } else {
               /* silently ignore */
            }
         } else if (str[0] == '#') {
            if (kw_match ("#RETURNI", str)) {
               ipc_handle_returni ();
            } else if (kw_match ("#MINTIME", str)) {
               double d1/*,d2*/;
               if (1 != sscanf (&str[8], "%lg", &d1)) {
                  status = IPC_STATUS_ERROR;
                  need_another = IPC_FALSE;
               } else {
                  ipc_handle_mintime (d1);
               }
            } else if (kw_match ("#VTRANS", str)) {
               char *tok1;
               char *tok2;
               char *tok3;
               
               tok1 = &str[8];
               for (tok2 = tok1; *tok2; tok2++) {
                  if (isspace_c(*tok2)) {
                     *tok2 = '\0';
                     tok2++;
                     break;
                  }
               }
               for(tok3 = tok2; *tok3; tok3++) {
                   if(isspace_c(*tok3)) {
                       *tok3 = '\0';
                       break;
                   }
               }
               ipc_handle_vtrans (tok1, tok2);
            } else {
               /* silently ignore */
            }
         } else if (str[0] == '.') {
            if (kw_match (".TEMP", str)) {
               /* don't pass .TEMP card to caller */
               printf("Old-style .TEMP card found - ignored\n");
            }
            else {
               /* pass all other . cards to the caller */
               need_another = IPC_FALSE;
            }
         } else {
            /*
             * Not a '>' or '#' record - let the caller deal with it
             */
            need_another = IPC_FALSE;
         }
         break;
      default:
         /*
          * some unknown status value!
          */
         assert (0);
         status = IPC_STATUS_ERROR;
         need_another = IPC_FALSE;
         break;
      }
   } while (need_another);

   return status;
}
Beispiel #5
0
int
PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line)
{
    static char *specials = " \t%()-^+*,/|&<>~=";
    char  *sbuf = *line;
    int token;

    while ((*sbuf == ' ') || (*sbuf == '\t'))
        sbuf++;

    llocp->start = sbuf;

#define lexer_return(token_, length)                            \
    do { token = token_; sbuf += length; goto done; } while(0)

    if ((sbuf[0] == 'g') && (sbuf[1] == 't') &&
        strchr(specials, sbuf[2])) {
        lexer_return('>', 2);
    } else if ((sbuf[0] == 'l') && (sbuf[1] == 't') &&
               strchr(specials, sbuf[2])) {
        lexer_return('<', 2);
    } else if ((sbuf[0] == 'g') && (sbuf[1] == 'e') &&
               strchr(specials, sbuf[2])) {
        lexer_return(TOK_GE, 2);
    } else if ((sbuf[0] == 'l') && (sbuf[1] == 'e') &&
               strchr(specials, sbuf[2])) {
        lexer_return(TOK_LE, 2);
    } else if ((sbuf[0] == 'n') && (sbuf[1] == 'e') &&
               strchr(specials, sbuf[2])) {
        lexer_return(TOK_NE, 2);
    } else if ((sbuf[0] == 'e') && (sbuf[1] == 'q') &&
               strchr(specials, sbuf[2])) {
        lexer_return('=', 2);
    } else if ((sbuf[0] == 'o') && (sbuf[1] == 'r') &&
               strchr(specials, sbuf[2])) {
        lexer_return('|', 2);
    } else if ((sbuf[0] == 'a') && (sbuf[1] == 'n') &&
               (sbuf[2] == 'd') && strchr(specials, sbuf[3])) {
        lexer_return('&', 3);
    } else if ((sbuf[0] == 'n') && (sbuf[1] == 'o') &&
               (sbuf[2] == 't') && strchr(specials, sbuf[3])) {
        lexer_return('~', 3);
    }

    switch (*sbuf) {

    case '[':
    case ']':
        lexer_return(*sbuf, 1);

    case '>':
    case '<':
    {
        /* Workaround, The Frontend makes "<>" into "< >" */
        int j = 1;
        while (isspace_c(sbuf[j]))
            j++;
        if (((sbuf[j] == '<') || (sbuf[j] == '>')) && (sbuf[0] != sbuf[j])) {
            /* Allow both <> and >< for NE. */
            lexer_return(TOK_NE, j+1);
        } else if (sbuf[1] == '=') {
            lexer_return((sbuf[0] == '>') ? TOK_GE : TOK_LE, 2);
        } else {
            lexer_return(*sbuf, 1);
        }
    }

    case '?':
    case ':':
    case ',':
    case '+':
    case '-':
    case '*':
    case '%':
    case '/':
    case '^':
    case '(':
    case ')':
    case '=':
    case '&':
    case '|':
    case '~':
        lexer_return(*sbuf, 1);

    case '\0':
        lexer_return(*sbuf, 0);

    case '"':
    {
        char *start = ++sbuf;
        while (*sbuf && (*sbuf != '"'))
            sbuf++;
        lvalp->str = copy_substring(start, sbuf);
        if (*sbuf)
            sbuf++;
        lexer_return(TOK_STR, 0);
    }

    default:
    {
        char *s = sbuf;
        double *td = ft_numparse(&s, FALSE);
        if ((!s || *s != ':') && td) {
            sbuf = s;
            lvalp->num = *td;
            lexer_return(TOK_NUM, 0);
        } else {
            int atsign = 0;
            char *start = sbuf;
            /* It is bad how we have to recognise '[' -- sometimes
             * it is part of a word, when it defines a parameter
             * name, and otherwise it isn't.
             *
             * what is valid here ?
             *   foo  dc1.foo  dc1.@m1[vth]
             * this too ?
             *   vthing#branch
             * should we convert the pseudo identifier ?
             *   i(v5) --> v5#branch
             */
            for (; *sbuf && !strchr(specials, *sbuf); sbuf++)
                if (*sbuf == '@')
                    atsign = 1;
                else if (!atsign && *sbuf == '[')
                    break;
                else if (*sbuf == ']') {
                    if (atsign)
                        sbuf++;
                    break;
                }

            lvalp->str = copy_substring(start, sbuf);
            lexer_return(TOK_STR, 0);
        }
    }
    }

done:
    if (ft_parsedb) {
        if (token == TOK_STR)
            fprintf(stderr, "lexer: TOK_STR, \"%s\"\n", lvalp->str);
        else if (token == TOK_NUM)
            fprintf(stderr, "lexer: TOK_NUM, %G\n", lvalp->num);
        else
            fprintf(stderr, "lexer: token %d\n", token);
    }

    *line = sbuf;
    llocp->stop = sbuf;
    return (token);
}