static void peek_char(struct buffer buff, char *c, const char **error) { if (is_eot(buff)) { raise_unexpected_eof(buff.offset, error); return; } *c = buff.data[buff.offset]; }
static struct buffer get_char(struct buffer buff, char * c, const char ** error) { if (is_eot(buff)) { raise_unexpected_eof(buff.offset, error); return buff; } *c = buff.data[buff.offset]; buff.offset++; return buff; }
static struct buffer expect_char(struct buffer buff, char c, const char ** error) { if ((unsigned)buff.offset >= buff.len) raise_unexpected_eof(buff.offset, error); else if (buff.data[buff.offset] != c) raise_unexpected_char( buff.offset, c, buff.data[buff.offset], error); else buff.offset++; return buff; }
void *libretrodb_query_compile(libretrodb_t *db, const char *query, size_t buff_len, const char **error) { struct buffer buff; struct query *q = (struct query*)malloc(sizeof(struct query)); if (!q) goto clean; memset(q, 0, sizeof(struct query)); q->ref_count = 1; buff.data = query; buff.len = buff_len; buff.offset = 0; *error = NULL; buff = chomp(buff); if (peek(buff, "{")) { buff = parse_table(buff, &q->root, error); if (*error) goto clean; } else if (isalpha(buff.data[buff.offset])) buff = parse_method_call(buff, &q->root, error); buff = expect_eof(buff, error); if (*error) goto clean; if (!q->root.func) { raise_unexpected_eof(buff.offset, error); return NULL; } goto success; clean: if (q) libretrodb_query_free(q); success: return q; }
static struct buffer get_ident(struct buffer buff, const char **ident, size_t *len, const char **error) { char c = '\0'; if (is_eot(buff)) { raise_unexpected_eof(buff.offset, error); return buff; } *ident = buff.data + buff.offset; *len = 0; peek_char(buff, &c, error); if (*error) goto clean; if (!isalpha((int)c)) return buff; buff.offset++; *len = *len + 1; peek_char(buff, &c, error); while (!*error) { if (!(isalpha((int)c) || isdigit((int)c) || c == '_')) break; buff.offset++; *len = *len + 1; peek_char(buff, &c, error); } clean: return buff; }