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 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 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 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 * 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 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 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 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