/* We regard non-alphanumerics as equiv. */ static bool typematch(const char *a, const char *b) { size_t i; for (i = 0; a[i]; i++) { if (cisalnum(a[i])) { if (a[i] != b[i]) return false; } else { if (cisalnum(b[i])) return false; } } return b[i] == '\0'; }
/* Simplified tokenizer: comments and preproc directives removed, identifiers are a token, others are single char tokens. */ static struct token *tokenize(const void *ctx, const char *code) { unsigned int i, len, tok_start = -1; bool start_of_line = true; struct token *toks = tal_arr(ctx, struct token, 0); for (i = 0; code[i]; i += len) { if (code[i] == '#' && start_of_line) { /* Preprocessor line. */ len = strcspn(code+i, "\n"); } else if (code[i] == '/' && code[i+1] == '/') { /* One line comment. */ len = strcspn(code+i, "\n"); if (tok_start != -1U) { add_token(&toks, code+tok_start, i - tok_start); tok_start = -1U; } } else if (code[i] == '/' && code[i+1] == '*') { /* Multi-line comment. */ const char *end = strstr(code+i+2, "*/"); len = (end + 2) - (code + i); if (!end) len = strlen(code + i); if (tok_start != -1U) { add_token(&toks, code+tok_start, i - tok_start); tok_start = -1U; } } else if (cisalnum(code[i]) || code[i] == '_') { /* Identifier or part thereof */ if (tok_start == -1U) tok_start = i; len = 1; } else if (!cisspace(code[i])) { /* Punctuation: treat as single char token. */ if (tok_start != -1U) { add_token(&toks, code+tok_start, i - tok_start); tok_start = -1U; } add_token(&toks, code+i, 1); len = 1; } else { /* Whitespace. */ if (tok_start != -1U) { add_token(&toks, code+tok_start, i - tok_start); tok_start = -1U; } len = 1; } if (code[i] == '\n') start_of_line = true; else if (!cisspace(code[i])) start_of_line = false; } /* Add terminating NULL. */ tal_resizez(&toks, tal_count(toks) + 1); return toks; }
/* We only handle simple function definitions here. */ static char *add_func(char *others, const char *line) { const char *p, *end = strchr(line, '(') - 1; while (cisspace(*end)) { end--; if (end == line) return others; } for (p = end; cisalnum(*p) || *p == '_'; p--) { if (p == line) return others; } return talloc_asprintf_append(others, "printf(\"%%p\", %.*s);\n", (unsigned)(end - p), p+1); }
/* Get token if it's equal to token. */ bool get_token(const char **line, const char *token) { unsigned int toklen; *line += strspn(*line, " \t"); if (cisalnum(token[0]) || token[0] == '_') toklen = strspn(*line, IDENT_CHARS); else { /* FIXME: real tokenizer handles ++ and other multi-chars. */ toklen = strlen(token); } if (toklen == strlen(token) && !strncmp(*line, token, toklen)) { *line += toklen; return true; } return false; }
/* We only handle simple function definitions here. */ static char *add_func(const tal_t *ctx, char *others, const char *line) { const char *p, *end = strchr(line, '(') - 1; char *use; while (cisspace(*end)) { end--; if (end == line) return others; } for (p = end; cisalnum(*p) || *p == '_'; p--) { if (p == line) return others; } use = tal_fmt(ctx, "printf(\"%%p\", %.*s);\n", (unsigned)(end - p), p+1); if (others) use = tal_strcat(ctx, take(others), take(use)); return use; }