nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

parser.h (6810B)


      1 #ifndef PARSER_H
      2 #define PARSER_H
      3 
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <stdint.h>
      7 #include <string.h>
      8 
      9 #include "../../config/config.h"
     10 #include "flatcc/flatcc.h"
     11 #include "symbols.h"
     12 
     13 #define ELEM_BUFSIZ (64 * 1024)
     14 #define ERROR_BUFSIZ 200
     15 
     16 #define REVERT_LIST(TYPE, FIELD, HEAD)                                      \
     17     do {                                                                    \
     18         TYPE *tmp__next, *tmp__prev = 0, *tmp__link = *(HEAD);              \
     19         while (tmp__link) {                                                 \
     20             tmp__next = tmp__link->FIELD;                                   \
     21             tmp__link->FIELD = tmp__prev;                                   \
     22             tmp__prev = tmp__link;                                          \
     23             tmp__link = tmp__next;                                          \
     24         }                                                                   \
     25         *(HEAD) = tmp__prev;                                                \
     26     } while (0)
     27 
     28 typedef struct fb_parser fb_parser_t;
     29 typedef flatcc_options_t fb_options_t;
     30 
     31 typedef void (*fb_error_fun)(void *err_ctx, const char *buf, size_t len);
     32 
     33 void __flatcc_fb_default_error_out(void *err_ctx, const char *buf, size_t len);
     34 #define  fb_default_error_out __flatcc_fb_default_error_out
     35 
     36 int __flatcc_fb_print_error(fb_parser_t *P, const char * format, ...);
     37 #define fb_print_error __flatcc_fb_print_error
     38 
     39 struct fb_parser {
     40     fb_parser_t *dependencies;
     41     fb_parser_t *inverse_dependencies;
     42     fb_error_fun error_out;
     43     void *error_ctx;
     44 
     45     const char *managed_input;
     46 
     47     fb_token_t *ts, *te;
     48     int tcapacity;
     49     int doc_mode;
     50     fb_doc_t *doc;
     51     fb_token_t *token;
     52 
     53     size_t elem_end;
     54     void *elem_buffers;
     55     size_t elem;
     56     size_t offset_size;
     57 
     58     const char *line;
     59     long linenum;
     60 
     61     /* Internal id (not a pointer into token stream). */
     62     fb_token_t t_none;
     63     fb_token_t t_ubyte;
     64 
     65     int failed;
     66 
     67     unsigned char *tmp_field_marker;
     68     fb_symbol_t **tmp_field_index;
     69     int nesting_level;
     70 
     71     int has_schema;
     72     fb_options_t opts;
     73     fb_schema_t schema;
     74     fb_scope_t *root_scope;
     75     fb_scope_t *current_scope;
     76     char *path;
     77     char *referer_path;
     78 };
     79 
     80 static inline void checkmem(const void *p)
     81 {
     82     if (!p) {
     83         fprintf(stderr, "error: out of memory, aborting...\n");
     84         exit(1);
     85     }
     86 }
     87 
     88 static inline void *new_elem(fb_parser_t *P, size_t size)
     89 {
     90     size_t elem;
     91     void *buf;
     92 
     93     size = (size + 15) & ~(size_t)15;
     94     elem = P->elem;
     95     if (elem + size > P->elem_end) {
     96         buf = calloc(ELEM_BUFSIZ, 1);
     97         checkmem(buf);
     98         *(void**)buf = P->elem_buffers;
     99         P->elem_buffers = buf;
    100         elem = P->elem = (size_t)buf + 16;
    101         P->elem_end = (size_t)buf + ELEM_BUFSIZ;
    102     }
    103     P->elem += size;
    104     return (void*)elem;
    105 }
    106 
    107 int __flatcc_fb_print_error(fb_parser_t *P, const char * format, ...);
    108 #define fb_print_error __flatcc_fb_print_error
    109 
    110 const char *__flatcc_error_find_file_of_token(fb_parser_t *P, fb_token_t *t);
    111 #define error_find_file_of_token __flatcc_error_find_file_of_token
    112 
    113 /*
    114  * This is the primary error reporting function.
    115  * The parser is flagged as failed and error count incremented.
    116  *
    117  * If s is not null, then s, len replaces the token text of `t` but
    118  * still reports the location of t. `peer` is optional and prints the
    119  * token location and text and the end of the message.
    120  * `msg` may be the only non-zero argument besides `P`.
    121  *
    122  * Various helper functions are available for the various cases.
    123  *
    124  * `fb_print_error` may be called instead to generate text to the error
    125  * output that is not counted as an error.
    126  */
    127 void __flatcc_error_report(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer, const char *s, size_t len);
    128 #define error_report __flatcc_error_report
    129 
    130 static void error_tok_2(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer)
    131 {
    132     error_report(P, t, msg, peer, 0, 0);
    133 }
    134 
    135 static inline void error_tok(fb_parser_t *P, fb_token_t *t, const char *msg)
    136 {
    137     error_tok_2(P, t, msg, 0);
    138 }
    139 
    140 /* Only use the token location. */
    141 static inline void error_tok_as_string(fb_parser_t *P, fb_token_t *t, const char *msg, char *s, size_t len)
    142 {
    143     error_report(P, t, msg, 0, s, len);
    144 }
    145 
    146 static inline void error(fb_parser_t *P, const char *msg)
    147 {
    148     error_tok(P, 0, msg);
    149 }
    150 
    151 static inline void error_name(fb_parser_t *P, fb_name_t *name, const char *msg)
    152 {
    153     if (!name) {
    154         error(P, msg);
    155     } else {
    156         error_report(P, 0, msg, 0, name->name.s.s, (size_t)name->name.s.len);
    157     }
    158 }
    159 
    160 static inline void error_sym(fb_parser_t *P, fb_symbol_t *s, const char *msg)
    161 {
    162     error_tok(P, s->ident, msg);
    163 }
    164 
    165 static inline void error_sym_2(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_symbol_t *s2)
    166 {
    167     error_tok_2(P, s->ident, msg, s2->ident);
    168 }
    169 
    170 static inline void error_sym_tok(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_token_t *t2)
    171 {
    172     error_tok_2(P, s->ident, msg, t2);
    173 }
    174 
    175 void error_ref_sym(fb_parser_t *P, fb_ref_t *ref, const char *msg, fb_symbol_t *s2);
    176 
    177 static inline void error_ref(fb_parser_t *P, fb_ref_t *ref, const char *msg)
    178 {
    179     error_ref_sym(P, ref, msg, 0);
    180 }
    181 
    182 /*
    183  * If `opts` is null, defaults options are being used, otherwise opts is
    184  * copied into the parsers options. The name may be path, the basename
    185  * without default extension will be extracted. The `error_out` funciton is
    186  * optional, otherwise output is printed to stderr, truncated to a
    187  * reasoanble size per error. `error_ctx` is provided as argument to
    188  * `error_out` if non-zero, and otherwise ignored.
    189  *
    190  * This api only deals with a single schema file so a parent level
    191  * driver must handle file inclusion and update P->dependencies but
    192  * order is not significant (parse order is, but this is handled by
    193  * updating the `include_index` in the root schema).
    194  *
    195  * P->dependencies must be cleared by callee in any order but once one
    196  * is cleared the entire structure should be taken down because symbols
    197  * trees point everywhere. For parses without file inclusion
    198  * dependencies will be null. Dependencies are not handled at this
    199  * level. P->inverse_dependencies is just the reverse list.
    200  *
    201  * The file at the head of the dependencies list is the root and the
    202  * one that provides the root schema. Other root schemas are not used.
    203  */
    204 int __flatcc_fb_init_parser(fb_parser_t *P, fb_options_t *opts, const char *name,
    205         fb_error_fun error_out, void *error_ctx, fb_root_schema_t *rs);
    206 #define fb_init_parser __flatcc_fb_init_parser
    207 
    208 int __flatcc_fb_parse(fb_parser_t *P, const char *input, size_t len, int own_buffer);
    209 #define fb_parse __flatcc_fb_parse
    210 
    211 void __flatcc_fb_clear_parser(fb_parser_t *P);
    212 #define fb_clear_parser __flatcc_fb_clear_parser
    213 
    214 #endif /* PARSER_H */