static BtorNode * parse_read (BtorBTORParser * parser, int len) { BtorNode *array, *idx, *res; int idxlen; if (parse_space (parser)) return 0; if (!(array = parse_array_exp (parser, len))) return 0; if (parse_space (parser)) { RELEASE_ARRAY_AND_RETURN_ERROR: btor_release_exp (parser->btor, array); return 0; } idxlen = btor_get_index_exp_len (parser->btor, array); if (!(idx = parse_exp (parser, idxlen, 0))) goto RELEASE_ARRAY_AND_RETURN_ERROR; res = btor_read_exp (parser->btor, array, idx); btor_release_exp (parser->btor, idx); btor_release_exp (parser->btor, array); return res; }
static int parse_group_info(char * response, struct newsnntp_group_info ** result) { char * line; uint32_t first; uint32_t last; uint32_t count; char * name; struct newsnntp_group_info * info; line = response; count = strtoul(line, &line, 10); if (!parse_space(&line)) return FALSE; first = strtoul(line, &line, 10); if (!parse_space(&line)) return FALSE; last = strtoul(line, &line, 10); if (!parse_space(&line)) return FALSE; name = line; info = group_info_init(name, first, last, count, FALSE); if (info == NULL) return FALSE; * result = info; return TRUE; }
static BtorNode * parse_binary (BtorBTORParser * parser, int len, Binary f) { BtorNode *l, *r, *res; assert (len); if (parse_space (parser)) return 0; if (!(l = parse_exp (parser, len, 0))) return 0; if (parse_space (parser)) { RELEASE_L_AND_RETURN_ERROR: btor_release_exp (parser->btor, l); return 0; } if (!(r = parse_exp (parser, len, 0))) goto RELEASE_L_AND_RETURN_ERROR; res = f (parser->btor, l, r); btor_release_exp (parser->btor, r); btor_release_exp (parser->btor, l); assert (btor_get_exp_len (parser->btor, res) == len); return res; }
static BtorNode * parse_slice (BtorBTORParser * parser, int len) { int arglen, upper, lower, delta; BtorNode *res, *arg; if (parse_space (parser)) return 0; if (!(arg = parse_exp (parser, 0, 0))) return 0; if (parse_space (parser)) { RELEASE_ARG_AND_RETURN_ERROR: btor_release_exp (parser->btor, arg); return 0; } arglen = btor_get_exp_len (parser->btor, arg); if (parse_non_negative_int (parser, &upper)) goto RELEASE_ARG_AND_RETURN_ERROR; if (upper >= arglen) { (void) btor_perr_btor (parser, "upper index '%d' >= argument width '%d", upper, arglen); goto RELEASE_ARG_AND_RETURN_ERROR; } if (parse_space (parser)) goto RELEASE_ARG_AND_RETURN_ERROR; if (parse_non_negative_int (parser, &lower)) goto RELEASE_ARG_AND_RETURN_ERROR; if (upper < lower) { (void) btor_perr_btor (parser, "upper index '%d' smaller than lower index '%d'", upper, lower); goto RELEASE_ARG_AND_RETURN_ERROR; } delta = upper - lower + 1; if (delta != len) { (void) btor_perr_btor (parser, "slice width '%d' not equal to expected width '%d'", delta, len); goto RELEASE_ARG_AND_RETURN_ERROR; } res = btor_slice_exp (parser->btor, arg, upper, lower); btor_release_exp (parser->btor, arg); return res; }
static BtorNode * parse_acond (BtorBTORParser * parser, int len) { BtorNode *c, *t, *e, *res; int idxlen; if (parse_space (parser)) return 0; if (parse_positive_int (parser, &idxlen)) return 0; if (parse_space (parser)) return 0; if (!(c = parse_exp (parser, 1, 0))) return 0; if (parse_space (parser)) { RELEASE_C_AND_RETURN_ERROR: btor_release_exp (parser->btor, c); return 0; } if (!(t = parse_array_exp (parser, len))) goto RELEASE_C_AND_RETURN_ERROR; if (idxlen != btor_get_index_exp_len (parser->btor, t)) { (void) btor_perr_btor (parser, "mismatch of index bit width of 'then' array"); RELEASE_C_AND_T_AND_RETURN_ERROR: btor_release_exp (parser->btor, t); goto RELEASE_C_AND_RETURN_ERROR; } if (parse_space (parser)) goto RELEASE_C_AND_T_AND_RETURN_ERROR; if (!(e = parse_array_exp (parser, len))) goto RELEASE_C_AND_T_AND_RETURN_ERROR; if (idxlen != btor_get_index_exp_len (parser->btor, e)) { (void) btor_perr_btor (parser, "mismatch of index bit width of 'else' array"); btor_release_exp (parser->btor, e); goto RELEASE_C_AND_T_AND_RETURN_ERROR; } res = btor_cond_exp (parser->btor, c, t, e); btor_release_exp (parser->btor, e); btor_release_exp (parser->btor, t); btor_release_exp (parser->btor, c); return res; }
// Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF const char* parse_status_line(unsigned char** p) { if (parse_http_version(p)) return ERR; if (parse_space(p)) return ERR; if (parse_status_code(p)) return ERR; if (parse_space(p)) return ERR; if (parse_reason_phrase(p)) return ERR; return parse_crlf(p); }
// Request-Line = Method SP Request-URI SP HTTP-Version CRLF const char* parse_request_line(unsigned char** p) { if (parse_method(p)) return ERR; if (parse_space(p)) return ERR; if (parse_request_uri(p)) return ERR; if (parse_space(p)) return ERR; if (parse_http_version(p)) return ERR; return parse_crlf(p); }
static bool parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature) { parse_space (pp, end); char quote = 0; if (*pp < end && (**pp == '\'' || **pp == '"')) { quote = **pp; (*pp)++; } const char *p = *pp; while (*pp < end && ISALNUM(**pp)) (*pp)++; if (p == *pp || *pp - p > 4) return false; feature->tag = hb_tag_from_string (p, *pp - p); if (quote) { /* CSS expects exactly four bytes. And we only allow quotations for * CSS compatibility. So, enforce the length. */ if (*pp - p != 4) return false; if (*pp == end || **pp != quote) return false; (*pp)++; } return true; }
static BtorNode * parse_redunary (BtorBTORParser * parser, int len, Unary f) { BtorNode *tmp, *res; (void) len; assert (len == 1); if (parse_space (parser)) return 0; if (!(tmp = parse_exp (parser, 0, 0))) return 0; if (btor_get_exp_len (parser->btor, tmp) == 1) { (void) btor_perr_btor (parser, "argument of reduction operation of width 1"); btor_release_exp (parser->btor, tmp); return 0; } res = f (parser->btor, tmp); btor_release_exp (parser->btor, tmp); assert (btor_get_exp_len (parser->btor, res) == 1); return res; }
static BtorNode * parse_write (BtorBTORParser * parser, int len) { BtorNode *array, *idx, *val, *res; int idxlen, vallen; if (parse_space (parser)) return 0; if (parse_positive_int (parser, &idxlen)) return 0; if (parse_space (parser)) return 0; if (!(array = parse_array_exp (parser, len))) return 0; if (parse_space (parser)) { RELEASE_ARRAY_AND_RETURN_ERROR: btor_release_exp (parser->btor, array); return 0; } if (!(idx = parse_exp (parser, idxlen, 0))) goto RELEASE_ARRAY_AND_RETURN_ERROR; if (parse_space (parser)) { RELEASE_ARRAY_AND_IDX_AND_RETURN_ERROR: btor_release_exp (parser->btor, idx); goto RELEASE_ARRAY_AND_RETURN_ERROR; } vallen = btor_get_exp_len (parser->btor, array); if (!(val = parse_exp (parser, vallen, 0))) goto RELEASE_ARRAY_AND_IDX_AND_RETURN_ERROR; res = btor_write_exp (parser->btor, array, idx, val); btor_release_exp (parser->btor, array); btor_release_exp (parser->btor, idx); btor_release_exp (parser->btor, val); return res; }
static BtorNode * parse_next (BtorBTORParser * parser, int len) { int idx; BtorNode * current, * next; Info info; if (parse_space (parser)) return 0; if (parse_positive_int (parser, &idx)) return 0; if (idx >= BTOR_COUNT_STACK (parser->exps) || !(current = parser->exps.start[idx])) { (void) btor_perr_btor (parser, "invalid next index %d", idx); return 0; } info = parser->info.start[idx]; if (!info.var) { (void) btor_perr_btor (parser, "next index %d is not a variable", idx); return 0; } if (info.next) { (void) btor_perr_btor (parser, "next index %d already used", idx); return 0; } if (parse_space (parser)) return 0; assert (!btor_is_array_exp (parser->btor, current)); if (!(next = parse_exp (parser, len, 0))) return 0; BTOR_PUSH_STACK (parser->mem, parser->regs, current); BTOR_PUSH_STACK (parser->mem, parser->nexts, next); parser->info.start[idx].next = 1; return next; }
static BtorNode * parse_logical (BtorBTORParser * parser, int len, Binary f) { BtorNode * l, * r, * res; if (len != 1) { (void) btor_perr_btor (parser, "logical operator bit width '%d'", len); return 0; } if (parse_space (parser)) return 0; if (!(l = parse_exp (parser, 0, 0))) return 0; if (btor_get_exp_len (parser->btor, l) != 1) { BIT_WIDTH_ERROR_RELEASE_L_AND_RETURN: (void) btor_perr_btor (parser, "expected argument of bit width '1'"); RELEASE_L_AND_RETURN_ERROR: btor_release_exp (parser->btor, l); return 0; } if (parse_space (parser)) goto RELEASE_L_AND_RETURN_ERROR; if (!(r = parse_exp (parser, 0, 0))) goto RELEASE_L_AND_RETURN_ERROR; if (btor_get_exp_len (parser->btor, r) != 1) { btor_release_exp (parser->btor, r); goto BIT_WIDTH_ERROR_RELEASE_L_AND_RETURN; } res = f (parser->btor, l, r); btor_release_exp (parser->btor, r); btor_release_exp (parser->btor, l); assert (btor_get_exp_len (parser->btor, res) == 1); return res; }
static clist * read_group_time_list(newsnntp * f) { char * line; char * group_name; time_t date; char * email; clist * group_time_list; struct newsnntp_group_time * n; int r; group_time_list = clist_new(); if (group_time_list == NULL) goto err; while (1) { char * p; char * remaining; line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; p = cut_token(line); if (p == NULL) continue; date = strtoul(p, &remaining, 10); p = remaining; parse_space(&p); email = p; group_name = line; n = group_time_new(group_name, date, email); if (n == NULL) goto free_list; r = clist_append(group_time_list, n); if (r < 0) { group_time_free(n); goto free_list; } } return group_time_list; free_list: group_time_list_free(group_time_list); err: return NULL; }
static BtorNode * parse_consth (BtorBTORParser * parser, int len) { char * tmp, * extended; BtorNode *res; int ch, clen; if (parse_space (parser)) return 0; assert (BTOR_EMPTY_STACK (parser->constant)); while (!isspace (ch = btor_nextch_btor (parser)) && ch != EOF && ch != ';') { if (!isxdigit (ch)) { (void) btor_perr_btor (parser, "expected hexidecimal digit"); return 0; } BTOR_PUSH_STACK (parser->mem, parser->constant, ch); } btor_savech_btor (parser, ch); clen = BTOR_COUNT_STACK (parser->constant); BTOR_PUSH_STACK (parser->mem, parser->constant, 0); BTOR_RESET_STACK (parser->constant); tmp = btor_hex_to_const_n (parser->mem, parser->constant.start, clen); clen = (int) strlen (tmp); if (clen > len) { (void) btor_perr_btor (parser, "hexadecimal constant '%s' exceeds bit width %d", parser->constant.start, len); btor_freestr (parser->mem, tmp); return 0; } if (clen < len) { extended = btor_uext_const (parser->mem, tmp, len - clen); btor_delete_const (parser->mem, tmp); tmp = extended; } assert (len == (int) strlen (tmp)); res = btor_const_exp (parser->btor, tmp); btor_freestr (parser->mem, tmp); assert (btor_get_exp_len (parser->btor, res) == len); return res; }
static BtorNode * parse_concat (BtorBTORParser * parser, int len) { BtorNode *l, *r, *res; int llen, rlen; if (parse_space (parser)) return 0; if (!(l = parse_exp (parser, 0, 0))) return 0; if (parse_space (parser)) { RELEASE_L_AND_RETURN_ERROR: btor_release_exp (parser->btor, l); return 0; } if (!(r = parse_exp (parser, 0, 0))) goto RELEASE_L_AND_RETURN_ERROR; llen = btor_get_exp_len (parser->btor, l); rlen = btor_get_exp_len (parser->btor, r); if (llen + rlen != len) { (void) btor_perr_btor (parser, "operands widths %d and %d do not add up to %d", llen, rlen, len); btor_release_exp (parser->btor, r); btor_release_exp (parser->btor, l); return 0; } res = btor_concat_exp (parser->btor, l, r); btor_release_exp (parser->btor, r); btor_release_exp (parser->btor, l); assert (btor_get_exp_len (parser->btor, res) == len); return res; }
static clist * read_distrib_default_value_list(newsnntp * f) { char * line; uint32_t weight; char * group_pattern; char * meaning; clist * distrib_default_value_list; struct newsnntp_distrib_default_value * n; int r; distrib_default_value_list = clist_new(); if (distrib_default_value_list == NULL) goto err; while (1) { char * p; char * remaining; line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; p = line; weight = strtoul(p, &remaining, 10); p = remaining; parse_space(&p); p = cut_token(line); if (p == NULL) continue; meaning = p; group_pattern = line; n = distrib_default_value_new(weight, group_pattern, meaning); if (n == NULL) goto free_list; r = clist_append(distrib_default_value_list, n); if (r < 0) { distrib_default_value_free(n); goto free_list; } } return distrib_default_value_list; free_list: distrib_default_value_list_free(distrib_default_value_list); err: return NULL; }
static bool parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) { return parse_feature_value_prefix (pp, end, feature) && parse_feature_tag (pp, end, feature) && parse_feature_indices (pp, end, feature) && parse_feature_value_postfix (pp, end, feature) && parse_space (pp, end) && *pp == end; }
static bool parse_char (const char **pp, const char *end, char c) { parse_space (pp, end); if (*pp == end || **pp != c) return false; (*pp)++; return true; }
static BtorNode * parse_ext (BtorBTORParser * parser, int len, Extend f) { BtorNode *res, *arg; int alen, elen; if (parse_space (parser)) return 0; if (!(arg = parse_exp (parser, 0, 0))) return 0; alen = btor_get_exp_len (parser->btor, arg); if (parse_space (parser)) { RELEASE_ARG_AND_RETURN_ERROR: btor_release_exp (parser->btor, arg); return 0; } if (parse_non_negative_int (parser, &elen)) goto RELEASE_ARG_AND_RETURN_ERROR; if (alen + elen != len) { (void) btor_perr_btor (parser, "argument length of %d plus %d does not match %d", alen, elen, len); goto RELEASE_ARG_AND_RETURN_ERROR; } res = f (parser->btor, arg, elen); assert (btor_get_exp_len (parser->btor, res) == len); btor_release_exp (parser->btor, arg); return res; }
static int read_list(mailpop3 * f, carray ** result) { unsigned int indx; uint32_t size; carray * msg_tab; struct mailpop3_msg_info * msg; char * line; msg_tab = carray_new(128); if (msg_tab == NULL) goto err; while (1) { line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; indx = strtol(line, &line, 10); if (!parse_space(&line)) continue; size = strtol(line, &line, 10); msg = mailpop3_msg_info_new(indx, size, NULL); if (msg == NULL) goto free_list; if (carray_count(msg_tab) < indx) { int r; r = carray_set_size(msg_tab, indx); if (r == -1) goto free_list; } carray_set(msg_tab, indx - 1, msg); } * result = msg_tab; return MAILPOP3_NO_ERROR; free_list: mailpop3_msg_info_tab_free(msg_tab); err: return MAILPOP3_ERROR_STREAM; }
static BtorNode * parse_shift (BtorBTORParser * parser, int len, Shift f) { BtorNode *l, *r, *res; int rlen; for (rlen = 1; rlen <= 30 && len != (1 << rlen); rlen++) ; if (len != (1 << rlen)) { (void) btor_perr_btor (parser, "length %d is not a power of two", len); return 0; } if (parse_space (parser)) return 0; if (!(l = parse_exp (parser, len, 0))) return 0; if (parse_space (parser)) { RELEASE_L_AND_RETURN_ERROR: btor_release_exp (parser->btor, l); return 0; } if (!(r = parse_exp (parser, rlen, 0))) goto RELEASE_L_AND_RETURN_ERROR; res = f (parser->btor, l, r); btor_release_exp (parser->btor, r); btor_release_exp (parser->btor, l); assert (btor_get_exp_len (parser->btor, res) == len); return res; }
static BtorNode * parse_cond (BtorBTORParser * parser, int len) { BtorNode *c, *t, *e, *res; if (parse_space (parser)) return 0; if (!(c = parse_exp (parser, 1, 0))) return 0; if (parse_space (parser)) { RELEASE_C_AND_RETURN_ERROR: btor_release_exp (parser->btor, c); return 0; } if (!(t = parse_exp (parser, len, 0))) goto RELEASE_C_AND_RETURN_ERROR; if (parse_space (parser)) { RELEASE_C_AND_T_AND_RETURN_ERROR: btor_release_exp (parser->btor, t); goto RELEASE_C_AND_RETURN_ERROR; } if (!(e = parse_exp (parser, len, 0))) goto RELEASE_C_AND_T_AND_RETURN_ERROR; res = btor_cond_exp (parser->btor, c, t, e); btor_release_exp (parser->btor, e); btor_release_exp (parser->btor, t); btor_release_exp (parser->btor, c); return res; }
static BtorNode * parse_root (BtorBTORParser * parser, int len) { BtorNode *res; if (parse_space (parser)) return 0; if (!(res = parse_exp (parser, len, 0))) return 0; BTOR_PUSH_STACK (parser->mem, parser->outputs, res); return res; }
static clist * read_xhdr_resp_list(newsnntp * f) { char * line; uint32_t article; char * value; clist * xhdr_resp_list; struct newsnntp_xhdr_resp_item * n; int r; xhdr_resp_list = clist_new(); if (xhdr_resp_list == NULL) goto err; while (1) { line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; article = strtoul(line, &line, 10); if (!parse_space(&line)) continue; value = line; n = xhdr_resp_item_new(article, value); if (n == NULL) goto free_list; r = clist_append(xhdr_resp_list, n); if (r < 0) { xhdr_resp_item_free(n); goto free_list; } } return xhdr_resp_list; free_list: xhdr_resp_list_free(xhdr_resp_list); err: return NULL; }
static BtorNode * parse_unary (BtorBTORParser * parser, int len, Unary f) { BtorNode *tmp, *res; assert (len); if (parse_space (parser)) return 0; if (!(tmp = parse_exp (parser, len, 0))) return 0; res = f (parser->btor, tmp); btor_release_exp (parser->btor, tmp); assert (btor_get_exp_len (parser->btor, res) == len); return res; }
static int read_uidl(mailpop3 * f, carray * msg_tab) { unsigned int indx; struct mailpop3_msg_info * msg; char * line; while (1) { char * uidl; line = read_line(f); if (line == NULL) goto err; if (mailstream_is_end_multiline(line)) break; indx = strtol(line, &line, 10); if (!parse_space(&line)) continue; uidl = strdup(line); if (uidl == NULL) continue; if (indx > carray_count(msg_tab)) { free(uidl); continue; } msg = carray_get(msg_tab, indx - 1); if (msg == NULL) { free(uidl); continue; } msg->msg_uidl = uidl; } return MAILPOP3_NO_ERROR; err: return MAILPOP3_ERROR_STREAM; }
static bool parse_bool (const char **pp, const char *end, unsigned int *pv) { parse_space (pp, end); const char *p = *pp; while (*pp < end && ISALPHA(**pp)) (*pp)++; /* CSS allows on/off as aliases 1/0. */ if (*pp - p == 2 || 0 == strncmp (p, "on", 2)) *pv = 1; else if (*pp - p == 3 || 0 == strncmp (p, "off", 2)) *pv = 0; else return false; return true; }
static int parse_response(newsnntp * f, char * response) { int code; code = strtol(response, &response, 10); if (response == NULL) { f->nntp_response = NULL; return code; } parse_space(&response); if (mmap_string_assign(f->nntp_response_buffer, response) != NULL) f->nntp_response = f->nntp_response_buffer->str; else f->nntp_response = NULL; return code; }
/* * Parse the given query string to extract the parameter pname * and return to the caller. (Not the best way to do it but * going for simplicity at the moment.) */ char * get_param(char *qstr, const char *pname) { if (qstr == NULL) return NULL; char *temp; char *param = NULL; char *value = NULL; size_t sz; while (*qstr) { sz = strcspn(qstr, "=&"); if (qstr[sz] == '=') { qstr[sz] = 0; param = qstr; } qstr += sz + 1; if (param && strcmp(param, pname) == 0) break; else param = NULL; } if (param == NULL) return NULL; if ((temp = strchr(qstr, '&')) == NULL) value = strdup(qstr); else { sz = temp - qstr; value = malloc(sz + 1); if (value == NULL) errx(EXIT_FAILURE, "malloc failed"); memcpy(value, qstr, sz); value[sz] = 0; } value = parse_space(value); char *retval = parse_hex(value); free(value); return retval; }
static BtorNode * parse_const (BtorBTORParser * parser, int len) { BtorNode *res; int ch, clen; if (parse_space (parser)) return 0; assert (BTOR_EMPTY_STACK (parser->constant)); while (!isspace (ch = btor_nextch_btor (parser)) && ch != EOF && ch != ';') { if (ch != '0' && ch != '1') { (void) btor_perr_btor (parser, "expected '0' or '1'"); return 0; } BTOR_PUSH_STACK (parser->mem, parser->constant, ch); } btor_savech_btor (parser, ch); clen = BTOR_COUNT_STACK (parser->constant); BTOR_PUSH_STACK (parser->mem, parser->constant, 0); BTOR_RESET_STACK (parser->constant); if (clen != len) { (void) btor_perr_btor (parser, "binary constant '%s' exceeds bit width %d", parser->constant.start, len); return 0; } res = btor_const_exp (parser->btor, parser->constant.start); return res; }