#include #include #include // for intptr_t #include #include #include "pbc_utils.h" #include "pbc_memory.h" #include "pbc_param.h" #include "pbc_a_param.h" #include "pbc_mnt.h" #include "pbc_d_param.h" #include "pbc_e_param.h" #include "pbc_f_param.h" #include "pbc_a1_param.h" #include "pbc_g_param.h" #include "pbc_i_param.h" #include "misc/symtab.h" #include "ecc/param.h" // Parser that reads a bunch of strings and places them in a symbol table. // TODO: Replace with Flex/Bison? enum { token_none = 0, token_langle, token_langleslash, token_rangle, token_word, token_eof, }; struct token_s { int type; char *s; }; typedef struct token_s token_t[1]; typedef struct token_s *token_ptr; // Reads next token from `input`. // Returns 1 on reaching `end` (if not NULL) or '\0' is read, 0 otherwise. static const char *token_get(token_t tok, const char *input, const char *end) { char *buf; int n = 32; int i; char c; #define get() (((!end || input < end) && *input) ? (c = *input++, 0) : 1) // Skip whitespace and comments. for(;;) { do { if (get()) { tok->type = token_eof; return input; } } while (strchr(" \t\r\n", c)); if (c == '#') { do { if (get()) { tok->type = token_eof; return input; } } while (c != '\n'); } else break; } tok->type = token_word; pbc_free(tok->s); buf = (char *) pbc_malloc(n); i = 0; for (;;) { buf[i] = c; i++; if (i == n) { n += 32; buf = (char *) pbc_realloc(buf, n); } if (get() || strchr(" \t\r\n", c)) break; } buf[i] = 0; tok->s = buf; return input; #undef get } static void token_init(token_t tok) { tok->type = token_none; tok->s = NULL; } static void token_clear(token_t tok) { pbc_free(tok->s); } static void read_symtab(symtab_t tab, const char *input, size_t limit) { token_t tok; const char *inputend = limit ? input + limit : NULL; token_init(tok); for (;;) { input = token_get(tok, input, inputend); if (tok->type != token_word) break; char *key = pbc_strdup(tok->s); input = token_get(tok, input, inputend); if (tok->type != token_word) { pbc_free(key); break; } symtab_put(tab, pbc_strdup(tok->s), key); pbc_free(key); } token_clear(tok); } // These functions have hidden visibility (see header). void param_out_type(FILE *stream, char *s) { fprintf(stream, "type %s\n", s); } void param_out_mpz(FILE *stream, char *s, mpz_t z) { fprintf(stream, "%s ", s); mpz_out_str(stream, 0, z); fprintf(stream, "\n"); } void param_out_int(FILE *stream, char *s, int i) { mpz_t z; mpz_init(z); mpz_set_si(z, i); param_out_mpz(stream, s, z); mpz_clear(z); } static const char *lookup(symtab_t tab, const char *key) { if (!symtab_has(tab, key)) { pbc_error("missing param: `%s'", key); return NULL; } return symtab_at(tab, key); } int lookup_mpz(mpz_t z, symtab_t tab, const char *key) { const char *data = lookup(tab, key); if (!data) { pbc_error("missing param: `%s'", key); return 1; } mpz_set_str(z, data, 0); return 0; } int lookup_int(int *n, symtab_t tab, const char *key) { mpz_t z; const char *data = lookup(tab, key); if (!data) { pbc_error("missing param: `%s'", key); return 1; } mpz_init(z); mpz_set_str(z, data, 0); *n = mpz_get_si(z); mpz_clear(z); return 0; } static int param_set_tab(pbc_param_t par, symtab_t tab) { const char *s = lookup(tab, "type"); static struct { char *s; int (*fun)(pbc_param_ptr, symtab_t tab); } funtab[] = { { "a", pbc_param_init_a }, { "d", pbc_param_init_d }, { "e", pbc_param_init_e }, { "f", pbc_param_init_f }, { "g", pbc_param_init_g }, { "a1", pbc_param_init_a1 }, { "i", pbc_param_init_i }, }; int res = 1; if (s) { unsigned int i; for(i = 0; i < sizeof(funtab)/sizeof(*funtab); i++) { if (!strcmp(s, funtab[i].s)) { res = funtab[i].fun(par, tab); if (res) pbc_error("bad pairing parameters"); return res; } } } pbc_error("unknown pairing type"); return res; } // Public functions: int pbc_param_init_set_str(pbc_param_t par, const char *input) { symtab_t tab; symtab_init(tab); read_symtab(tab, input, 0); int res = param_set_tab(par, tab); symtab_forall_data(tab, pbc_free); symtab_clear(tab); return res; } int pbc_param_init_set_buf(pbc_param_t par, const char *input, size_t len) { symtab_t tab; symtab_init(tab); read_symtab(tab, input, len); int res = param_set_tab(par, tab); symtab_forall_data(tab, pbc_free); symtab_clear(tab); return res; }