static void decode_de(yystype *params[], struct text_buffer *txtbuf) { const char *p = TOKEN_GET(params[0], cstring); const long a = TOKEN_GET(params[1], ival); /*const char *c = params[2];*/ char *k = TOKEN_GET(params[3], string); /*const char *r = params[5];*/ unsigned val=0; unsigned nsplit = 0; const char* o; const char **tokens; memset(txtbuf, 0, sizeof(*txtbuf)); if(!p || !k ) return; for(o = k; *o; o++) if(*o == '|') nsplit++; nsplit++; tokens = malloc(sizeof(char*)*nsplit); if(!tokens) { return; } cli_strtokenize(k,'|',nsplit, tokens); do { while(*p && !isalnum(*p)) { if(*p=='\\' && (p[1] == '\'' || p[1] == '\"')) p++; else textbuffer_putc(txtbuf, *p++); } if(!*p) break; val = 0; o = p; while(*p && isalnum(*p)) { unsigned x; unsigned char v = *p++; /* TODO: use a table here */ if(v >= 'a') x = 10+v-'a'; else if(v >= 'A') x = 36+v-'A'; else x = v-'0'; val = val*a+x; } if(val >= nsplit || !tokens[val] || !tokens[val][0]) while(o!=p) textbuffer_putc(txtbuf, *o++); else textbuffer_append(txtbuf, tokens[val]); } while (*p); free(tokens); textbuffer_append(txtbuf, "\0"); }
END_TEST START_TEST (test_putc) { fail_unless(textbuffer_putc(&buf, '\x5a') != -1, "tbuf putc"); fail_unless(buf.data && buf.data[0] == '\x5a', "textbuffer_putc"); }
static inline int parseString(YYSTYPE *lvalp, yyscan_t scanner, const char q, enum tokenizer_state tostate) { size_t len; /* look for " terminating the string */ const char *start = &scanner->in[scanner->pos], *end = start; do { const size_t siz = &scanner->in[scanner->insize] - end; end = memchr(end, q, siz); if(end && end > start && end[-1] == '\\') { ++end; continue; } break; } while (1); if(end && end >= start) len = end - start; else len = scanner->insize - scanner->pos; cli_textbuffer_append_normalize(&scanner->buf, start, len); if(end) { /* skip over end quote */ scanner->pos += len + 1; textbuffer_putc(&scanner->buf, '\0'); TOKEN_SET(lvalp, string, textbuffer_done(scanner)); scanner->state = Initial; assert(lvalp->val.string); return TOK_StringLiteral; } else { scanner->pos += len; /* unfinished string */ scanner->state = tostate; return 0; } }
END_TEST START_TEST (test_append) { fail_unless(textbuffer_append(&buf, "test") != -1, "tbuf append"); fail_unless(textbuffer_putc(&buf, '\0') != -1, "tbuf putc"); fail_unless(buf.data && !strcmp(buf.data,"test"), "textbuffer_append"); }
static inline int parseId(YYSTYPE *lvalp, yyscan_t scanner) { const struct keyword *kw; const unsigned char *in = (const unsigned char*)scanner->in; scanner->state = Initial; while(scanner->pos < scanner->insize) { unsigned char c = in[scanner->pos++]; enum char_class cClass = id_ctype[c]; switch(cClass) { case IdStart: textbuffer_putc(&scanner->buf, c); break; case Operator: /* the table contains OP only for \ */ assert(c == '\\'); if(scanner->pos < scanner->insize && in[scanner->pos++] == 'u') { textbuffer_putc(&scanner->buf, c); break; } if(scanner->pos == scanner->insize) { scanner->pos++; } /* else fallthrough */ default: /* character is no longer part of identifier */ scanner->state = Initial; textbuffer_putc(&scanner->buf, '\0'); scanner->pos--; kw = in_word_set(scanner->buf.data, scanner->buf.pos-1); if(kw) { /* we got a keyword */ TOKEN_SET(lvalp, cstring, kw->name); return kw->val; } /* it is not a keyword, just an identifier */ TOKEN_SET(lvalp, cstring, NULL); return TOK_IDENTIFIER_NAME; } } scanner->state = Identifier; return 0; }
static inline int parseNumber(YYSTYPE *lvalp, yyscan_t scanner) { const unsigned char *in = (const unsigned char*)scanner->in; int is_float = 0; while(scanner->pos < scanner->insize) { unsigned char c = in[scanner->pos++]; if(isdigit(c)) { textbuffer_putc(&scanner->buf, c); continue; } if(c =='.' && !is_float) { is_float = 1; textbuffer_putc(&scanner->buf, '.'); continue; } if((c=='e' || c=='E') && is_float) { textbuffer_putc(&scanner->buf, c); if(scanner->pos < scanner->insize) { c = in[scanner->pos++]; if(c == '+' || c == '-' || isdigit(c)) { textbuffer_putc(&scanner->buf, c); continue; } } } scanner->pos--; textbuffer_putc(&scanner->buf, '\0'); scanner->state = Initial; if (!scanner->buf.data) return 0; if(is_float) { TOKEN_SET(lvalp, dval, atof(scanner->buf.data)); return TOK_NumericFloat; } else { TOKEN_SET(lvalp, ival, atoi(scanner->buf.data)); return TOK_NumericInt; } } scanner->state = Number; return 0; }
END_TEST START_TEST (test_normalize) { const char *str = "test\\0\\b\\t\\n\\v\\f\\r\\z\\x2a\\u1234test"; const char *expected ="test\x1\b\t\n\v\f\rz\x2a\xe1\x88\xb4test"; int rc; rc = cli_textbuffer_append_normalize(&buf, str, strlen(str)); fail_unless(rc != -1, "normalize"); fail_unless(textbuffer_putc(&buf, '\0') != -1, "putc \\0"); fail_unless(buf.data && !strcmp(buf.data, expected), "normalized text"); }