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; }
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); }
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); }
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; }
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); }