1 /*
2 test-str-source.c - Sample program for using tre_reguexec()
3
4 This software is released under a BSD-style license.
5 See the file LICENSE for details and copyright.
6
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif /* HAVE_CONFIG_H */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include "regex.h"
17 #include "tre-internal.h"
18
19 /* Context structure for the tre_str_source wrappers. */
20 typedef struct {
21 /* Our string. */
22 const char *str;
23 /* Current position in the string. */
24 size_t pos;
25 } str_handler_ctx;
26
27 /* The get_next_char() handler. Sets `c' to the value of the next character,
28 and increases `pos_add' by the number of bytes read. Returns 1 if the
29 string has ended, 0 if there are more characters. */
30 static int
str_handler_get_next(tre_char_t * c,unsigned int * pos_add,void * context)31 str_handler_get_next(tre_char_t *c, unsigned int *pos_add, void *context)
32 {
33 str_handler_ctx *ctx = context;
34 unsigned char ch = ctx->str[ctx->pos];
35
36 printf("str[%lu] = %d\n", (unsigned long)ctx->pos, ch);
37 *c = ch;
38 if (ch)
39 ctx->pos++;
40 *pos_add = 1;
41
42 return ch == '\0';
43 }
44
45 /* The rewind() handler. Resets the current position in the input string. */
46 static void
str_handler_rewind(size_t pos,void * context)47 str_handler_rewind(size_t pos, void *context)
48 {
49 str_handler_ctx *ctx = context;
50
51 printf("rewind to %lu\n", (unsigned long)pos);
52 ctx->pos = pos;
53 }
54
55 /* The compare() handler. Compares two substrings in the input and returns
56 0 if the substrings are equal, and a nonzero value if not. */
57 static int
str_handler_compare(size_t pos1,size_t pos2,size_t len,void * context)58 str_handler_compare(size_t pos1, size_t pos2, size_t len, void *context)
59 {
60 str_handler_ctx *ctx = context;
61 printf("comparing %lu-%lu and %lu-%lu\n",
62 (unsigned long)pos1, (unsigned long)pos1 + len,
63 (unsigned long)pos2, (unsigned long)pos2 + len);
64 return strncmp(ctx->str + pos1, ctx->str + pos2, len);
65 }
66
67 /* Creates a tre_str_source wrapper around the string `str'. Returns the
68 tre_str_source object or NULL if out of memory. */
69 static tre_str_source *
make_str_source(const char * str)70 make_str_source(const char *str)
71 {
72 tre_str_source *s;
73 str_handler_ctx *ctx;
74
75 s = calloc(1, sizeof(*s));
76 if (!s)
77 return NULL;
78
79 ctx = malloc(sizeof(str_handler_ctx));
80 if (!ctx)
81 {
82 free(s);
83 return NULL;
84 }
85
86 ctx->str = str;
87 ctx->pos = 0;
88 s->context = ctx;
89 s->get_next_char = str_handler_get_next;
90 s->rewind = str_handler_rewind;
91 s->compare = str_handler_compare;
92
93 return s;
94 }
95
96 /* Frees the memory allocated for `s'. */
97 static void
free_str_source(tre_str_source * s)98 free_str_source(tre_str_source *s)
99 {
100 free(s->context);
101 free(s);
102 }
103
104 /* Run one test with tre_reguexec */
105 static void
test_reguexec(const char * str,const char * regex)106 test_reguexec(const char *str, const char *regex)
107 {
108 regex_t preg;
109 tre_str_source *source;
110 regmatch_t pmatch[5];
111
112 source = make_str_source(str);
113 if (!source)
114 return;
115
116 tre_regcomp(&preg, regex, REG_EXTENDED);
117 if (tre_reguexec(&preg, source, elementsof(pmatch), pmatch, 0) == 0)
118 printf("Match: %d - %d\n", (int)pmatch[0].rm_so, (int)pmatch[0].rm_eo);
119
120 free_str_source(source);
121 tre_regfree(&preg);
122 }
123
124 int
main(int argc,char ** argv)125 main(int argc, char **argv)
126 {
127 test_reguexec("xfoofofoofoo","(foo)\\1");
128 test_reguexec("catcat","(cat|dog)\\1");
129 test_reguexec("catdog","(cat|dog)\\1");
130 test_reguexec("dogdog","(cat|dog)\\1");
131 test_reguexec("dogcat","(cat|dog)\\1");
132
133 return 0;
134 }
135