From 5370eeeceaa85313c164e5718605b8512bfc701a Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 19 Oct 2001 14:36:57 +0000 Subject: [PATCH] o First pass at the regex code. lib/regex/matcher takes an array of regex's and builds a *very* efficient engine that will tell you which regex a string matches with only a single pass through the string. To be used in the config file when specifying devices. o Anchor's aren't supported yet (^ and $) but that won't take long. o Also when we get some realistic config files we may want to consider adding an extra level of indirection to the dfa state in order to compress the table. It all depends on how large typical tables get. --- configure | 2 + configure.in | 1 + include/.symlinks | 2 + lib/Makefile.in | 5 +- lib/datastruct/bitset.c | 79 +++ lib/datastruct/bitset.h | 46 ++ lib/regex/matcher.c | 349 ++++++++++++++ lib/regex/matcher.h | 18 + lib/regex/parse_rx.c | 363 ++++++++++++++ lib/regex/parse_rx.h | 39 ++ lib/regex/ttree.c | 129 +++++ lib/regex/ttree.h | 19 + old-tests/format1/read_vg_t.c | 1 + old-tests/regex/Makefile.in | 26 + old-tests/regex/dev_patterns | 2 + old-tests/regex/devices.list | 880 ++++++++++++++++++++++++++++++++++ old-tests/regex/matcher_t.c | 135 ++++++ old-tests/regex/parse_t.c | 93 ++++ 18 files changed, 2188 insertions(+), 1 deletion(-) create mode 100644 lib/datastruct/bitset.c create mode 100644 lib/datastruct/bitset.h create mode 100644 lib/regex/matcher.c create mode 100644 lib/regex/matcher.h create mode 100644 lib/regex/parse_rx.c create mode 100644 lib/regex/parse_rx.h create mode 100644 lib/regex/ttree.c create mode 100644 lib/regex/ttree.h create mode 100644 old-tests/regex/Makefile.in create mode 100644 old-tests/regex/dev_patterns create mode 100644 old-tests/regex/devices.list create mode 100644 old-tests/regex/matcher_t.c create mode 100644 old-tests/regex/parse_t.c diff --git a/configure b/configure index 336851831..c59e4089f 100755 --- a/configure +++ b/configure @@ -2162,6 +2162,7 @@ tools/Makefile \ test/mm/Makefile \ test/device/Makefile \ test/format1/Makefile \ +test/regex/Makefile \ " | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF diff --git a/configure.in b/configure.in index 9968b1ccf..7365ecb6a 100644 --- a/configure.in +++ b/configure.in @@ -138,4 +138,5 @@ tools/Makefile \ test/mm/Makefile \ test/device/Makefile \ test/format1/Makefile \ +test/regex/Makefile \ ) diff --git a/include/.symlinks b/include/.symlinks index 486f9e1d5..4193c2888 100644 --- a/include/.symlinks +++ b/include/.symlinks @@ -1,5 +1,6 @@ ../lib/activate/activate.h ../lib/config/config.h +../lib/datastruct/bitset.h ../lib/datastruct/hash.h ../lib/datastruct/list.h ../lib/datastruct/lvm-types.h @@ -13,4 +14,5 @@ ../lib/mm/dbg_malloc.h ../lib/mm/pool.h ../lib/mm/xlate.h +../lib/regex/matcher.h ../lib/uuid/uuid.h diff --git a/lib/Makefile.in b/lib/Makefile.in index 3676762e0..4ef950ae3 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -11,11 +11,11 @@ VPATH = @srcdir@ SOURCES=\ activate/activate.c \ config/config.c \ + datastruct/bitset.c \ datastruct/hash.c \ device/dev-cache.c \ device/dev-io.c \ device/device.c \ - display/display.c \ filters/filter.c \ format1/disk-rep.c \ format1/format1.c \ @@ -26,6 +26,9 @@ SOURCES=\ metadata/metadata.c \ mm/dbg_malloc.c \ mm/pool.c \ + regex/parse_rx.c \ + regex/matcher.c \ + regex/ttree.c \ uuid/uuid.c TARGETS=liblvm.a diff --git a/lib/datastruct/bitset.c b/lib/datastruct/bitset.c new file mode 100644 index 000000000..707a51d61 --- /dev/null +++ b/lib/datastruct/bitset.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "bitset.h" +#include "dbg_malloc.h" + +#include + +/* FIXME: calculate this. */ +#define INT_SHIFT 5 + +bitset_t bitset_create(struct pool *mem, unsigned num_bits) +{ + int n = (num_bits / BITS_PER_INT) + 2; + int size = sizeof(int) * n; + unsigned *bs = pool_zalloc(mem, size); + + if (!bs) + return NULL; + + *bs = num_bits; + return bs; +} + +void bitset_destroy(bitset_t bs) +{ + dbg_free(bs); +} + +void bit_union(bitset_t out, bitset_t in1, bitset_t in2) +{ + int i; + for(i = (in1[0] / BITS_PER_INT) + 1; i; i--) + out[i] = in1[i] | in2[i]; +} + +/* + * FIXME: slow + */ +static inline int _test_word(uint32_t test, int bit) +{ + while (bit < BITS_PER_INT) { + if (test & (0x1 << bit)) + return bit; + bit++; + } + + return -1; +} + +int bit_get_next(bitset_t bs, int last_bit) +{ + int bit, word; + uint32_t test; + + last_bit++; /* otherwise we'll return the same bit again */ + + while(last_bit < bs[0]) { + word = last_bit >> INT_SHIFT; + test = bs[word + 1]; + bit = last_bit & (BITS_PER_INT - 1); + + if ((bit = _test_word(test, bit)) >= 0) + return (word * BITS_PER_INT) + bit; + + last_bit = last_bit - (last_bit & (BITS_PER_INT - 1)) + + BITS_PER_INT; + } + + return -1; +} + +int bit_get_first(bitset_t bs) +{ + return bit_get_next(bs, -1); +} diff --git a/lib/datastruct/bitset.h b/lib/datastruct/bitset.h new file mode 100644 index 000000000..93f1c130b --- /dev/null +++ b/lib/datastruct/bitset.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#ifndef _LVM_BITSET_H +#define _LVM_BITSET_H + +#include "lvm-types.h" +#include "pool.h" + +#include +#include + + +typedef uint32_t *bitset_t; + +bitset_t bitset_create(struct pool *mem, unsigned num_bits); + +void bit_union(bitset_t out, bitset_t in1, bitset_t in2); +int bit_get_first(bitset_t bs); +int bit_get_next(bitset_t bs, int last_bit); + + +#define BITS_PER_INT (sizeof(int) * CHAR_BIT) + +#define bit(bs, i) \ + (bs[(i / BITS_PER_INT) + 1] & (0x1 << (i & (BITS_PER_INT - 1)))) + +#define bit_set(bs, i) \ + (bs[(i / BITS_PER_INT) + 1] |= (0x1 << (i & (BITS_PER_INT - 1)))) + +#define bit_clear(bs, i) \ + (bs[(i / BITS_PER_INT) + 1] &= ~(0x1 << (i & (BITS_PER_INT - 1)))) + +#define bit_set_all(bs) \ + memset(bs + 1, -1, ((*bs / BITS_PER_INT) + 1) * sizeof(int)) + +#define bit_clear_all(bs) \ + memset(bs + 1, 0, ((*bs / BITS_PER_INT) + 1) * sizeof(int)) + +#define bit_copy(bs1, bs2) \ + memcpy(bs1 + 1, bs2 + 1, ((*bs1 / BITS_PER_INT) + 1) * sizeof(int)) + +#endif diff --git a/lib/regex/matcher.c b/lib/regex/matcher.c new file mode 100644 index 000000000..94fd5265a --- /dev/null +++ b/lib/regex/matcher.c @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "matcher.h" +#include "parse_rx.h" +#include "log.h" +#include "ttree.h" +#include "bitset.h" + +#include +#include +#include + +struct dfa_state { + int final; + struct dfa_state *lookup[256]; +}; + +struct state_queue { + struct dfa_state *s; + bitset_t bits; + struct state_queue *next; +}; + +struct matcher { /* Instance variables for the lexer */ + struct dfa_state *start; + int num_nodes, nodes_entered; + struct rx_node **nodes; + struct pool *scratch, *mem; +}; + +#define TARGET_TRANS '\0' + +static int _count_nodes(struct rx_node *rx) +{ + int r = 1; + + if(rx->left) + r += _count_nodes(rx->left); + + if(rx->right) + r += _count_nodes(rx->right); + + return r; +} + +static void _fill_table(struct matcher *m, struct rx_node *rx) +{ + assert((rx->type != OR) || (rx->left && rx->right)); + + if(rx->left) + _fill_table(m, rx->left); + + if(rx->right) + _fill_table(m, rx->right); + + m->nodes[m->nodes_entered++] = rx; +} + +static void _create_bitsets(struct matcher *m) +{ + int i; + + for(i = 0; i < m->num_nodes; i++) { + struct rx_node *n = m->nodes[i]; + n->firstpos = bitset_create(m->scratch, m->num_nodes); + n->lastpos = bitset_create(m->scratch, m->num_nodes); + n->followpos = bitset_create(m->scratch, m->num_nodes); + } +} + +static void _calc_functions(struct matcher *m) +{ + int i, j, final = 1; + struct rx_node *rx, *c1, *c2; + + for(i = 0; i < m->num_nodes; i++) { + rx = m->nodes[i]; + c1 = rx->left; + c2 = rx->right; + + if(bit(rx->charset, TARGET_TRANS)) + rx->final = final++; + + switch(rx->type) { + case CAT: + if(c1->nullable) + bit_union(rx->firstpos, + c1->firstpos, c2->firstpos); + else + bit_copy(rx->firstpos, c1->firstpos); + + if(c2->nullable) + bit_union(rx->lastpos, + c1->lastpos, c2->lastpos); + else + bit_copy(rx->lastpos, c2->lastpos); + + rx->nullable = c1->nullable && c2->nullable; + break; + + case PLUS: + bit_copy(rx->firstpos, c1->firstpos); + bit_copy(rx->lastpos, c1->lastpos); + rx->nullable = c1->nullable; + break; + + case OR: + bit_union(rx->firstpos, c1->firstpos, c2->firstpos); + bit_union(rx->lastpos, c1->lastpos, c2->lastpos); + rx->nullable = c1->nullable || c2->nullable; + break; + + case QUEST: + case STAR: + bit_copy(rx->firstpos, c1->firstpos); + bit_copy(rx->lastpos, c1->lastpos); + rx->nullable = 1; + break; + + case CHARSET: + bit_set(rx->firstpos, i); + bit_set(rx->lastpos, i); + rx->nullable = 0; + break; + + default: + log_debug("unknown node type"); + } + + /* + * followpos has it's own switch + * because PLUS and STAR do the + * same thing. + */ + switch(rx->type) { + case CAT: + for(j = 0; j < m->num_nodes; j++) { + if(bit(c1->lastpos, j)) { + struct rx_node *n = m->nodes[j]; + bit_union(n->followpos, + n->followpos, c2->firstpos); + } + } + break; + + case PLUS: + case STAR: + for(j = 0; j < m->num_nodes; j++) { + if(bit(rx->lastpos, j)) { + struct rx_node *n = m->nodes[j]; + bit_union(n->followpos, + n->followpos, rx->firstpos); + } + } + break; + } + } +} + +static inline struct dfa_state *_create_dfa_state(struct pool *mem) +{ + return pool_zalloc(mem, sizeof(struct dfa_state)); +} + +static struct state_queue *_create_state_queue(struct pool *mem, + struct dfa_state *dfa, + bitset_t bits) +{ + struct state_queue *r = pool_alloc(mem, sizeof(*r)); + + if (!r) { + stack; + return NULL; + } + + r->s = dfa; + r->bits = bitset_create(mem, bits[0]); /* first element is the size */ + bit_copy(r->bits, bits); + r->next = 0; + return r; +} + +static int _calc_states(struct matcher *m, struct rx_node *rx) +{ + int iwidth = (m->num_nodes / BITS_PER_INT) + 1; + struct ttree *tt = ttree_create(m->scratch, iwidth); + struct state_queue *h, *t, *tmp; + struct dfa_state *dfa, *ldfa; + int i, a, set_bits = 0, count = 0; + bitset_t bs = bitset_create(m->scratch, m->num_nodes), dfa_bits; + + if (!tt) { + stack; + return 0; + } + + if (!bs) { + stack; + return 0; + } + + /* create first state */ + dfa = _create_dfa_state(m->mem); + m->start = dfa; + ttree_insert(tt, rx->firstpos, dfa); + + /* prime the queue */ + h = t = _create_state_queue(m->scratch, dfa, rx->firstpos); + while(h) { + /* pop state off front of the queue */ + dfa = h->s; + dfa_bits = h->bits; + h = h->next; + + /* iterate through all the inputs for this state */ + bit_clear_all(bs); + for(a = 0; a < 256; a++) { + /* iterate through all the states in firstpos */ + for(i = bit_get_first(dfa_bits); + i >=0; + i = bit_get_next(dfa_bits, i)) { + if(bit(m->nodes[i]->charset, a)) { + if(a == TARGET_TRANS) + dfa->final = m->nodes[i]->final; + + bit_union(bs, bs, m->nodes[i]->followpos); + set_bits = 1; + } + } + + if(set_bits) { + ldfa = ttree_lookup(tt, bs + 1); + if(!ldfa) { + /* push */ + ldfa = _create_dfa_state(m->mem); + ttree_insert(tt, bs + 1, ldfa); + tmp = _create_state_queue(m->scratch, ldfa, bs); + if(!h) + h = t = tmp; + else { + t->next = tmp; + t = tmp; + } + + count++; + } + + dfa->lookup[a] = ldfa; + set_bits = 0; + bit_clear_all(bs); + } + } + } + + log_debug("Lexer built with %d dfa states", count); + return 1; +} + +struct matcher *matcher_create(struct pool *mem, + const char **patterns, int num) +{ + char *all, *ptr; + int i, len = 0; + struct rx_node *rx; + struct pool *scratch = pool_create(10 * 1024); + struct matcher *m; + + if (!scratch) { + stack; + return NULL; + } + + if (!(m = pool_alloc(mem, sizeof(*m)))) { + stack; + return NULL; + } + + memset(m, 0, sizeof(*m)); + + /* join the regexps together, delimiting with zero */ + for(i = 0; i < num; i++) + len += strlen(patterns[i]) + 8; + + ptr = all = pool_alloc(scratch, len + 1); + + if (!all) { + stack; + goto bad; + } + + for(i = 0; i < num; i++) { + ptr += sprintf(ptr, "(.*(%s)%c)", patterns[i], + TARGET_TRANS); + if(i < (num - 1)) + *ptr++ = '|'; + } + + /* parse this expression */ + if(!(rx = rx_parse_tok(scratch, all, ptr))) { + log_debug("Couldn't parse the regex"); + goto bad; + } + + m->mem = mem; + m->scratch = scratch; + m->num_nodes = _count_nodes(rx); + m->nodes = pool_alloc(scratch, sizeof(*m->nodes) * m->num_nodes); + + if (!m->nodes) { + stack; + goto bad; + } + + _fill_table(m, rx); + _create_bitsets(m); + _calc_functions(m); + _calc_states(m, rx); + pool_destroy(scratch); + m->scratch = NULL; + + return m; + + bad: + pool_destroy(scratch); + pool_destroy(mem); + return NULL; +} + +int matcher_run(struct matcher *m, const char *b, const char *e) +{ + struct dfa_state *cs = m->start; + int r = -1; + + for (; b != e; b++) { + + if (!(cs = cs->lookup[(int) (unsigned char) *b])) + break; + + if (cs->final) + r = cs->final; + } + + /* subtract 1 to get back to zero index */ + return (r < 0) ? r : (r - 1); +} diff --git a/lib/regex/matcher.h b/lib/regex/matcher.h new file mode 100644 index 000000000..40b68f7e3 --- /dev/null +++ b/lib/regex/matcher.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#ifndef _LVM_MATCHER_H +#define _LVM_MATCHER_H + +#include "pool.h" + +struct matcher; +struct matcher *matcher_create(struct pool *mem, + const char **patterns, int num); + +int matcher_run(struct matcher *m, const char *begin, const char *end); + +#endif diff --git a/lib/regex/parse_rx.c b/lib/regex/parse_rx.c new file mode 100644 index 000000000..fc750fa03 --- /dev/null +++ b/lib/regex/parse_rx.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "parse_rx.h" +#include "bitset.h" +#include "log.h" + +#include +#include +#include + + +struct parse_sp { /* scratch pad for the parsing process */ + struct pool *mem; + int type; /* token type, 0 indicates a charset */ + bitset_t charset; /* The current charset */ + const char *cursor; /* where we are in the regex */ + const char *rx_end; /* 1pte for the expression being parsed */ +}; + + +static struct rx_node *_expr(struct parse_sp *ps, struct rx_node *l); + + +/* + * Get the next token from the regular expression. + * Returns: 1 success, 0 end of input, -1 error. + */ +static int _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 == '^') { + bit_set_all(ps->charset); + + /* never transition on zero */ + bit_clear(ps->charset, 0); + neg = 1; + ptr++; + + } else + 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_info("incomplete charset " + "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) + bit_clear(ps->charset, lc); + else + bit_set(ps->charset, lc); + } + range = 0; + } else { + /* add c into the bitset */ + if(neg) + bit_clear(ps->charset, c); + else + 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 '|': + case '^': + case '$': + ps->type = (int) *ptr; + ps->cursor = ptr + 1; + break; + + case '.': + /* The 'all but newline' character set */ + ps->type = 0; + ps->cursor = ptr + 1; + bit_set_all(ps->charset); + bit_clear(ps->charset, (int) '\n'); + bit_clear(ps->charset, (int) '\r'); + bit_clear(ps->charset, 0); + break; + + case '\\': + /* escaped character */ + ptr++; + if(ptr >= ps->rx_end) { + log_info("badly quoted character at end " + "of expression"); + ps->type = -1; + return -1; + } + + ps->type = 0; + ps->cursor = ptr + 1; + bit_clear_all(ps->charset); + switch(*ptr) { + case 'n': bit_set(ps->charset, (int) '\n'); break; + case 'r': bit_set(ps->charset, (int) '\r'); break; + case 't': bit_set(ps->charset, (int) '\t'); break; + default: + bit_set(ps->charset, (int) *ptr); + } + break; + + default: + /* add a single character to the bitset */ + ps->type = 0; + ps->cursor = ptr + 1; + bit_clear_all(ps->charset); + bit_set(ps->charset, (int) *ptr); + break; + } + + return 1; +} + +static struct rx_node *_create_node(struct pool *mem, int type, + struct rx_node *l, struct rx_node *r) +{ + struct rx_node *n = pool_zalloc(mem, sizeof(*n)); + + if (n) { + if (!(n->charset = bitset_create(mem, 256))) { + pool_free(mem, n); + return NULL; + } + + n->type = type; + n->left = l; + n->right = r; + } + + return n; +} + +static struct rx_node *_term(struct parse_sp *ps) +{ + struct rx_node *n; + + switch(ps->type) { + case 0: + if (!(n = _create_node(ps->mem, CHARSET, NULL, NULL))) { + stack; + return NULL; + } + + bit_copy(n->charset, ps->charset); + _get_token(ps); /* match charset */ + break; + + case '(': + _get_token(ps); /* match '(' */ + n = _expr(ps, 0); + if(ps->type != ')') { + log_debug("missing ')' in regular expression"); + return 0; + } + _get_token(ps); /* match ')' */ + break; + + default: + n = 0; + } + + return n; +} + +static struct rx_node *_closure_term(struct parse_sp *ps) +{ + struct rx_node *l, *n; + + if(!(l = _term(ps))) + return NULL; + + switch(ps->type) { + case '*': + n = _create_node(ps->mem, STAR, l, NULL); + break; + + case '+': + n = _create_node(ps->mem, PLUS, l, NULL); + break; + + case '?': + n = _create_node(ps->mem, QUEST, l, NULL); + break; + + default: + return l; + } + + if (!n) { + stack; + return NULL; + } + + _get_token(ps); + return n; +} + +static struct rx_node *_cat_term(struct parse_sp *ps) +{ + struct rx_node *l, *r, *n; + + if (!(l = _closure_term(ps))) + return NULL; + + if (ps->type == '|') + /* bail out */ + return l; + + /* catenate */ + if (!(r = _cat_term(ps))) + return l; + + if (!(n = _create_node(ps->mem, CAT, l, r))) { + stack; + return NULL; + } + + return n; +} + +static struct rx_node *_expr(struct parse_sp *ps, struct rx_node *l) +{ + struct rx_node *n = 0; + while((ps->type >= 0) && (ps->type != ')')) { + + if (!(n = _create_node(ps->mem, CAT, l, NULL))) { + stack; + return NULL; + } + + switch(ps->type) { + case 0: + case '(': + /* implicit catenation */ + if(!l) + n = _cat_term(ps); + else + n->right = _cat_term(ps); + + break; + + case '|': + /* 'or' */ + if(!l) { + log_debug("badly formed '|' expression"); + return 0; + } + n->type = OR; + _get_token(ps); /* match '|' */ + n->right = _cat_term(ps); + break; + + default: + log_debug("unexpected token"); + return 0; + } + + if(!n) { + log_err("parse error in regex"); + return NULL; + } + + if((n->type != CHARSET) && !n->left) { + log_debug("badly formed regex"); + ps->type = -1; + ps->cursor = ps->rx_end; + return 0; + } + + l = n; + } + + return n; +} + +struct rx_node *rx_parse_tok(struct pool *mem, + const char *begin, const char *end) +{ + struct rx_node *r; + struct parse_sp *ps = pool_alloc(mem, sizeof(*ps)); + + if (!ps) { + stack; + return NULL; + } + + memset(ps, 0, sizeof(*ps)); + ps->mem = mem; + ps->charset = bitset_create(mem, 256); + ps->cursor = begin; + ps->rx_end = end; + _get_token(ps); /* load the first token */ + if (!(r = _expr(ps, NULL))) + pool_free(mem, ps); + + return r; +} + +struct rx_node *rx_parse_str(struct pool *mem, const char *str) +{ + return rx_parse_tok(mem, str, str + strlen(str)); +} diff --git a/lib/regex/parse_rx.h b/lib/regex/parse_rx.h new file mode 100644 index 000000000..f75c99502 --- /dev/null +++ b/lib/regex/parse_rx.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#ifndef _LVM_PARSE_REGEX_H +#define _LVM_PARSE_REGEX_H + +#include "bitset.h" + +enum { + CAT, + STAR, + PLUS, + OR, + QUEST, + CHARSET, + HAT, + DOLLAR +}; + +struct rx_node { + int type; + bitset_t charset; + struct rx_node *left, *right; + + /* used to build the dfa for the toker */ + int nullable, final; + bitset_t firstpos; + bitset_t lastpos; + bitset_t followpos; +}; + +struct rx_node *rx_parse_str(struct pool *mem, const char *str); +struct rx_node *rx_parse_tok(struct pool *mem, + const char *begin, const char *end); + +#endif diff --git a/lib/regex/ttree.c b/lib/regex/ttree.c new file mode 100644 index 000000000..38e6ba220 --- /dev/null +++ b/lib/regex/ttree.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "ttree.h" +#include "pool.h" +#include "log.h" + +#include + +struct node { + unsigned k; + struct node *l, *m, *r; + void *data; +}; + +struct ttree { + int klen; + struct pool *mem; + struct node *root; +}; + +struct ttree *ttree_create(struct pool *mem, unsigned int klen) +{ + struct ttree *tt; + + if (!(tt = pool_zalloc(mem, sizeof(*tt)))) { + stack; + return NULL; + } + + tt->klen = klen; + tt->mem = mem; + return tt; +} + +void *ttree_lookup(struct ttree *tt, unsigned *key) +{ + struct node *c = tt->root; + int count = tt->klen; + unsigned k = *key++; + + while (c) { + if (k < c->k) + c = c->l; + + else if (k > c->k) + c = c->r; + + else { + if (!--count) + break; + + c = c->m; + k = *key++; + } + } + + return c ? c->data : 0; +} + +void *ttree_insert(struct ttree *tt, unsigned *key, void *data) +{ + struct node *c = tt->root, *p = 0; + int count = tt->klen, first = 1; + unsigned k = *key; + void *r = NULL; + + while (c) { + p = c; + if (k < c->k) + c = c->l; + + else if (k > c->k) + c = c->r; + + else { + c = c->m; + if (!--count) + break; + + k = *++key; + } + } + + if (!count) { + /* key is already in the tree */ + r = p->data; + p->data = data; + + } else { + /* FIXME: put this in seperate function */ + /* insert new chain of nodes */ + while (count--) { + k = *key++; + c = pool_alloc(tt->mem, sizeof(*c)); + + if (!c) { + stack; + return NULL; + } + + c->k = k; + c->l = c->m = c->r = c->data = 0; + if (!p) + tt->root = c; + + else if (first) { + if (k < p->k) + p->l = c; + + else if (k > p->k) + p->r = c; + + else + p->m = c; + + first = 0; + } else + p->m = c; + p = c; + } + c->data = data; + } + + return r; +} diff --git a/lib/regex/ttree.h b/lib/regex/ttree.h new file mode 100644 index 000000000..06e116ffb --- /dev/null +++ b/lib/regex/ttree.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#ifndef _LVM_TTREE_H +#define _LVM_TTREE_H + +#include "pool.h" + +struct ttree; + +struct ttree *ttree_create(struct pool *mem, unsigned int klen); + +void *ttree_lookup(struct ttree *tt, unsigned *key); +void *ttree_insert(struct ttree *tt, unsigned *key, void *data); + +#endif diff --git a/old-tests/format1/read_vg_t.c b/old-tests/format1/read_vg_t.c index a5c93a2a6..8ce0c49fe 100644 --- a/old-tests/format1/read_vg_t.c +++ b/old-tests/format1/read_vg_t.c @@ -65,3 +65,4 @@ int main(int argc, char **argv) fin_log(); return 0; } + diff --git a/old-tests/regex/Makefile.in b/old-tests/regex/Makefile.in new file mode 100644 index 000000000..c1be29267 --- /dev/null +++ b/old-tests/regex/Makefile.in @@ -0,0 +1,26 @@ +# +# Copyright (C) 2001 Sistina Software (UK) Limited +# +# This file is released under the GPL. +# + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +SOURCES=\ + parse_t.c \ + matcher_t.c + +TARGETS=\ + parse_t \ + matcher_t + +include ../../make.tmpl + +parse_t: parse_t.o $(top_srcdir)/lib/liblvm.a + $(CC) -o parse_t parse_t.o -L$(top_srcdir)/lib -llvm + +matcher_t: matcher_t.o $(top_srcdir)/lib/liblvm.a + $(CC) -o matcher_t matcher_t.o -L$(top_srcdir)/lib -llvm + diff --git a/old-tests/regex/dev_patterns b/old-tests/regex/dev_patterns new file mode 100644 index 000000000..34459ba60 --- /dev/null +++ b/old-tests/regex/dev_patterns @@ -0,0 +1,2 @@ +"loop/[0-9]+" +"hd[a-d][0-5]+" diff --git a/old-tests/regex/devices.list b/old-tests/regex/devices.list new file mode 100644 index 000000000..91af305e1 --- /dev/null +++ b/old-tests/regex/devices.list @@ -0,0 +1,880 @@ +/dev +/dev/.devfsd +/dev/cpu +/dev/cpu/mtrr +/dev/netlink +/dev/netlink/route +/dev/netlink/skip +/dev/netlink/USERSOCK +/dev/netlink/fwmonitor +/dev/netlink/ARPD +/dev/netlink/ROUTE6 +/dev/netlink/IP6_FW +/dev/netlink/tap0 +/dev/netlink/tap1 +/dev/netlink/tap2 +/dev/netlink/tap3 +/dev/netlink/tap4 +/dev/netlink/tap5 +/dev/netlink/tap6 +/dev/netlink/tap7 +/dev/netlink/tap8 +/dev/netlink/tap9 +/dev/netlink/tap10 +/dev/netlink/tap11 +/dev/netlink/tap12 +/dev/netlink/tap13 +/dev/netlink/tap14 +/dev/netlink/tap15 +/dev/shm +/dev/mem +/dev/kmem +/dev/null +/dev/port +/dev/zero +/dev/full +/dev/random +/dev/urandom +/dev/tty +/dev/console +/dev/vc +/dev/vc/1 +/dev/vc/2 +/dev/vc/3 +/dev/vc/4 +/dev/vc/5 +/dev/vc/6 +/dev/vc/7 +/dev/vc/8 +/dev/vc/9 +/dev/vc/10 +/dev/vc/11 +/dev/vc/12 +/dev/vc/13 +/dev/vc/14 +/dev/vc/15 +/dev/vc/16 +/dev/vc/17 +/dev/vc/18 +/dev/vc/19 +/dev/vc/20 +/dev/vc/21 +/dev/vc/22 +/dev/vc/23 +/dev/vc/24 +/dev/vc/25 +/dev/vc/26 +/dev/vc/27 +/dev/vc/28 +/dev/vc/29 +/dev/vc/30 +/dev/vc/31 +/dev/vc/32 +/dev/vc/33 +/dev/vc/34 +/dev/vc/35 +/dev/vc/36 +/dev/vc/37 +/dev/vc/38 +/dev/vc/39 +/dev/vc/40 +/dev/vc/41 +/dev/vc/42 +/dev/vc/43 +/dev/vc/44 +/dev/vc/45 +/dev/vc/46 +/dev/vc/47 +/dev/vc/48 +/dev/vc/49 +/dev/vc/50 +/dev/vc/51 +/dev/vc/52 +/dev/vc/53 +/dev/vc/54 +/dev/vc/55 +/dev/vc/56 +/dev/vc/57 +/dev/vc/58 +/dev/vc/59 +/dev/vc/60 +/dev/vc/61 +/dev/vc/62 +/dev/vc/63 +/dev/vc/0 +/dev/ptmx +/dev/misc +/dev/misc/psaux +/dev/pty +/dev/pty/m0 +/dev/pty/m1 +/dev/pty/m2 +/dev/pty/m3 +/dev/pty/m4 +/dev/pty/m5 +/dev/pty/m6 +/dev/pty/m7 +/dev/pty/m8 +/dev/pty/m9 +/dev/pty/m10 +/dev/pty/m11 +/dev/pty/m12 +/dev/pty/m13 +/dev/pty/m14 +/dev/pty/m15 +/dev/pty/m16 +/dev/pty/m17 +/dev/pty/m18 +/dev/pty/m19 +/dev/pty/m20 +/dev/pty/m21 +/dev/pty/m22 +/dev/pty/m23 +/dev/pty/m24 +/dev/pty/m25 +/dev/pty/m26 +/dev/pty/m27 +/dev/pty/m28 +/dev/pty/m29 +/dev/pty/m30 +/dev/pty/m31 +/dev/pty/m32 +/dev/pty/m33 +/dev/pty/m34 +/dev/pty/m35 +/dev/pty/m36 +/dev/pty/m37 +/dev/pty/m38 +/dev/pty/m39 +/dev/pty/m40 +/dev/pty/m41 +/dev/pty/m42 +/dev/pty/m43 +/dev/pty/m44 +/dev/pty/m45 +/dev/pty/m46 +/dev/pty/m47 +/dev/pty/m48 +/dev/pty/m49 +/dev/pty/m50 +/dev/pty/m51 +/dev/pty/m52 +/dev/pty/m53 +/dev/pty/m54 +/dev/pty/m55 +/dev/pty/m56 +/dev/pty/m57 +/dev/pty/m58 +/dev/pty/m59 +/dev/pty/m60 +/dev/pty/m61 +/dev/pty/m62 +/dev/pty/m63 +/dev/pty/m64 +/dev/pty/m65 +/dev/pty/m66 +/dev/pty/m67 +/dev/pty/m68 +/dev/pty/m69 +/dev/pty/m70 +/dev/pty/m71 +/dev/pty/m72 +/dev/pty/m73 +/dev/pty/m74 +/dev/pty/m75 +/dev/pty/m76 +/dev/pty/m77 +/dev/pty/m78 +/dev/pty/m79 +/dev/pty/m80 +/dev/pty/m81 +/dev/pty/m82 +/dev/pty/m83 +/dev/pty/m84 +/dev/pty/m85 +/dev/pty/m86 +/dev/pty/m87 +/dev/pty/m88 +/dev/pty/m89 +/dev/pty/m90 +/dev/pty/m91 +/dev/pty/m92 +/dev/pty/m93 +/dev/pty/m94 +/dev/pty/m95 +/dev/pty/m96 +/dev/pty/m97 +/dev/pty/m98 +/dev/pty/m99 +/dev/pty/m100 +/dev/pty/m101 +/dev/pty/m102 +/dev/pty/m103 +/dev/pty/m104 +/dev/pty/m105 +/dev/pty/m106 +/dev/pty/m107 +/dev/pty/m108 +/dev/pty/m109 +/dev/pty/m110 +/dev/pty/m111 +/dev/pty/m112 +/dev/pty/m113 +/dev/pty/m114 +/dev/pty/m115 +/dev/pty/m116 +/dev/pty/m117 +/dev/pty/m118 +/dev/pty/m119 +/dev/pty/m120 +/dev/pty/m121 +/dev/pty/m122 +/dev/pty/m123 +/dev/pty/m124 +/dev/pty/m125 +/dev/pty/m126 +/dev/pty/m127 +/dev/pty/m128 +/dev/pty/m129 +/dev/pty/m130 +/dev/pty/m131 +/dev/pty/m132 +/dev/pty/m133 +/dev/pty/m134 +/dev/pty/m135 +/dev/pty/m136 +/dev/pty/m137 +/dev/pty/m138 +/dev/pty/m139 +/dev/pty/m140 +/dev/pty/m141 +/dev/pty/m142 +/dev/pty/m143 +/dev/pty/m144 +/dev/pty/m145 +/dev/pty/m146 +/dev/pty/m147 +/dev/pty/m148 +/dev/pty/m149 +/dev/pty/m150 +/dev/pty/m151 +/dev/pty/m152 +/dev/pty/m153 +/dev/pty/m154 +/dev/pty/m155 +/dev/pty/m156 +/dev/pty/m157 +/dev/pty/m158 +/dev/pty/m159 +/dev/pty/m160 +/dev/pty/m161 +/dev/pty/m162 +/dev/pty/m163 +/dev/pty/m164 +/dev/pty/m165 +/dev/pty/m166 +/dev/pty/m167 +/dev/pty/m168 +/dev/pty/m169 +/dev/pty/m170 +/dev/pty/m171 +/dev/pty/m172 +/dev/pty/m173 +/dev/pty/m174 +/dev/pty/m175 +/dev/pty/m176 +/dev/pty/m177 +/dev/pty/m178 +/dev/pty/m179 +/dev/pty/m180 +/dev/pty/m181 +/dev/pty/m182 +/dev/pty/m183 +/dev/pty/m184 +/dev/pty/m185 +/dev/pty/m186 +/dev/pty/m187 +/dev/pty/m188 +/dev/pty/m189 +/dev/pty/m190 +/dev/pty/m191 +/dev/pty/m192 +/dev/pty/m193 +/dev/pty/m194 +/dev/pty/m195 +/dev/pty/m196 +/dev/pty/m197 +/dev/pty/m198 +/dev/pty/m199 +/dev/pty/m200 +/dev/pty/m201 +/dev/pty/m202 +/dev/pty/m203 +/dev/pty/m204 +/dev/pty/m205 +/dev/pty/m206 +/dev/pty/m207 +/dev/pty/m208 +/dev/pty/m209 +/dev/pty/m210 +/dev/pty/m211 +/dev/pty/m212 +/dev/pty/m213 +/dev/pty/m214 +/dev/pty/m215 +/dev/pty/m216 +/dev/pty/m217 +/dev/pty/m218 +/dev/pty/m219 +/dev/pty/m220 +/dev/pty/m221 +/dev/pty/m222 +/dev/pty/m223 +/dev/pty/m224 +/dev/pty/m225 +/dev/pty/m226 +/dev/pty/m227 +/dev/pty/m228 +/dev/pty/m229 +/dev/pty/m230 +/dev/pty/m231 +/dev/pty/m232 +/dev/pty/m233 +/dev/pty/m234 +/dev/pty/m235 +/dev/pty/m236 +/dev/pty/m237 +/dev/pty/m238 +/dev/pty/m239 +/dev/pty/m240 +/dev/pty/m241 +/dev/pty/m242 +/dev/pty/m243 +/dev/pty/m244 +/dev/pty/m245 +/dev/pty/m246 +/dev/pty/m247 +/dev/pty/m248 +/dev/pty/m249 +/dev/pty/m250 +/dev/pty/m251 +/dev/pty/m252 +/dev/pty/m253 +/dev/pty/m254 +/dev/pty/m255 +/dev/pts +/dev/pts/0 +/dev/pts/1 +/dev/pts/2 +/dev/pts/3 +/dev/pts/4 +/dev/pts/5 +/dev/pts/6 +/dev/pts/7 +/dev/vcc +/dev/vcc/0 +/dev/vcc/a +/dev/vcc/1 +/dev/vcc/a1 +/dev/vcc/2 +/dev/vcc/a2 +/dev/vcc/3 +/dev/vcc/a3 +/dev/vcc/5 +/dev/vcc/a5 +/dev/vcc/4 +/dev/vcc/a4 +/dev/vcc/6 +/dev/vcc/a6 +/dev/vcc/7 +/dev/vcc/a7 +/dev/tts +/dev/tts/0 +/dev/cua +/dev/cua/0 +/dev/ide +/dev/ide/host0 +/dev/ide/host0/bus0 +/dev/ide/host0/bus0/target0 +/dev/ide/host0/bus0/target0/lun0 +/dev/ide/host0/bus0/target0/lun0/disc +/dev/ide/host0/bus0/target0/lun0/part1 +/dev/ide/host0/bus0/target0/lun0/part2 +/dev/ide/host0/bus0/target0/lun0/part3 +/dev/ide/host0/bus0/target0/lun0/part4 +/dev/ide/host0/bus0/target0/lun0/part5 +/dev/ide/host0/bus0/target0/lun0/part6 +/dev/ide/host0/bus0/target0/lun0/part7 +/dev/ide/host0/bus0/target0/lun0/part8 +/dev/ide/host0/bus0/target1 +/dev/ide/host0/bus0/target1/lun0 +/dev/ide/host0/bus0/target1/lun0/disc +/dev/ide/host0/bus0/target1/lun0/part1 +/dev/ide/host0/bus1 +/dev/ide/host0/bus1/target0 +/dev/ide/host0/bus1/target0/lun0 +/dev/ide/host0/bus1/target0/lun0/disc +/dev/ide/host0/bus1/target0/lun0/part1 +/dev/ide/host0/bus1/target1 +/dev/ide/host0/bus1/target1/lun0 +/dev/discs +/dev/discs/disc0 +/dev/discs/disc1 +/dev/discs/disc2 +/dev/floppy +/dev/floppy/0u1440 +/dev/floppy/0u1680 +/dev/floppy/0u1722 +/dev/floppy/0u1743 +/dev/floppy/0u1760 +/dev/floppy/0u1920 +/dev/floppy/0u1840 +/dev/floppy/0u1600 +/dev/floppy/0u360 +/dev/floppy/0u720 +/dev/floppy/0u820 +/dev/floppy/0u830 +/dev/floppy/0u1040 +/dev/floppy/0u1120 +/dev/floppy/0u800 +/dev/floppy/0 +/dev/loop +/dev/loop/0 +/dev/loop/1 +/dev/loop/2 +/dev/loop/3 +/dev/loop/4 +/dev/loop/5 +/dev/loop/6 +/dev/loop/7 +/dev/cdroms +/dev/sound +/dev/sound/dsp +/dev/sound/dsp1 +/dev/sound/mixer +/dev/sound/midi +/dev/usb +/dev/root +/dev/initctl +/dev/xconsole +/dev/fd +/dev/stdin +/dev/stdout +/dev/stderr +/dev/route +/dev/skip +/dev/USERSOCK +/dev/fwmonitor +/dev/ARPD +/dev/ROUTE6 +/dev/IP6_FW +/dev/tap0 +/dev/tap1 +/dev/tap2 +/dev/tap3 +/dev/tap4 +/dev/tap5 +/dev/tap6 +/dev/tap7 +/dev/tap8 +/dev/tap9 +/dev/tap10 +/dev/tap11 +/dev/tap12 +/dev/tap13 +/dev/tap14 +/dev/tap15 +/dev/tty1 +/dev/tty2 +/dev/tty3 +/dev/tty4 +/dev/tty5 +/dev/tty6 +/dev/tty7 +/dev/tty8 +/dev/tty9 +/dev/tty10 +/dev/tty11 +/dev/tty12 +/dev/tty13 +/dev/tty14 +/dev/tty15 +/dev/tty16 +/dev/tty17 +/dev/tty18 +/dev/tty19 +/dev/tty20 +/dev/tty21 +/dev/tty22 +/dev/tty23 +/dev/tty24 +/dev/tty25 +/dev/tty26 +/dev/tty27 +/dev/tty28 +/dev/tty29 +/dev/tty30 +/dev/tty31 +/dev/tty32 +/dev/tty33 +/dev/tty34 +/dev/tty35 +/dev/tty36 +/dev/tty37 +/dev/tty38 +/dev/tty39 +/dev/tty40 +/dev/tty41 +/dev/tty42 +/dev/tty43 +/dev/tty44 +/dev/tty45 +/dev/tty46 +/dev/tty47 +/dev/tty48 +/dev/tty49 +/dev/tty50 +/dev/tty51 +/dev/tty52 +/dev/tty53 +/dev/tty54 +/dev/tty55 +/dev/tty56 +/dev/tty57 +/dev/tty58 +/dev/tty59 +/dev/tty60 +/dev/tty61 +/dev/tty62 +/dev/tty63 +/dev/tty0 +/dev/psaux +/dev/ptyp0 +/dev/ptyp1 +/dev/ptyp2 +/dev/ptyp3 +/dev/ptyp4 +/dev/ptyp5 +/dev/ptyp6 +/dev/ptyp7 +/dev/ptyp8 +/dev/ptyp9 +/dev/ptypa +/dev/ptypb +/dev/ptypc +/dev/ptypd +/dev/ptype +/dev/ptypf +/dev/ptyq0 +/dev/ptyq1 +/dev/ptyq2 +/dev/ptyq3 +/dev/ptyq4 +/dev/ptyq5 +/dev/ptyq6 +/dev/ptyq7 +/dev/ptyq8 +/dev/ptyq9 +/dev/ptyqa +/dev/ptyqb +/dev/ptyqc +/dev/ptyqd +/dev/ptyqe +/dev/ptyqf +/dev/ptyr0 +/dev/ptyr1 +/dev/ptyr2 +/dev/ptyr3 +/dev/ptyr4 +/dev/ptyr5 +/dev/ptyr6 +/dev/ptyr7 +/dev/ptyr8 +/dev/ptyr9 +/dev/ptyra +/dev/ptyrb +/dev/ptyrc +/dev/ptyrd +/dev/ptyre +/dev/ptyrf +/dev/ptys0 +/dev/ptys1 +/dev/ptys2 +/dev/ptys3 +/dev/ptys4 +/dev/ptys5 +/dev/ptys6 +/dev/ptys7 +/dev/ptys8 +/dev/ptys9 +/dev/ptysa +/dev/ptysb +/dev/ptysc +/dev/ptysd +/dev/ptyse +/dev/ptysf +/dev/ptyt0 +/dev/ptyt1 +/dev/ptyt2 +/dev/ptyt3 +/dev/ptyt4 +/dev/ptyt5 +/dev/ptyt6 +/dev/ptyt7 +/dev/ptyt8 +/dev/ptyt9 +/dev/ptyta +/dev/ptytb +/dev/ptytc +/dev/ptytd +/dev/ptyte +/dev/ptytf +/dev/ptyu0 +/dev/ptyu1 +/dev/ptyu2 +/dev/ptyu3 +/dev/ptyu4 +/dev/ptyu5 +/dev/ptyu6 +/dev/ptyu7 +/dev/ptyu8 +/dev/ptyu9 +/dev/ptyua +/dev/ptyub +/dev/ptyuc +/dev/ptyud +/dev/ptyue +/dev/ptyuf +/dev/ptyv0 +/dev/ptyv1 +/dev/ptyv2 +/dev/ptyv3 +/dev/ptyv4 +/dev/ptyv5 +/dev/ptyv6 +/dev/ptyv7 +/dev/ptyv8 +/dev/ptyv9 +/dev/ptyva +/dev/ptyvb +/dev/ptyvc +/dev/ptyvd +/dev/ptyve +/dev/ptyvf +/dev/ptyw0 +/dev/ptyw1 +/dev/ptyw2 +/dev/ptyw3 +/dev/ptyw4 +/dev/ptyw5 +/dev/ptyw6 +/dev/ptyw7 +/dev/ptyw8 +/dev/ptyw9 +/dev/ptywa +/dev/ptywb +/dev/ptywc +/dev/ptywd +/dev/ptywe +/dev/ptywf +/dev/ptyx0 +/dev/ptyx1 +/dev/ptyx2 +/dev/ptyx3 +/dev/ptyx4 +/dev/ptyx5 +/dev/ptyx6 +/dev/ptyx7 +/dev/ptyx8 +/dev/ptyx9 +/dev/ptyxa +/dev/ptyxb +/dev/ptyxc +/dev/ptyxd +/dev/ptyxe +/dev/ptyxf +/dev/ptyy0 +/dev/ptyy1 +/dev/ptyy2 +/dev/ptyy3 +/dev/ptyy4 +/dev/ptyy5 +/dev/ptyy6 +/dev/ptyy7 +/dev/ptyy8 +/dev/ptyy9 +/dev/ptyya +/dev/ptyyb +/dev/ptyyc +/dev/ptyyd +/dev/ptyye +/dev/ptyyf +/dev/ptyz0 +/dev/ptyz1 +/dev/ptyz2 +/dev/ptyz3 +/dev/ptyz4 +/dev/ptyz5 +/dev/ptyz6 +/dev/ptyz7 +/dev/ptyz8 +/dev/ptyz9 +/dev/ptyza +/dev/ptyzb +/dev/ptyzc +/dev/ptyzd +/dev/ptyze +/dev/ptyzf +/dev/ptya0 +/dev/ptya1 +/dev/ptya2 +/dev/ptya3 +/dev/ptya4 +/dev/ptya5 +/dev/ptya6 +/dev/ptya7 +/dev/ptya8 +/dev/ptya9 +/dev/ptyaa +/dev/ptyab +/dev/ptyac +/dev/ptyad +/dev/ptyae +/dev/ptyaf +/dev/ptyb0 +/dev/ptyb1 +/dev/ptyb2 +/dev/ptyb3 +/dev/ptyb4 +/dev/ptyb5 +/dev/ptyb6 +/dev/ptyb7 +/dev/ptyb8 +/dev/ptyb9 +/dev/ptyba +/dev/ptybb +/dev/ptybc +/dev/ptybd +/dev/ptybe +/dev/ptybf +/dev/ptyc0 +/dev/ptyc1 +/dev/ptyc2 +/dev/ptyc3 +/dev/ptyc4 +/dev/ptyc5 +/dev/ptyc6 +/dev/ptyc7 +/dev/ptyc8 +/dev/ptyc9 +/dev/ptyca +/dev/ptycb +/dev/ptycc +/dev/ptycd +/dev/ptyce +/dev/ptycf +/dev/ptyd0 +/dev/ptyd1 +/dev/ptyd2 +/dev/ptyd3 +/dev/ptyd4 +/dev/ptyd5 +/dev/ptyd6 +/dev/ptyd7 +/dev/ptyd8 +/dev/ptyd9 +/dev/ptyda +/dev/ptydb +/dev/ptydc +/dev/ptydd +/dev/ptyde +/dev/ptydf +/dev/ptye0 +/dev/ptye1 +/dev/ptye2 +/dev/ptye3 +/dev/ptye4 +/dev/ptye5 +/dev/ptye6 +/dev/ptye7 +/dev/ptye8 +/dev/ptye9 +/dev/ptyea +/dev/ptyeb +/dev/ptyec +/dev/ptyed +/dev/ptyee +/dev/ptyef +/dev/vcs +/dev/vcsa +/dev/vcs1 +/dev/vcsa1 +/dev/ttyS0 +/dev/cua0 +/dev/hda +/dev/hda1 +/dev/hda2 +/dev/hda3 +/dev/hda4 +/dev/hda5 +/dev/hda6 +/dev/hda7 +/dev/hda8 +/dev/hdb +/dev/hdb1 +/dev/hdc +/dev/hdc1 +/dev/fd0u1440 +/dev/fd0u1680 +/dev/fd0u1722 +/dev/fd0u1743 +/dev/fd0u1760 +/dev/fd0u1920 +/dev/fd0u1840 +/dev/fd0u1600 +/dev/fd0u360 +/dev/fd0u720 +/dev/fd0u820 +/dev/fd0u830 +/dev/fd0u1040 +/dev/fd0u1120 +/dev/fd0u800 +/dev/fd0 +/dev/loop0 +/dev/loop1 +/dev/loop2 +/dev/loop3 +/dev/loop4 +/dev/loop5 +/dev/loop6 +/dev/loop7 +/dev/dsp +/dev/dsp1 +/dev/mixer +/dev/midi +/dev/lvm +/dev/vg0 +/dev/vg0/group +/dev/vg0/packages +/dev/vg0/photos +/dev/vg0/music +/dev/log +/dev/MAKEDEV +/dev/printer +/dev/vcs2 +/dev/vcsa2 +/dev/vcs3 +/dev/vcsa3 +/dev/vcs5 +/dev/vcsa5 +/dev/vcs4 +/dev/vcsa4 +/dev/vcs6 +/dev/vcsa6 +/dev/nvidia0 +/dev/nvidia1 +/dev/nvidia2 +/dev/nvidia3 +/dev/nvidiactl +/dev/vcs7 +/dev/vcsa7 diff --git a/old-tests/regex/matcher_t.c b/old-tests/regex/matcher_t.c new file mode 100644 index 000000000..00deea94f --- /dev/null +++ b/old-tests/regex/matcher_t.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "matcher.h" +#include "dbg_malloc.h" +#include "log.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int _read_spec(const char *file, char ***regex, int *nregex) +{ + char buffer[1024], *start, *ptr; + FILE *fp = fopen(file, "r"); + int asize = 100; + char **rx = dbg_malloc(sizeof(*rx) * asize); + int nr = 0; + + if (!fp) + return 0; + + while (fgets(buffer, sizeof(buffer),fp)) { + + /* trim leading whitespace */ + for (ptr = buffer; *ptr && isspace((int) *ptr); ptr++); + + if (!*ptr || *ptr == '#') + continue; + + if (*ptr == '\"') { + ptr++; + start = ptr; + while (*ptr && *ptr != '\"') { + if (*ptr == '\\') + ptr++; + ptr++; + } + + if (!*ptr) { + fprintf(stderr, "Formatting error : " + "No terminating quote\n"); + return 0; + } + + rx[nr] = dbg_malloc((ptr - start) + 1); + strncpy(rx[nr], start, ptr - start); + rx[nr][ptr - start] = '\0'; + nr++; + } else { + fprintf(stderr, "%s", ptr); + fprintf(stderr, "Formatting error : \"\" " + "\n"); + return 0; + } + } + + *regex = rx; + *nregex = nr; + return 1; +} + +static void _free_regex(char **regex, int nregex) +{ + int i; + for (i = 0; i < nregex; i++) + dbg_free(regex[i]); + + dbg_free(regex); +} + +static void _scan_input(struct matcher *m, char **regex) +{ + char buffer[256], *ptr; + int r; + + while (fgets(buffer, sizeof(buffer), stdin)) { + if ((ptr = strchr(buffer, '\n'))) + *ptr = '\0'; + + r = matcher_run(m, buffer, buffer + strlen(buffer)); + + if (r >= 0) + printf("%s : %s\n", buffer, regex[r]); + } +} + +int main(int argc, char **argv) +{ + struct pool *mem; + struct matcher *scanner; + char **regex; + int nregex; + + if (argc < 2) { + fprintf(stderr, "Usage : %s \n", argv[0]); + exit(1); + } + + init_log(stderr); + init_debug(_LOG_DEBUG); + + if (!(mem = pool_create(10 * 1024))) { + fprintf(stderr, "Couldn't create pool\n"); + exit(2); + } + + if (!_read_spec(argv[1], ®ex, &nregex)) { + fprintf(stderr, "Couldn't read the lex specification\n"); + exit(3); + } + + if (!(scanner = matcher_create(mem, (const char **) regex, nregex))) { + fprintf(stderr, "Couldn't build the lexer\n"); + exit(4); + } + + _scan_input(scanner, regex); + _free_regex(regex, nregex); + pool_destroy(mem); + + dump_memory(); + fin_log(); + return 0; +} + diff --git a/old-tests/regex/parse_t.c b/old-tests/regex/parse_t.c new file mode 100644 index 000000000..25bf7f9c2 --- /dev/null +++ b/old-tests/regex/parse_t.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dbg_malloc.h" +#include "log.h" +#include "../../lib/regex/parse_rx.h" +#include "bitset.h" + +#include +#include + +static void _pretty_print(struct rx_node *rx, int depth) +{ + int i; + for (i = 0; i < depth; i++) + printf(" "); + + /* display info about the node */ + switch (rx->type) { + case CAT: + printf("Cat"); + break; + + case OR: + printf("Or"); + break; + + case STAR: + printf("Star"); + break; + + case PLUS: + printf("Plus"); + break; + + case QUEST: + printf("Quest"); + break; + + case CHARSET: + printf("Charset : "); + for (i = 0; i < 256; i++) { + if (bit(rx->charset, i) && isprint(i)) + printf("%c", (char) i); + } + break; + + default: + printf("Unknown type"); + } + printf("\n"); + + if (rx->left) + _pretty_print(rx->left, depth + 1); + + if (rx->right) + _pretty_print(rx->right, depth + 1); +} + + +int main(int argc, char **argv) +{ + struct pool *mem; + struct rx_node *rx; + + if (argc != 2) { + fprintf(stderr, "Usage : %s \n", argv[0]); + exit(0); + } + + init_log(stderr); + init_debug(_LOG_INFO); + + if (!(mem = pool_create(1024))) { + fprintf(stderr, "Couldn't create pool\n"); + exit(1); + } + + if (!(rx = rx_parse_str(mem, argv[1]))) { + fprintf(stderr, "Couldn't parse regex\n"); + exit(1); + } + + _pretty_print(rx, 0); + pool_destroy(mem); + + dump_memory(); + fin_log(); + return 0; +}