diff --git a/libretrodb/compat_fnmatch.c b/libretrodb/compat_fnmatch.c index 5d409a3da4..6c39b9b11b 100644 --- a/libretrodb/compat_fnmatch.c +++ b/libretrodb/compat_fnmatch.c @@ -35,8 +35,9 @@ int rl_fnmatch(const char *pattern, const char *string, int flags) { const char *c; - int charmatch = 0; int rv; + int charmatch = 0; + for (c = pattern; *c != '\0'; c++) { /* String ended before pattern */ diff --git a/libretrodb/dat_converter.c b/libretrodb/dat_converter.c index b3b849c2f3..428ff0ef0a 100644 --- a/libretrodb/dat_converter.c +++ b/libretrodb/dat_converter.c @@ -23,7 +23,8 @@ static char *strndup_(const char *s, size_t n) return buff; } -static struct rmsgpack_dom_value *get_map_value(const struct rmsgpack_dom_value *m, char* key) +static struct rmsgpack_dom_value *get_map_value( + const struct rmsgpack_dom_value *m, char* key) { struct rmsgpack_dom_value v; @@ -261,10 +262,12 @@ int main(int argc, char **argv) int rv = 0; int src = -1; int dst = -1; + if (argc != 3) printf("Usage: %s \n", argv[0]); src = open(argv[1], O_RDONLY); + if (src == -1) { printf("Could not open source file '%s': %s\n", argv[1], strerror(errno)); @@ -273,6 +276,7 @@ int main(int argc, char **argv) } dst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (dst == -1) { printf("Could not open destination file '%s': %s\n", argv[1], strerror(errno)); diff --git a/libretrodb/libretrodb.c b/libretrodb/libretrodb.c index 91166cb393..e9a9546d3f 100644 --- a/libretrodb/libretrodb.c +++ b/libretrodb/libretrodb.c @@ -20,124 +20,115 @@ #include "libretrodb_endian.h" #include "query.h" -struct node_iter_ctx { +struct node_iter_ctx +{ libretrodb_t *db; libretrodb_index_t *idx; }; static struct rmsgpack_dom_value sentinal; -static int libretrodb_read_metadata( - int fd, - libretrodb_metadata_t *md -){ - return rmsgpack_dom_read_into(fd, "count", &md->count, NULL); +static int libretrodb_read_metadata(int fd, libretrodb_metadata_t *md) +{ + return rmsgpack_dom_read_into(fd, "count", &md->count, NULL); } -static int libretrodb_write_metadata( - int fd, - libretrodb_metadata_t *md -){ - rmsgpack_write_map_header(fd, 1); - rmsgpack_write_string(fd, "count", strlen("count")); - return rmsgpack_write_uint(fd, md->count); +static int libretrodb_write_metadata(int fd, libretrodb_metadata_t *md) +{ + rmsgpack_write_map_header(fd, 1); + rmsgpack_write_string(fd, "count", strlen("count")); + return rmsgpack_write_uint(fd, md->count); } -static int validate_document(const struct rmsgpack_dom_value * doc) { - int rv = 0; - unsigned i; - struct rmsgpack_dom_value key; - struct rmsgpack_dom_value value; +static int validate_document(const struct rmsgpack_dom_value * doc) +{ + unsigned i; + struct rmsgpack_dom_value key; + struct rmsgpack_dom_value value; + int rv = 0; - if (doc->type != RDT_MAP) { - return -EINVAL; - } + if (doc->type != RDT_MAP) + return -EINVAL; - for (i = 0; i < doc->map.len; i++) { - key = doc->map.items[i].key; - value = doc->map.items[i].value; - if (key.type != RDT_STRING) { - return -EINVAL; - } - if (key.string.len <= 0) { - return -EINVAL; - } - if (key.string.buff[0] == '$') { - return -EINVAL; - } + for (i = 0; i < doc->map.len; i++) + { + key = doc->map.items[i].key; + value = doc->map.items[i].value; - if (value.type == RDT_MAP) { - if ((rv == validate_document(&value)) != 0) { - return rv; - } - } - } + if (key.type != RDT_STRING) + return -EINVAL; - return rv; + if (key.string.len <= 0) + return -EINVAL; + + if (key.string.buff[0] == '$') + return -EINVAL; + + if (value.type != RDT_MAP) + continue; + + if ((rv == validate_document(&value)) != 0) + return rv; + } + + return rv; } -int libretrodb_create( - int fd, - libretrodb_value_provider value_provider, - void * ctx -){ - int rv; - off_t root; - libretrodb_metadata_t md; - uint64_t item_count = 0; - struct rmsgpack_dom_value item = {}; - libretrodb_header_t header = {}; +int libretrodb_create(int fd, libretrodb_value_provider value_provider, + void * ctx) +{ + int rv; + off_t root; + libretrodb_metadata_t md; + uint64_t item_count = 0; + struct rmsgpack_dom_value item = {}; + libretrodb_header_t header = {}; - memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); - root = lseek(fd, 0, SEEK_CUR); + memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); + root = lseek(fd, 0, SEEK_CUR); - /* We write the header in the end because we need to know the size of + /* We write the header in the end because we need to know the size of * the db first */ - lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR); + lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR); - while ((rv = value_provider(ctx, &item)) == 0) { + while ((rv = value_provider(ctx, &item)) == 0) + { + if ((rv = validate_document(&item)) < 0) + goto clean; - if ((rv = validate_document(&item)) < 0) - goto clean; + if ((rv = rmsgpack_dom_write(fd, &item)) < 0) + goto clean; - if ((rv = rmsgpack_dom_write(fd, &item)) < 0) - goto clean; + item_count++; + } - item_count++; - } + if (rv < 0) + goto clean; - if (rv < 0) - goto clean; + if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0) + goto clean; - if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0) - goto clean; - - header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR)); - md.count = item_count; - libretrodb_write_metadata(fd, &md); - lseek(fd, root, SEEK_SET); - write(fd, &header, sizeof(header)); + header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR)); + md.count = item_count; + libretrodb_write_metadata(fd, &md); + lseek(fd, root, SEEK_SET); + write(fd, &header, sizeof(header)); clean: - rmsgpack_dom_value_free(&item); - return rv; + rmsgpack_dom_value_free(&item); + return rv; } -static int libretrodb_read_index_header( - int fd, libretrodb_index_t *idx) +static int libretrodb_read_index_header(int fd, libretrodb_index_t *idx) { - uint64_t name_len = 50; - return rmsgpack_dom_read_into( - fd, - "name", idx->name, &name_len, - "key_size", &idx->key_size, - "next", &idx->next, - NULL - ); + uint64_t name_len = 50; + return rmsgpack_dom_read_into(fd, + "name", idx->name, &name_len, + "key_size", &idx->key_size, + "next", &idx->next, NULL); } -static void libretrodb_write_index_header( - int fd, libretrodb_index_t * idx) +static void libretrodb_write_index_header(int fd, libretrodb_index_t * idx) { rmsgpack_write_map_header(fd, 3); rmsgpack_write_string(fd, "name", strlen("name")); @@ -154,54 +145,55 @@ void libretrodb_close(libretrodb_t * db) db->fd = -1; } -int libretrodb_open( - const char * path, - libretrodb_t * db -) +int libretrodb_open(const char * path, libretrodb_t * db) { - libretrodb_header_t header; - libretrodb_metadata_t md; - int rv; - int fd = open(path, O_RDWR); + libretrodb_header_t header; + libretrodb_metadata_t md; + int rv; + int fd = open(path, O_RDWR); - if (fd == -1) - return -errno; + if (fd == -1) + return -errno; - db->root = lseek(fd, 0, SEEK_CUR); - if ((rv = read(fd, &header, sizeof(header))) == -1) { - rv = -errno; - goto error; - } + db->root = lseek(fd, 0, SEEK_CUR); - if (strncmp(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)) != 0) { - rv = -EINVAL; - goto error; - } + if ((rv = read(fd, &header, sizeof(header))) == -1) + { + rv = -errno; + goto error; + } - header.metadata_offset = betoht64(header.metadata_offset); - lseek(fd, header.metadata_offset, SEEK_SET); - if (libretrodb_read_metadata(fd, &md) < 0) { - rv = -EINVAL; - goto error; - } - db->count = md.count; - db->first_index_offset = lseek(fd, 0, SEEK_CUR); - db->fd = fd; - return 0; + if (strncmp(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)) != 0) + { + rv = -EINVAL; + goto error; + } + + header.metadata_offset = betoht64(header.metadata_offset); + lseek(fd, header.metadata_offset, SEEK_SET); + + if (libretrodb_read_metadata(fd, &md) < 0) + { + rv = -EINVAL; + goto error; + } + + db->count = md.count; + db->first_index_offset = lseek(fd, 0, SEEK_CUR); + db->fd = fd; + return 0; error: - close(fd); - return rv; + close(fd); + return rv; } -static int libretrodb_find_index( - libretrodb_t *db, - const char *index_name, - libretrodb_index_t *idx -){ - off_t eof = lseek(db->fd, 0, SEEK_END); - off_t offset = lseek(db->fd, db->first_index_offset, SEEK_SET); +static int libretrodb_find_index(libretrodb_t *db, const char *index_name, + libretrodb_index_t *idx) +{ + off_t eof = lseek(db->fd, 0, SEEK_END); + off_t offset = lseek(db->fd, db->first_index_offset, SEEK_SET); - while (offset < eof) + while (offset < eof) { libretrodb_read_index_header(db->fd, idx); if (strncmp(index_name, idx->name, strlen(idx->name)) == 0) @@ -209,83 +201,79 @@ static int libretrodb_find_index( offset = lseek(db->fd, idx->next, SEEK_CUR); } - return -1; + return -1; } -static int node_compare( - const void * a, - const void * b, - void * ctx -){ - return memcmp(a, b, *(uint8_t *)ctx); +static int node_compare(const void * a, const void * b, void * ctx) +{ + return memcmp(a, b, *(uint8_t *)ctx); } -static int binsearch( - const void * buff, - const void * item, - uint64_t count, - uint8_t field_size, - uint64_t * offset -){ - int mid = count / 2; - int item_size = field_size + sizeof(uint64_t); - uint64_t * current = (uint64_t *)buff + (mid * item_size); - int rv = node_compare(current, item, &field_size); +static int binsearch(const void * buff, const void * item, + uint64_t count, uint8_t field_size, uint64_t * offset) +{ + int mid = count / 2; + int item_size = field_size + sizeof(uint64_t); + uint64_t * current = (uint64_t *)buff + (mid * item_size); + int rv = node_compare(current, item, &field_size); - if (rv == 0) { - *offset = *(uint64_t *)(current + field_size); - return 0; - } else if (count == 0) - return -1; - else if (rv > 0) - return binsearch(buff, item, mid, field_size, offset); + if (rv == 0) + { + *offset = *(uint64_t *)(current + field_size); + return 0; + } + else if (count == 0) + return -1; + else if (rv > 0) + return binsearch(buff, item, mid, field_size, offset); - return binsearch(current + item_size, item, count - mid, field_size, offset); + return binsearch(current + item_size, item, + count - mid, field_size, offset); } -int libretrodb_find_entry( - libretrodb_t *db, - const char *index_name, - const void *key, - struct rmsgpack_dom_value * out -) { - libretrodb_index_t idx; - int rv; - void * buff; - uint64_t offset; - ssize_t bufflen, nread = 0; +int libretrodb_find_entry(libretrodb_t *db, const char *index_name, + const void *key, struct rmsgpack_dom_value *out) +{ + libretrodb_index_t idx; + int rv; + void * buff; + uint64_t offset; + ssize_t bufflen, nread = 0; - if (libretrodb_find_index(db, index_name, &idx) < 0) - return -1; + if (libretrodb_find_index(db, index_name, &idx) < 0) + return -1; - bufflen = idx.next; - buff = malloc(bufflen); + bufflen = idx.next; + buff = malloc(bufflen); - if (!buff) - return -ENOMEM; + if (!buff) + return -ENOMEM; - while (nread < bufflen) { - void * buff_ = (uint64_t *)buff + nread; - rv = read(db->fd, buff_, bufflen - nread); - if (rv <= 0) { - free(buff); - return -errno; - } - nread += rv; - } + while (nread < bufflen) + { + void * buff_ = (uint64_t *)buff + nread; + rv = read(db->fd, buff_, bufflen - nread); - rv = binsearch(buff, key, db->count, idx.key_size, &offset); - free(buff); + if (rv <= 0) + { + free(buff); + return -errno; + } + nread += rv; + } - if (rv == 0) - lseek(db->fd, offset, SEEK_SET); + rv = binsearch(buff, key, db->count, idx.key_size, &offset); + free(buff); - rv = rmsgpack_dom_read(db->fd, out); - if (rv < 0) - return rv; + if (rv == 0) + lseek(db->fd, offset, SEEK_SET); + + rv = rmsgpack_dom_read(db->fd, out); + if (rv < 0) + return rv; - return rv; + return rv; } /** @@ -299,38 +287,37 @@ int libretrodb_find_entry( int libretrodb_cursor_reset(libretrodb_cursor_t *cursor) { cursor->eof = 0; - return lseek( - cursor->fd, - cursor->db->root + sizeof(libretrodb_header_t), - SEEK_SET - ); + return lseek(cursor->fd, + cursor->db->root + sizeof(libretrodb_header_t), + SEEK_SET); } -int libretrodb_cursor_read_item( - libretrodb_cursor_t *cursor, - struct rmsgpack_dom_value * out -) { - int rv; - if (cursor->eof) - return EOF; +int libretrodb_cursor_read_item(libretrodb_cursor_t *cursor, + struct rmsgpack_dom_value * out) +{ + int rv; + + if (cursor->eof) + return EOF; retry: - rv = rmsgpack_dom_read(cursor->fd, out); - if (rv < 0) - return rv; + rv = rmsgpack_dom_read(cursor->fd, out); + if (rv < 0) + return rv; - if (out->type == RDT_NULL) { - cursor->eof = 1; - return EOF; - } + if (out->type == RDT_NULL) + { + cursor->eof = 1; + return EOF; + } - if (cursor->query) { - if (!libretrodb_query_filter(cursor->query, out)) { - goto retry; - } - } + if (cursor->query) + { + if (!libretrodb_query_filter(cursor->query, out)) + goto retry; + } - return 0; + return 0; } /** @@ -398,11 +385,9 @@ static uint64_t libretrodb_tell(libretrodb_t *db) return lseek(db->fd, 0, SEEK_CUR); } -int libretrodb_create_index( - libretrodb_t *db, - const char *name, - const char *field_name -){ +int libretrodb_create_index(libretrodb_t *db, + const char *name, const char *field_name) +{ int rv; struct node_iter_ctx nictx; struct rmsgpack_dom_value key; @@ -411,14 +396,16 @@ int libretrodb_create_index( struct rmsgpack_dom_value * field; struct bintree tree; libretrodb_cursor_t cur; + uint64_t idx_header_offset; void * buff = NULL; uint64_t * buff_u64 = NULL; uint8_t field_size = 0; - uint64_t idx_header_offset; uint64_t item_loc = libretrodb_tell(db); bintree_new(&tree, node_compare, &field_size); - if (libretrodb_cursor_open(db, &cur, NULL) != 0) { + + if (libretrodb_cursor_open(db, &cur, NULL) != 0) + { rv = -1; goto clean; } @@ -427,25 +414,33 @@ int libretrodb_create_index( key.string.len = strlen(field_name); /* We know we aren't going to change it */ key.string.buff = (char *) field_name; - while (libretrodb_cursor_read_item(&cur, &item) == 0) { - if (item.type != RDT_MAP) { + while (libretrodb_cursor_read_item(&cur, &item) == 0) + { + if (item.type != RDT_MAP) + { rv = -EINVAL; printf("Only map keys are supported\n"); goto clean; } + field = rmsgpack_dom_value_map_value(&item, &key); - if (!field) { + + if (!field) + { rv = -EINVAL; printf("field not found in item\n"); goto clean; } - if (field->type != RDT_BINARY) { + + if (field->type != RDT_BINARY) + { rv = -EINVAL; printf("field is not binary\n"); goto clean; } - if (field->binary.len == 0) { + if (field->binary.len == 0) + { rv = -EINVAL; printf("field is empty\n"); goto clean; @@ -453,14 +448,16 @@ int libretrodb_create_index( if (field_size == 0) field_size = field->binary.len; - else if (field->binary.len != field_size) { + else if (field->binary.len != field_size) + { rv = -EINVAL; printf("field is not of correct size\n"); goto clean; } buff = malloc(field_size + sizeof(uint64_t)); - if (!buff) { + if (!buff) + { rv = -ENOMEM; goto clean; } @@ -469,7 +466,8 @@ int libretrodb_create_index( buff_u64 = (uint64_t *)buff + field_size; memcpy(buff_u64, &item_loc, sizeof(uint64_t)); - if (bintree_insert(&tree, buff) != 0) { + if (bintree_insert(&tree, buff) != 0) + { printf("Value is not unique: "); rmsgpack_dom_value_print(field); printf("\n"); @@ -500,8 +498,7 @@ clean: rmsgpack_dom_value_free(&item); if (buff) free(buff); - if (cur.is_valid) { + if (cur.is_valid) libretrodb_cursor_close(&cur); - } return 0; } diff --git a/libretrodb/libretrodb.h b/libretrodb/libretrodb.h index 024b840e7a..43eb341a28 100644 --- a/libretrodb/libretrodb.h +++ b/libretrodb/libretrodb.h @@ -52,29 +52,19 @@ typedef struct libretrodb_cursor libretrodb_t * db; } libretrodb_cursor_t; -typedef int (* libretrodb_value_provider)( - void * ctx, - struct rmsgpack_dom_value * out -); +typedef int (* libretrodb_value_provider)(void * ctx, + struct rmsgpack_dom_value * out); -int libretrodb_create( - int fd, - libretrodb_value_provider value_provider, - void * ctx -); +int libretrodb_create(int fd, libretrodb_value_provider value_provider, + void * ctx); void libretrodb_close(libretrodb_t * db); -int libretrodb_open( - const char * path, - libretrodb_t * db -); +int libretrodb_open(const char * path, libretrodb_t * db); + +int libretrodb_create_index(libretrodb_t * db, const char *name, + const char *field_name); -int libretrodb_create_index( - libretrodb_t * db, - const char * name, - const char * field_name -); int libretrodb_find_entry( libretrodb_t * db, const char * index_name, @@ -125,10 +115,8 @@ void *libretrodb_query_compile( void libretrodb_query_free(void *q); -int libretrodb_cursor_read_item( - libretrodb_cursor_t * cursor, - struct rmsgpack_dom_value * out -); +int libretrodb_cursor_read_item(libretrodb_cursor_t * cursor, + struct rmsgpack_dom_value * out); #ifdef __cplusplus } diff --git a/libretrodb/libretrodb_tool.c b/libretrodb/libretrodb_tool.c index 3ba6b393a2..442ccb6240 100644 --- a/libretrodb/libretrodb_tool.c +++ b/libretrodb/libretrodb_tool.c @@ -4,88 +4,104 @@ #include "libretrodb.h" #include "rmsgpack_dom.h" -int main( - int argc, - char ** argv -){ - int rv; - libretrodb_t db; - libretrodb_cursor_t cur; +int main(int argc, char ** argv) +{ + int rv; + libretrodb_t db; + libretrodb_cursor_t cur; libretrodb_query_t *q; - struct rmsgpack_dom_value item; + struct rmsgpack_dom_value item; const char *command, *path, *query_exp, *error; - if (argc < 3) { - printf("Usage: %s [extra args...]\n", argv[0]); - printf("Available Commands:\n"); - printf("\tlist\n"); - printf("\tcreate-index \n"); - printf("\tfind \n"); - return 1; - } + if (argc < 3) + { + printf("Usage: %s [extra args...]\n", argv[0]); + printf("Available Commands:\n"); + printf("\tlist\n"); + printf("\tcreate-index \n"); + printf("\tfind \n"); + return 1; + } - command = argv[2]; - path = argv[1]; + command = argv[2]; + path = argv[1]; - if ((rv = libretrodb_open(path, &db)) != 0) { - printf("Could not open db file '%s': %s\n", path, strerror(-rv)); - return 1; - } else if (strcmp(command, "list") == 0) { - if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0) { - printf("Could not open cursor: %s\n", strerror(-rv)); - return 1; - } - - if (argc != 3) { - printf("Usage: %s list\n", argv[0]); - return 1; - } - while (libretrodb_cursor_read_item(&cur, &item) == 0) { - rmsgpack_dom_value_print(&item); - printf("\n"); - rmsgpack_dom_value_free(&item); - } - } else if (strcmp(command, "find") == 0) { - if (argc != 4) { - printf("Usage: %s find \n", argv[0]); - return 1; - } - - query_exp = argv[3]; - error = NULL; - q = libretrodb_query_compile(&db, query_exp, strlen(query_exp), &error); - if (error) { - printf("%s\n", error); - return 1; - } - - if ((rv = libretrodb_cursor_open(&db, &cur, q)) != 0) + if ((rv = libretrodb_open(path, &db)) != 0) + { + printf("Could not open db file '%s': %s\n", path, strerror(-rv)); + return 1; + } + else if (strcmp(command, "list") == 0) + { + if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0) { - printf("Could not open cursor: %s\n", strerror(-rv)); - return 1; - } + printf("Could not open cursor: %s\n", strerror(-rv)); + return 1; + } - while (libretrodb_cursor_read_item(&cur, &item) == 0) + if (argc != 3) { - rmsgpack_dom_value_print(&item); - printf("\n"); - rmsgpack_dom_value_free(&item); - } - } else if (strcmp(command, "create-index") == 0) { - const char * index_name, * field_name; + printf("Usage: %s list\n", argv[0]); + return 1; + } - if (argc != 5) { - printf("Usage: %s create-index \n", argv[0]); - return 1; - } + while (libretrodb_cursor_read_item(&cur, &item) == 0) + { + rmsgpack_dom_value_print(&item); + printf("\n"); + rmsgpack_dom_value_free(&item); + } + } + else if (strcmp(command, "find") == 0) + { + if (argc != 4) + { + printf("Usage: %s find \n", argv[0]); + return 1; + } - index_name = argv[3]; - field_name = argv[4]; + query_exp = argv[3]; + error = NULL; + q = libretrodb_query_compile(&db, query_exp, strlen(query_exp), &error); - libretrodb_create_index(&db, index_name, field_name); - } else { - printf("Unkonwn command %s\n", argv[2]); - return 1; - } - libretrodb_close(&db); + if (error) + { + printf("%s\n", error); + return 1; + } + + if ((rv = libretrodb_cursor_open(&db, &cur, q)) != 0) + { + printf("Could not open cursor: %s\n", strerror(-rv)); + return 1; + } + + while (libretrodb_cursor_read_item(&cur, &item) == 0) + { + rmsgpack_dom_value_print(&item); + printf("\n"); + rmsgpack_dom_value_free(&item); + } + } + else if (strcmp(command, "create-index") == 0) + { + const char * index_name, * field_name; + + if (argc != 5) + { + printf("Usage: %s create-index \n", argv[0]); + return 1; + } + + index_name = argv[3]; + field_name = argv[4]; + + libretrodb_create_index(&db, index_name, field_name); + } + else + { + printf("Unkonwn command %s\n", argv[2]); + return 1; + } + libretrodb_close(&db); } diff --git a/libretrodb/query.c b/libretrodb/query.c index a0fe5f4a16..f9f75b2b9b 100644 --- a/libretrodb/query.c +++ b/libretrodb/query.c @@ -19,147 +19,113 @@ static char tmp_error_buff [MAX_ERROR_LEN] = {}; -struct buffer { +struct buffer +{ const char * data; size_t len; off_t offset; }; /* Errors */ -static void raise_too_many_arguments(const char ** error) { - snprintf( - tmp_error_buff, - MAX_ERROR_LEN, - "Too many arguments in function call" - ); +static void raise_too_many_arguments(const char ** error) +{ + snprintf(tmp_error_buff, MAX_ERROR_LEN, + "Too many arguments in function call."); *error = tmp_error_buff; } -static void raise_expected_number( - off_t where, - const char ** error -) { - snprintf( - tmp_error_buff, - MAX_ERROR_LEN, +static void raise_expected_number(off_t where, const char ** error) +{ + snprintf(tmp_error_buff, MAX_ERROR_LEN, #ifdef _WIN32 - "%I64u::Expected number", + "%I64u::Expected number", #else - "%llu::Expected number", + "%llu::Expected number", #endif - (unsigned long long)where - ); - *error = tmp_error_buff; + (unsigned long long)where); + *error = tmp_error_buff; } -static void raise_expected_string( - off_t where, - const char ** error -) { - snprintf( - tmp_error_buff, - MAX_ERROR_LEN, +static void raise_expected_string(off_t where, const char ** error) +{ + snprintf(tmp_error_buff, MAX_ERROR_LEN, #ifdef _WIN32 - "%I64u::Expected string", + "%I64u::Expected string", #else - "%llu::Expected string", + "%llu::Expected string", #endif - (unsigned long long)where - ); - *error = tmp_error_buff; + (unsigned long long)where); + *error = tmp_error_buff; } -static void raise_unexpected_eof( - off_t where, - const char ** error -) { - snprintf( - tmp_error_buff, - MAX_ERROR_LEN, +static void raise_unexpected_eof(off_t where, const char ** error) +{ + snprintf(tmp_error_buff, MAX_ERROR_LEN, #ifdef _WIN32 - "%I64u::Unexpected EOF", + "%I64u::Unexpected EOF", #else - "%llu::Unexpected EOF", + "%llu::Unexpected EOF", #endif - (unsigned long long)where - ); - *error = tmp_error_buff; + (unsigned long long)where + ); + *error = tmp_error_buff; } -static void raise_enomem(const char ** error) { - snprintf( - tmp_error_buff, - MAX_ERROR_LEN, - "Out of memory" - ); - *error = tmp_error_buff; +static void raise_enomem(const char ** error) +{ + snprintf(tmp_error_buff, MAX_ERROR_LEN, "Out of memory"); + *error = tmp_error_buff; } -static void raise_unknown_function( - off_t where, - const char * name, - size_t len, - const char ** error -) { - int n = snprintf( - tmp_error_buff, - MAX_ERROR_LEN, +static void raise_unknown_function(off_t where, const char * name, + size_t len, const char ** error) +{ + int n = snprintf(tmp_error_buff, MAX_ERROR_LEN, #ifdef _WIN32 - "%I64u::Unknown function '", + "%I64u::Unknown function '", #else - "%llu::Unknown function '", + "%llu::Unknown function '", #endif - (unsigned long long)where - ); - if (len < (MAX_ERROR_LEN - n - 3)) { - strncpy(tmp_error_buff + n, name, len); - } - strcpy(tmp_error_buff + n + len, "'"); - *error = tmp_error_buff; + (unsigned long long)where + ); + + if (len < (MAX_ERROR_LEN - n - 3)) + strncpy(tmp_error_buff + n, name, len); + + strcpy(tmp_error_buff + n + len, "'"); + *error = tmp_error_buff; } -static void raise_expected_eof( - off_t where, - char found, - const char ** error -) { - snprintf( - tmp_error_buff, - MAX_ERROR_LEN, +static void raise_expected_eof(off_t where, char found, const char ** error) +{ + snprintf(tmp_error_buff, MAX_ERROR_LEN, #ifdef _WIN32 - "%I64u::Expected EOF found '%c'", + "%I64u::Expected EOF found '%c'", #else - "%llu::Expected EOF found '%c'", + "%llu::Expected EOF found '%c'", #endif - (unsigned long long)where, - found - ); - *error = tmp_error_buff; + (unsigned long long)where, + found + ); + *error = tmp_error_buff; } -static void raise_unexpected_char( - off_t where, - char expected, - char found, - const char ** error -) { - snprintf( - tmp_error_buff, - MAX_ERROR_LEN, +static void raise_unexpected_char(off_t where, char expected, char found, + const char ** error) +{ + snprintf(tmp_error_buff, MAX_ERROR_LEN, #ifdef _WIN32 - "%I64u::Expected '%c' found '%c'", + "%I64u::Expected '%c' found '%c'", #else - "%llu::Expected '%c' found '%c'", + "%llu::Expected '%c' found '%c'", #endif - (unsigned long long)where, - expected, - found - ); - *error = tmp_error_buff; + (unsigned long long)where, expected, found); + *error = tmp_error_buff; } -enum argument_type { - AT_FUNCTION, - AT_VALUE +enum argument_type +{ + AT_FUNCTION, + AT_VALUE }; struct argument; @@ -170,210 +136,210 @@ typedef struct rmsgpack_dom_value (* rarch_query_func)( const struct argument * argv ); -struct invocation { +struct invocation +{ rarch_query_func func; unsigned argc; struct argument * argv; }; -struct argument { +struct argument +{ enum argument_type type; - union { + union + { struct rmsgpack_dom_value value; struct invocation invocation; }; }; -static void argument_free(struct argument * arg) { - unsigned i; - if (arg->type == AT_FUNCTION) { - for (i = 0; i < arg->invocation.argc; i++) { - argument_free(&arg->invocation.argv[i]); - } - } else { - rmsgpack_dom_value_free(&arg->value); - } +static void argument_free(struct argument * arg) +{ + unsigned i; + + if (arg->type != AT_FUNCTION) + { + rmsgpack_dom_value_free(&arg->value); + return; + + } + + for (i = 0; i < arg->invocation.argc; i++) + argument_free(&arg->invocation.argv[i]); } - -struct query { +struct query +{ unsigned ref_count; struct invocation root; }; -struct registered_func { +struct registered_func +{ const char * name; rarch_query_func func; }; -static struct buffer parse_argument( - struct buffer buff, - struct argument * arg, - const char ** error -); +static struct buffer parse_argument(struct buffer buff, struct argument * arg, + const char ** error); -static struct rmsgpack_dom_value is_true( - struct rmsgpack_dom_value input, - unsigned argc, - const struct argument * argv -) { - struct rmsgpack_dom_value res; - res.type = RDT_BOOL; - res.bool_ = 0; - if (argc > 0 || input.type != RDT_BOOL) { - res.bool_ = 0; - } else { - res.bool_ = input.bool_; - } - return res; +static struct rmsgpack_dom_value is_true(struct rmsgpack_dom_value input, + unsigned argc, const struct argument * argv) +{ + struct rmsgpack_dom_value res; + + res.type = RDT_BOOL; + res.bool_ = 0; + + if (argc > 0 || input.type != RDT_BOOL) + res.bool_ = 0; + else + res.bool_ = input.bool_; + + return res; } -static struct rmsgpack_dom_value equals ( - struct rmsgpack_dom_value input, - unsigned argc, - const struct argument * argv -) { - struct rmsgpack_dom_value res; - struct argument arg; - res.type = RDT_BOOL; - if (argc != 1) { - res.bool_ = 0; - } else { - arg = argv[0]; - if (arg.type != AT_VALUE) { - res.bool_ = 0; - } else { - if (input.type == RDT_UINT && arg.value.type == RDT_INT) { - arg.value.type = RDT_UINT; - arg.value.uint_ = arg.value.int_; - } - res.bool_ = (rmsgpack_dom_value_cmp(&input, &arg.value) == 0); - } - } - return res; +static struct rmsgpack_dom_value equals(struct rmsgpack_dom_value input, + unsigned argc, const struct argument * argv) +{ + struct rmsgpack_dom_value res; + struct argument arg; + + res.type = RDT_BOOL; + + if (argc != 1) + res.bool_ = 0; + else + { + arg = argv[0]; + + if (arg.type != AT_VALUE) + res.bool_ = 0; + else + { + if (input.type == RDT_UINT && arg.value.type == RDT_INT) + { + arg.value.type = RDT_UINT; + arg.value.uint_ = arg.value.int_; + } + res.bool_ = (rmsgpack_dom_value_cmp(&input, &arg.value) == 0); + } + } + return res; } -static struct rmsgpack_dom_value operator_or ( - struct rmsgpack_dom_value input, - unsigned argc, - const struct argument * argv -) { - struct rmsgpack_dom_value res; - unsigned i; - res.type = RDT_BOOL; - res.bool_ = 0; - for (i = 0; i < argc; i++) { - if (argv[i].type == AT_VALUE) { - res = equals(input, 1, &argv[i]); - } else { - res = is_true( - argv[i].invocation.func(input, - argv[i].invocation.argc, - argv[i].invocation.argv - ), - 0, - NULL - ); - } +static struct rmsgpack_dom_value operator_or(struct rmsgpack_dom_value input, + unsigned argc, const struct argument * argv) +{ + struct rmsgpack_dom_value res; + unsigned i; - if (res.bool_) { - return res; - } - } - return res; + res.type = RDT_BOOL; + res.bool_ = 0; + + for (i = 0; i < argc; i++) + { + if (argv[i].type == AT_VALUE) + res = equals(input, 1, &argv[i]); + else + { + res = is_true(argv[i].invocation.func(input, + argv[i].invocation.argc, + argv[i].invocation.argv + ), 0, NULL); + } + + if (res.bool_) + return res; + } + + return res; } -static struct rmsgpack_dom_value between ( - struct rmsgpack_dom_value input, - unsigned argc, - const struct argument * argv -) { - struct rmsgpack_dom_value res; - unsigned i = 0; - res.type = RDT_BOOL; - res.bool_ = 0; +static struct rmsgpack_dom_value between(struct rmsgpack_dom_value input, + unsigned argc, const struct argument * argv) +{ + struct rmsgpack_dom_value res; + unsigned i = 0; + res.type = RDT_BOOL; + res.bool_ = 0; (void)i; - if (argc != 2) { - return res; - } - if (argv[0].type != AT_VALUE || argv[1].type != AT_VALUE) { - return res; - } - if (argv[0].value.type != RDT_INT || argv[1].value.type != RDT_INT) { - return res; - } - switch (input.type) { - case RDT_INT: - res.bool_ = input.int_ >= argv[0].value.int_ && input.int_ <= argv[1].value.int_; - break; - case RDT_UINT: - res.bool_ = input.int_ >= argv[0].value.uint_ && input.int_ <= argv[1].value.int_; - break; - default: - return res; - } - return res; + if (argc != 2) + return res; + if (argv[0].type != AT_VALUE || argv[1].type != AT_VALUE) + return res; + if (argv[0].value.type != RDT_INT || argv[1].value.type != RDT_INT) + return res; + + switch (input.type) + { + case RDT_INT: + res.bool_ = input.int_ >= argv[0].value.int_ && input.int_ <= argv[1].value.int_; + break; + case RDT_UINT: + res.bool_ = input.int_ >= argv[0].value.uint_ && input.int_ <= argv[1].value.int_; + break; + default: + return res; + } + + return res; } -static struct rmsgpack_dom_value operator_and ( - struct rmsgpack_dom_value input, - unsigned argc, - const struct argument * argv -) { - struct rmsgpack_dom_value res; - unsigned i; - res.type = RDT_BOOL; - res.bool_ = 0; - for (i = 0; i < argc; i++) { - if (argv[i].type == AT_VALUE) { - res = equals(input, 1, &argv[i]); - } else { - res = is_true( - argv[i].invocation.func(input, - argv[i].invocation.argc, - argv[i].invocation.argv - ), - 0, - NULL - ); - } +static struct rmsgpack_dom_value operator_and(struct rmsgpack_dom_value input, + unsigned argc, const struct argument * argv) +{ + struct rmsgpack_dom_value res; + unsigned i; - if (!res.bool_) { - return res; - } - } - return res; + res.type = RDT_BOOL; + res.bool_ = 0; + + for (i = 0; i < argc; i++) + { + if (argv[i].type == AT_VALUE) + res = equals(input, 1, &argv[i]); + else + { + res = is_true( + argv[i].invocation.func(input, + argv[i].invocation.argc, + argv[i].invocation.argv + ), + 0, NULL); + } + + if (!res.bool_) + return res; + } + return res; } -static struct rmsgpack_dom_value q_glob ( - struct rmsgpack_dom_value input, - unsigned argc, - const struct argument * argv -) { - struct rmsgpack_dom_value res; - unsigned i = 0; - res.type = RDT_BOOL; - res.bool_ = 0; +static struct rmsgpack_dom_value q_glob(struct rmsgpack_dom_value input, + unsigned argc, const struct argument * argv) +{ + struct rmsgpack_dom_value res; + unsigned i = 0; + + res.type = RDT_BOOL; + res.bool_ = 0; (void)i; - if (argc != 1) { - return res; - } - if (argv[0].type != AT_VALUE || argv[0].value.type != RDT_STRING) { - return res; - } - if (input.type != RDT_STRING) { - return res; - } - res.bool_ = rl_fnmatch( - argv[0].value.string.buff, - input.string.buff, - 0 - ) == 0; - return res; + if (argc != 1) + return res; + if (argv[0].type != AT_VALUE || argv[0].value.type != RDT_STRING) + return res; + if (input.type != RDT_STRING) + return res; + res.bool_ = rl_fnmatch( + argv[0].value.string.buff, + input.string.buff, + 0 + ) == 0; + return res; } static struct rmsgpack_dom_value all_map ( @@ -444,73 +410,57 @@ static struct buffer chomp(struct buffer buff) { return buff; } -static struct buffer expect_char( - struct buffer buff, - char c, - const char ** error -) { - if (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; +static struct buffer expect_char(struct buffer buff, + char c, const char ** error) +{ + if (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; } -static struct buffer expect_eof( - struct buffer buff, - const char ** error -) { - buff = chomp(buff); - if (buff.offset < buff.len) { - raise_expected_eof(buff.offset, buff.data[buff.offset], error); - } - return buff; +static struct buffer expect_eof(struct buffer buff, const char ** error) +{ + buff = chomp(buff); + if (buff.offset < buff.len) + raise_expected_eof(buff.offset, buff.data[buff.offset], error); + return buff; } static struct buffer parse_table( - struct buffer buff, - struct invocation * invocation, - const char ** error + struct buffer buff, struct invocation * invocation, + const char ** error ); -static int peek( - struct buffer buff, - const char * data -) { - size_t remain = buff.len - buff.offset; - if (remain < strlen(data)) { - return 0; - } - return (strncmp( - buff.data + buff.offset, - data, - strlen(data) - ) == 0); +static int peek(struct buffer buff, const char * data) +{ + size_t remain = buff.len - buff.offset; + + if (remain < strlen(data)) + return 0; + + return (strncmp(buff.data + buff.offset, + data, strlen(data)) == 0); } -static int is_eot(struct buffer buff) { - return (buff.offset >= buff.len); +static int is_eot(struct buffer buff) +{ + return (buff.offset >= buff.len); } -static void peek_char( - struct buffer buff, - char * c, - const char ** error -) { - if (is_eot(buff)) +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]; + raise_unexpected_eof(buff.offset, error); + return; + } + + *c = buff.data[buff.offset]; } static struct buffer get_char( @@ -539,62 +489,65 @@ static struct buffer parse_string( (void)c; buff = get_char(buff, &terminator, error); - if (*error) { + + if (*error) return buff; - } - if (terminator != '"' && terminator != '\'') { - buff.offset--; - raise_expected_string(buff.offset, error); - } + + if (terminator != '"' && terminator != '\'') + { + buff.offset--; + raise_expected_string(buff.offset, error); + } + str_start = buff.data + buff.offset; buff = get_char(buff, &c, error); - while (!*error) { - if (c == terminator) { + + while (!*error) + { + if (c == terminator) break; - } buff = get_char(buff, &c, error); } - if (!*error) { - value->type = RDT_STRING; - value->string.len = (buff.data + buff.offset) - str_start - 1; - value->string.buff = (char*)calloc( - value->string.len + 1, - sizeof(char) - ); - if (!value->string.buff) { - raise_enomem(error); - } else { - memcpy( - value->string.buff, - str_start, - value->string.len - ); - } - } + + if (!*error) + { + value->type = RDT_STRING; + value->string.len = (buff.data + buff.offset) - str_start - 1; + value->string.buff = (char*)calloc(value->string.len + 1, sizeof(char)); + + if (!value->string.buff) + raise_enomem(error); + else + memcpy( + value->string.buff, + str_start, + value->string.len + ); + } return buff; } -static struct buffer parse_integer( - struct buffer buff, - struct rmsgpack_dom_value * value, - const char ** error -) { - value->type = RDT_INT; - if (sscanf(buff.data + buff.offset, +static struct buffer parse_integer(struct buffer buff, + struct rmsgpack_dom_value * value, const char ** error) +{ + value->type = RDT_INT; + + if (sscanf(buff.data + buff.offset, #ifdef _WIN32 - "%I64d", + "%I64d", #else - "%lld", + "%lld", #endif - (signed long long*)&value->int_) == 0) - { - raise_expected_number(buff.offset, error); - } else { - while (isdigit(buff.data[buff.offset])) { - buff.offset++; - } - } - return buff; + (signed long long*)&value->int_) == 0) + { + raise_expected_number(buff.offset, error); + } + else + { + while (isdigit(buff.data[buff.offset])) + buff.offset++; + } + return buff; } static struct buffer parse_value( @@ -624,38 +577,38 @@ static struct buffer parse_value( return buff; } -static struct buffer get_ident( - struct buffer buff, - const char ** ident, - size_t * len, - const char ** error -) { +static struct buffer get_ident(struct buffer buff, const char ** ident, + size_t * len, const char ** error) +{ char c; - if (is_eot(buff)) { - raise_unexpected_eof(buff.offset, error); - return buff; - } + + 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) { + + if (*error) goto clean; - } - if (!isalpha(c)) { + if (!isalpha(c)) return buff; - } + buff.offset++; *len = *len + 1; peek_char(buff, &c, error); - while (!*error) { - if (!(isalpha(c) || isdigit(c) || c == '_')) { - break; - } - buff.offset++; - *len = *len + 1; - peek_char(buff, &c, error); - } + + while (!*error) + { + if (!(isalpha(c) || isdigit(c) || c == '_')) + break; + buff.offset++; + *len = *len + 1; + peek_char(buff, &c, error); + } clean: return buff; } @@ -675,196 +628,218 @@ static struct buffer parse_method_call( invocation->func = NULL; buff = get_ident(buff, &func_name, &func_name_len, error); - if (*error) { + if (*error) goto clean; - } buff = chomp(buff); buff = expect_char(buff, '(', error); - if (*error) { + if (*error) goto clean; - } - while (rf->name) { - if (strncmp(rf->name, func_name, func_name_len) == 0) { - invocation->func = rf->func; - break; - } - rf++; - } + while (rf->name) + { + if (strncmp(rf->name, func_name, func_name_len) == 0) + { + invocation->func = rf->func; + break; + } + rf++; + } - if (!invocation->func) { - raise_unknown_function( - buff.offset, - func_name, - func_name_len, - error - ); - goto clean; - } + if (!invocation->func) + { + raise_unknown_function(buff.offset, func_name, + func_name_len, error); + goto clean; + } buff = chomp(buff); - while (!peek(buff, ")")) { - if (argi >= MAX_ARGS) { - raise_too_many_arguments(error); - goto clean; - } - buff = parse_argument(buff, &args[argi], error); - if (*error) { - goto clean; - } - argi++; - buff = chomp(buff); - buff = expect_char(buff, ',', error); - if (*error) { - *error = NULL; - break; - } - buff = chomp(buff); - } + while (!peek(buff, ")")) + { + if (argi >= MAX_ARGS) + { + raise_too_many_arguments(error); + goto clean; + } + + buff = parse_argument(buff, &args[argi], error); + + if (*error) + goto clean; + + argi++; + buff = chomp(buff); + buff = expect_char(buff, ',', error); + + if (*error) + { + *error = NULL; + break; + } + buff = chomp(buff); + } buff = expect_char(buff, ')', error); - if (*error) { + + if (*error) goto clean; - } invocation->argc = argi; invocation->argv = (struct argument*)malloc(sizeof(struct argument) * argi); - if (!invocation->argv) { - raise_enomem(error); - goto clean; - } + + if (!invocation->argv) + { + raise_enomem(error); + goto clean; + } memcpy(invocation->argv, args, sizeof(struct argument) * argi); goto success; clean: - for (i = 0; i < argi; i++) { + for (i = 0; i < argi; i++) argument_free(&args[i]); - } success: return buff; } -static struct buffer parse_argument( - struct buffer buff, - struct argument * arg, - const char ** error -) { - buff = chomp(buff); - if ( - isalpha(buff.data[buff.offset]) - && !( - peek(buff, "nil") - || peek(buff, "true") - || peek(buff, "false") - ) - ) { - arg->type = AT_FUNCTION; - buff = parse_method_call(buff, &arg->invocation, error); - } else if (peek(buff, "{")) { - arg->type = AT_FUNCTION; - buff = parse_table(buff, &arg->invocation, error); - } else { - arg->type = AT_VALUE; - buff = parse_value(buff, &arg->value, error); - } - return buff; +static struct buffer parse_argument(struct buffer buff, + struct argument * arg, const char ** error) +{ + buff = chomp(buff); + + if ( + isalpha(buff.data[buff.offset]) + && !( + peek(buff, "nil") + || peek(buff, "true") + || peek(buff, "false") + ) + ) + { + arg->type = AT_FUNCTION; + buff = parse_method_call(buff, &arg->invocation, error); + } + else if (peek(buff, "{")) + { + arg->type = AT_FUNCTION; + buff = parse_table(buff, &arg->invocation, error); + } + else + { + arg->type = AT_VALUE; + buff = parse_value(buff, &arg->value, error); + } + return buff; } -static struct buffer parse_table( - struct buffer buff, - struct invocation * invocation, - const char ** error -) { - struct argument args[MAX_ARGS]; - unsigned argi = 0; - unsigned i; +static struct buffer parse_table(struct buffer buff, + struct invocation * invocation, const char ** error) +{ + struct argument args[MAX_ARGS]; + unsigned i; + const char * ident_name; + size_t ident_len; + unsigned argi = 0; - const char * ident_name; - size_t ident_len; + memset(args, 0, sizeof(struct argument) * MAX_ARGS); - memset(args, 0, sizeof(struct argument) * MAX_ARGS); - buff = chomp(buff); - buff = expect_char(buff, '{', error); - if (*error) { - goto clean; - } + buff = chomp(buff); + buff = expect_char(buff, '{', error); - buff = chomp(buff); - while (!peek(buff, "}")) { - if (argi >= MAX_ARGS) { - raise_too_many_arguments(error); - goto clean; - } - if (isalpha(buff.data[buff.offset])) { - buff = get_ident(buff, &ident_name, &ident_len, error); - if (!*error) { - args[argi].value.type = RDT_STRING; - args[argi].value.string.len = ident_len; - args[argi].value.string.buff = (char*)calloc( - ident_len + 1, - sizeof(char) - ); - if (!args[argi].value.string.buff) { - goto clean; - } - strncpy( - args[argi].value.string.buff, - ident_name, - ident_len - ); - } - } else { - buff = parse_string(buff, &args[argi].value, error); - } - if (*error) { - goto clean; - } - args[argi].type = AT_VALUE; - buff = chomp(buff); - argi++; - buff = expect_char(buff, ':', error); - if (*error) { - goto clean; - } - buff = chomp(buff); - if (argi >= MAX_ARGS) { - raise_too_many_arguments(error); - goto clean; - } - buff = parse_argument(buff, &args[argi], error); - if (*error) { - goto clean; - } - argi++; - buff = chomp(buff); - buff = expect_char(buff, ',', error); - if (*error) { - *error = NULL; - break; - } - buff = chomp(buff); - } - buff = expect_char(buff, '}', error); - if (*error) { - goto clean; - } + if (*error) + goto clean; - invocation->func = all_map; - invocation->argc = argi; - invocation->argv = (struct argument*)malloc(sizeof(struct argument) * argi); - if (!invocation->argv) { - raise_enomem(error); - goto clean; - } - memcpy(invocation->argv, args, sizeof(struct argument) * argi); + buff = chomp(buff); + while (!peek(buff, "}")) + { + if (argi >= MAX_ARGS) + { + raise_too_many_arguments(error); + goto clean; + } - goto success; + if (isalpha(buff.data[buff.offset])) + { + buff = get_ident(buff, &ident_name, &ident_len, error); + + if (!*error) + { + args[argi].value.type = RDT_STRING; + args[argi].value.string.len = ident_len; + args[argi].value.string.buff = (char*)calloc( + ident_len + 1, + sizeof(char) + ); + + if (!args[argi].value.string.buff) + goto clean; + + strncpy( + args[argi].value.string.buff, + ident_name, + ident_len + ); + } + } + else + buff = parse_string(buff, &args[argi].value, error); + + if (*error) + goto clean; + + args[argi].type = AT_VALUE; + buff = chomp(buff); + argi++; + buff = expect_char(buff, ':', error); + + if (*error) + goto clean; + + buff = chomp(buff); + + if (argi >= MAX_ARGS) + { + raise_too_many_arguments(error); + goto clean; + } + + buff = parse_argument(buff, &args[argi], error); + + if (*error) + goto clean; + argi++; + buff = chomp(buff); + buff = expect_char(buff, ',', error); + + if (*error) + { + *error = NULL; + break; + } + buff = chomp(buff); + } + + buff = expect_char(buff, '}', error); + + if (*error) + goto clean; + + invocation->func = all_map; + invocation->argc = argi; + invocation->argv = (struct argument*)malloc(sizeof(struct argument) * argi); + + if (!invocation->argv) + { + raise_enomem(error); + goto clean; + } + memcpy(invocation->argv, args, sizeof(struct argument) * argi); + + goto success; clean: - for (i = 0; i < argi; i++) { - argument_free(&args[i]); - } + for (i = 0; i < argi; i++) + argument_free(&args[i]); success: - return buff; + return buff; } @@ -881,62 +856,60 @@ void libretrodb_query_free(void *q) argument_free(&real_q->root.argv[i]); } -void *libretrodb_query_compile( - libretrodb_t * db, - const char * query, - size_t buff_len, - const char ** error -) +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; + struct buffer buff; + struct query *q = (struct query*)malloc(sizeof(struct query)); - *error = NULL; + if (!q) + goto clean; - 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); - } + memset(q, 0, sizeof(struct query)); + q->ref_count = 1; + buff.data = query; + buff.len = buff_len; + buff.offset = 0; - buff = expect_eof(buff, error); - if (*error) - goto clean; + *error = NULL; - if (q->root.func == NULL) { - raise_unexpected_eof(buff.offset, error); - return NULL; - } - goto success; + 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 == NULL) + { + raise_unexpected_eof(buff.offset, error); + return NULL; + } + goto success; clean: - if (q) - libretrodb_query_free(q); + if (q) + libretrodb_query_free(q); success: - return q; + return q; } void libretrodb_query_inc_ref(libretrodb_query_t *q) { - struct query * rq = (struct query*)q; - rq->ref_count += 1; + struct query * rq = (struct query*)q; + rq->ref_count += 1; } -int libretrodb_query_filter( - libretrodb_query_t * q, - struct rmsgpack_dom_value * v -) { - struct invocation inv = ((struct query *)q)->root; - struct rmsgpack_dom_value res = inv.func(*v, inv.argc, inv.argv); - return (res.type == RDT_BOOL && res.bool_); +int libretrodb_query_filter(libretrodb_query_t * q, + struct rmsgpack_dom_value * v) +{ + struct invocation inv = ((struct query *)q)->root; + struct rmsgpack_dom_value res = inv.func(*v, inv.argc, inv.argv); + return (res.type == RDT_BOOL && res.bool_); } diff --git a/libretrodb/query.h b/libretrodb/query.h index 8f5cd30a49..f53f56af17 100644 --- a/libretrodb/query.h +++ b/libretrodb/query.h @@ -7,9 +7,7 @@ void libretrodb_query_inc_ref(libretrodb_query_t *q); void libretrodb_query_dec_ref(libretrodb_query_t *q); -int libretrodb_query_filter( - libretrodb_query_t *q, - struct rmsgpack_dom_value * v -); +int libretrodb_query_filter(libretrodb_query_t *q, + struct rmsgpack_dom_value * v); #endif diff --git a/libretrodb/rmsgpack.c b/libretrodb/rmsgpack.c index d8fdac975f..9801867df5 100644 --- a/libretrodb/rmsgpack.c +++ b/libretrodb/rmsgpack.c @@ -55,32 +55,36 @@ static const uint8_t MPF_UINT64 = 0xcf; static const uint8_t MPF_NIL = 0xc0; -int rmsgpack_write_array_header( - int fd, - uint32_t size -){ - uint16_t tmp_i16; - uint32_t tmp_i32; - if (size < 16) { - size = (size | MPF_FIXARRAY); - if (write(fd, &size, sizeof(int8_t)) == -1) - return -errno; - return sizeof(int8_t); - } else if (size == (uint16_t)size) { - if (write(fd, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1) - return -errno; - tmp_i16 = httobe16(size); - if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) - return -errno; - return sizeof(int8_t) + sizeof(uint16_t); - } else { - if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1) - return -errno; - tmp_i32 = httobe32(size); - if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) - return -errno; - return sizeof(int8_t) + sizeof(uint32_t); - } +int rmsgpack_write_array_header(int fd, uint32_t size) +{ + uint16_t tmp_i16; + uint32_t tmp_i32; + + if (size < 16) + { + size = (size | MPF_FIXARRAY); + if (write(fd, &size, sizeof(int8_t)) == -1) + return -errno; + return sizeof(int8_t); + } + else if (size == (uint16_t)size) + { + if (write(fd, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1) + return -errno; + tmp_i16 = httobe16(size); + if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) + return -errno; + return sizeof(int8_t) + sizeof(uint16_t); + } + else + { + if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1) + return -errno; + tmp_i32 = httobe32(size); + if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) + return -errno; + return sizeof(int8_t) + sizeof(uint32_t); + } } int rmsgpack_write_map_header(