1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#ifdef BENCHMARK_CHELP
5#include <sys/time.h>
6#endif
7#include "chelper.h"
8
9int NewOnigRegex( char *pattern, int pattern_length, int option,
10 OnigRegex *regex, OnigEncoding *encoding, OnigErrorInfo **error_info, char **error_buffer) {
11 int ret = ONIG_NORMAL;
12 int error_msg_len = 0;
13
14 OnigUChar *pattern_start = (OnigUChar *) pattern;
15 OnigUChar *pattern_end = (OnigUChar *) (pattern + pattern_length);
16
17 *error_info = (OnigErrorInfo *) malloc(sizeof(OnigErrorInfo));
18 memset(*error_info, 0, sizeof(OnigErrorInfo));
19
20 onig_initialize_encoding(*encoding);
21
22 *error_buffer = (char*) malloc(ONIG_MAX_ERROR_MESSAGE_LEN * sizeof(char));
23
24 memset(*error_buffer, 0, ONIG_MAX_ERROR_MESSAGE_LEN * sizeof(char));
25
26 ret = onig_new(regex, pattern_start, pattern_end, (OnigOptionType)(option), *encoding, OnigDefaultSyntax, *error_info);
27
28 if (ret != ONIG_NORMAL) {
29 error_msg_len = onig_error_code_to_str((unsigned char*)(*error_buffer), ret, *error_info);
30 if (error_msg_len >= ONIG_MAX_ERROR_MESSAGE_LEN) {
31 error_msg_len = ONIG_MAX_ERROR_MESSAGE_LEN - 1;
32 }
33 (*error_buffer)[error_msg_len] = '\0';
34 }
35 return ret;
36}
37
38int SearchOnigRegex( void *str, int str_length, int offset, int option,
39 OnigRegex regex, OnigErrorInfo *error_info, char *error_buffer, int *captures, int *numCaptures) {
40 int ret = ONIG_MISMATCH;
41 int error_msg_len = 0;
42 OnigRegion *region;
43#ifdef BENCHMARK_CHELP
44 struct timeval tim1, tim2;
45 long t;
46#endif
47
48 OnigUChar *str_start = (OnigUChar *) str;
49 OnigUChar *str_end = (OnigUChar *) (str_start + str_length);
50 OnigUChar *search_start = (OnigUChar *)(str_start + offset);
51 OnigUChar *search_end = str_end;
52
53#ifdef BENCHMARK_CHELP
54 gettimeofday(&tim1, NULL);
55#endif
56
57 region = onig_region_new();
58
59 ret = onig_search(regex, str_start, str_end, search_start, search_end, region, option);
60 if (ret < 0 && error_buffer != NULL) {
61 error_msg_len = onig_error_code_to_str((unsigned char*)(error_buffer), ret, error_info);
62 if (error_msg_len >= ONIG_MAX_ERROR_MESSAGE_LEN) {
63 error_msg_len = ONIG_MAX_ERROR_MESSAGE_LEN - 1;
64 }
65 error_buffer[error_msg_len] = '\0';
66 }
67 else if (captures != NULL) {
68 int i;
69 int count = 0;
70 for (i = 0; i < region->num_regs; i++) {
71 captures[2*count] = region->beg[i];
72 captures[2*count+1] = region->end[i];
73 count ++;
74 }
75 *numCaptures = count;
76 }
77
78 onig_region_free(region, 1);
79
80#ifdef BENCHMARK_CHELP
81 gettimeofday(&tim2, NULL);
82 t = (tim2.tv_sec - tim1.tv_sec) * 1000000 + tim2.tv_usec - tim1.tv_usec;
83 printf("%ld microseconds elapsed\n", t);
84#endif
85 return ret;
86}
87
88int MatchOnigRegex(void *str, int str_length, int offset, int option,
89 OnigRegex regex) {
90 int ret = ONIG_MISMATCH;
91 int error_msg_len = 0;
92 OnigRegion *region;
93#ifdef BENCHMARK_CHELP
94 struct timeval tim1, tim2;
95 long t;
96#endif
97
98 OnigUChar *str_start = (OnigUChar *) str;
99 OnigUChar *str_end = (OnigUChar *) (str_start + str_length);
100 OnigUChar *search_start = (OnigUChar *)(str_start + offset);
101
102#ifdef BENCHMARK_CHELP
103 gettimeofday(&tim1, NULL);
104#endif
105 region = onig_region_new();
106 ret = onig_match(regex, str_start, str_end, search_start, region, option);
107 onig_region_free(region, 1);
108#ifdef BENCHMARK_CHELP
109 gettimeofday(&tim2, NULL);
110 t = (tim2.tv_sec - tim1.tv_sec) * 1000000 + tim2.tv_usec - tim1.tv_usec;
111 printf("%ld microseconds elapsed\n", t);
112#endif
113 return ret;
114}
115
116int LookupOnigCaptureByName(char *name, int name_length,
117 OnigRegex regex) {
118 int ret = ONIGERR_UNDEFINED_NAME_REFERENCE;
119 OnigRegion *region;
120#ifdef BENCHMARK_CHELP
121 struct timeval tim1, tim2;
122 long t;
123#endif
124 OnigUChar *name_start = (OnigUChar *) name;
125 OnigUChar *name_end = (OnigUChar *) (name_start + name_length);
126#ifdef BENCHMARK_CHELP
127 gettimeofday(&tim1, NULL);
128#endif
129 region = onig_region_new();
130 ret = onig_name_to_backref_number(regex, name_start, name_end, region);
131 onig_region_free(region, 1);
132#ifdef BENCHMARK_CHELP
133 gettimeofday(&tim2, NULL);
134 t = (tim2.tv_sec - tim1.tv_sec) * 1000000 + tim2.tv_usec - tim1.tv_usec;
135 printf("%ld microseconds elapsed\n", t);
136#endif
137 return ret;
138}
139
140typedef struct {
141 char *nameBuffer;
142 int bufferOffset;
143 int bufferSize;
144 int *numbers;
145 int numIndex;
146} group_info_t;
147
148int name_callback(const UChar* name, const UChar* name_end,
149 int ngroup_num, int* group_nums,
150 regex_t* reg, void* arg)
151{
152 int nameLen, offset, newOffset;
153 group_info_t *groupInfo;
154
155 groupInfo = (group_info_t*) arg;
156 offset = groupInfo->bufferOffset;
157 nameLen = name_end - name;
158 newOffset = offset + nameLen;
159
160 //if there are already names, add a ";"
161 if (offset > 0) {
162 newOffset += 1;
163 }
164
165 if (newOffset <= groupInfo->bufferSize) {
166 if (offset > 0) {
167 groupInfo->nameBuffer[offset] = ';';
168 offset += 1;
169 }
170 memcpy(&groupInfo->nameBuffer[offset], name, nameLen);
171 }
172 groupInfo->bufferOffset = newOffset;
173 if (ngroup_num > 0) {
174 groupInfo->numbers[groupInfo->numIndex] = group_nums[ngroup_num-1];
175 } else {
176 groupInfo->numbers[groupInfo->numIndex] = -1;
177 }
178 groupInfo->numIndex += 1;
179 return 0; /* 0: continue */
180}
181
182int GetCaptureNames(OnigRegex reg, void *buffer, int bufferSize, int* groupNumbers) {
183 int ret;
184 group_info_t groupInfo;
185 groupInfo.nameBuffer = (char*)buffer;
186 groupInfo.bufferOffset = 0;
187 groupInfo.bufferSize = bufferSize;
188 groupInfo.numbers = groupNumbers;
189 groupInfo.numIndex = 0;
190 onig_foreach_name(reg, name_callback, (void* )&groupInfo);
191 return groupInfo.bufferOffset;
192}