1 /*
2 * echo.c
3 */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include "oniguruma.h"
8
9 static int
echo(OnigCalloutArgs * args,void * user_data)10 echo(OnigCalloutArgs* args, void* user_data)
11 {
12 int r;
13 OnigCalloutIn in;
14 OnigType type;
15 OnigValue val;
16 FILE* fp;
17
18 fp = stdout;
19
20 in = onig_get_callout_in_by_callout_args(args);
21
22 r = onig_get_arg_by_callout_args(args, 1, &type, &val);
23 if (r != ONIG_NORMAL) return r;
24
25 if (in == ONIG_CALLOUT_IN_PROGRESS) {
26 if (val.c == '<')
27 return ONIG_CALLOUT_SUCCESS;
28 }
29 else {
30 if (val.c != 'X' && val.c != '<')
31 return ONIG_CALLOUT_SUCCESS;
32 }
33
34 r = onig_get_arg_by_callout_args(args, 0, &type, &val);
35 if (r != ONIG_NORMAL) return r;
36
37
38 fprintf(fp, "%s %s\n",
39 (in == ONIG_CALLOUT_IN_PROGRESS ? "=>" : "<="),
40 val.s.start);
41 fflush(fp);
42
43 return ONIG_CALLOUT_SUCCESS;
44 }
45
46
47 static int
test(OnigEncoding enc,char * in_pattern,char * in_str)48 test(OnigEncoding enc, char* in_pattern, char* in_str)
49 {
50 int r;
51 unsigned char *start, *range, *end;
52 regex_t* reg;
53 OnigErrorInfo einfo;
54 OnigRegion *region;
55 UChar* pattern;
56 UChar* str;
57
58 pattern = (UChar* )in_pattern;
59 str = (UChar* )in_str;
60
61 r = onig_new(®, pattern, pattern + strlen((char* )pattern),
62 ONIG_OPTION_DEFAULT, enc, ONIG_SYNTAX_DEFAULT, &einfo);
63 if (r != ONIG_NORMAL) {
64 char s[ONIG_MAX_ERROR_MESSAGE_LEN];
65 onig_error_code_to_str((UChar* )s, r, &einfo);
66 fprintf(stderr, "COMPILE ERROR: %d: %s\n", r, s);
67 return -1;
68 }
69
70 region = onig_region_new();
71
72 end = str + strlen((char* )str);
73 start = str;
74 range = end;
75 r = onig_search(reg, str, end, start, range, region, ONIG_OPTION_NONE);
76 if (r >= 0) {
77 int i;
78
79 fprintf(stderr, "match at %d\n", r);
80 for (i = 0; i < region->num_regs; i++) {
81 fprintf(stderr, "%d: (%d-%d)\n", i, region->beg[i], region->end[i]);
82 }
83 }
84 else if (r == ONIG_MISMATCH) {
85 fprintf(stderr, "search fail\n");
86 }
87 else { /* error */
88 char s[ONIG_MAX_ERROR_MESSAGE_LEN];
89 onig_error_code_to_str((UChar* )s, r);
90 fprintf(stderr, "SEARCH ERROR: %d: %s\n", r, s);
91 }
92
93 onig_region_free(region, 1 /* 1:free self, 0:free contents only */);
94 onig_free(reg);
95 return r;
96 }
97
main(int argc,char * argv[])98 extern int main(int argc, char* argv[])
99 {
100 int r;
101 int id;
102 UChar* name;
103 OnigEncoding use_encs[1];
104 OnigType arg_types[4];
105 OnigValue opt_defaults[4];
106 OnigEncoding enc;
107
108 enc = ONIG_ENCODING_UTF8;
109 use_encs[0] = enc;
110
111 r = onig_initialize(use_encs, sizeof(use_encs)/sizeof(use_encs[0]));
112 if (r != ONIG_NORMAL) return -1;
113
114 name = (UChar* )"echo";
115 arg_types[0] = ONIG_TYPE_STRING;
116 arg_types[1] = ONIG_TYPE_CHAR;
117 opt_defaults[0].s.start = (UChar* )"echo";
118 opt_defaults[0].s.end = opt_defaults[0].s.start +
119 strlen((char* )opt_defaults[0].s.start);
120 opt_defaults[1].c = '>';
121
122 id = onig_set_callout_of_name(enc, ONIG_CALLOUT_TYPE_SINGLE,
123 name, name + strlen((char* )name),
124 ONIG_CALLOUT_IN_BOTH, echo, 0,
125 2, arg_types, 2, opt_defaults);
126 if (id < 0) {
127 fprintf(stderr, "ERROR: fail to set callout of name: %s\n", name);
128 return -1;
129 }
130
131 test(enc, "(?:(*echo{abc!!!})a|b)*", "abba");
132 test(enc, "(?:(*echo{xyz,X})a|b)*", "abba");
133
134 onig_end();
135 return 0;
136 }
137