xref: /netbsd-src/external/bsd/tre/dist/tests/test-str-source.c (revision 63d4abf06d37aace2f9e41a494102a64fe3abddb)
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