static void _single_char(struct parse_sp *ps, unsigned int c, const char *ptr) { ps->type = 0; ps->cursor = ptr + 1; dm_bit_clear_all(ps->charset); dm_bit_set(ps->charset, c); }
dm_bitset_t dm_bitset_create(struct dm_pool *mem, unsigned num_bits) { unsigned n = (num_bits / DM_BITS_PER_INT) + 2; size_t size = sizeof(int) * n; dm_bitset_t bs; if (mem) bs = dm_pool_zalloc(mem, size); else bs = dm_malloc(size); if (!bs) return NULL; *bs = num_bits; if (!mem) dm_bit_clear_all(bs); return bs; }
/* * Get the next token from the regular expression. * Returns: 1 success, 0 end of input, -1 error. */ static int _rx_get_token(struct parse_sp *ps) { int neg = 0, range = 0; char c, lc = 0; const char *ptr = ps->cursor; if (ptr == ps->rx_end) { /* end of input ? */ ps->type = -1; return 0; } switch (*ptr) { /* charsets and ncharsets */ case '[': ptr++; if (*ptr == '^') { dm_bit_set_all(ps->charset); /* never transition on zero */ dm_bit_clear(ps->charset, 0); neg = 1; ptr++; } else dm_bit_clear_all(ps->charset); while ((ptr < ps->rx_end) && (*ptr != ']')) { if (*ptr == '\\') { /* an escaped character */ ptr++; switch (*ptr) { case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; default: c = *ptr; } } else if (*ptr == '-' && lc) { /* we've got a range on our hands */ range = 1; ptr++; if (ptr == ps->rx_end) { log_error("Incomplete range" "specification"); return -1; } c = *ptr; } else c = *ptr; if (range) { /* add lc - c into the bitset */ if (lc > c) { char tmp = c; c = lc; lc = tmp; } for (; lc <= c; lc++) { if (neg) dm_bit_clear(ps->charset, lc); else dm_bit_set(ps->charset, lc); } range = 0; } else { /* add c into the bitset */ if (neg) dm_bit_clear(ps->charset, c); else dm_bit_set(ps->charset, c); } ptr++; lc = c; } if (ptr >= ps->rx_end) { ps->type = -1; return -1; } ps->type = 0; ps->cursor = ptr + 1; break; /* These characters are special, we just return their ASCII codes as the type. Sorted into ascending order to help the compiler */ case '(': case ')': case '*': case '+': case '?': case '|': ps->type = (int) *ptr; ps->cursor = ptr + 1; break; case '^': _single_char(ps, HAT_CHAR, ptr); break; case '$': _single_char(ps, DOLLAR_CHAR, ptr); break; case '.': /* The 'all but newline' character set */ ps->type = 0; ps->cursor = ptr + 1; dm_bit_set_all(ps->charset); dm_bit_clear(ps->charset, (int) '\n'); dm_bit_clear(ps->charset, (int) '\r'); dm_bit_clear(ps->charset, 0); break; case '\\': /* escaped character */ ptr++; if (ptr >= ps->rx_end) { log_error("Badly quoted character at end " "of expression"); ps->type = -1; return -1; } ps->type = 0; ps->cursor = ptr + 1; dm_bit_clear_all(ps->charset); switch (*ptr) { case 'n': dm_bit_set(ps->charset, (int) '\n'); break; case 'r': dm_bit_set(ps->charset, (int) '\r'); break; case 't': dm_bit_set(ps->charset, (int) '\t'); break; default: dm_bit_set(ps->charset, (int) *ptr); } break; default: /* add a single character to the bitset */ ps->type = 0; ps->cursor = ptr + 1; dm_bit_clear_all(ps->charset); dm_bit_set(ps->charset, (int) *ptr); break; } return 1; }