Sync with 5.3.0
[deliverable/titan.core.git] / core / TEXT.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include <string.h>
9 #include <sys/types.h>
10 #include <regex.h>
11 #include "../common/memory.h"
12 #include "../common/pattern.hh"
13 #include "TEXT.hh"
14 #include "Addfunc.hh"
15 #include "Logger.hh"
16 #include "Integer.hh"
17 #include "Charstring.hh"
18 #define ERRMSG_BUFSIZE2 500
19
20 Token_Match::Token_Match(const char *posix_str, boolean case_sensitive,
21 boolean fixed)
22 : posix_regexp_begin()
23 , posix_regexp_first()
24 , token_str(posix_str)
25 , fixed_len(0)
26 , null_match(FALSE)
27 {
28 if (posix_str == NULL || posix_str[0] == '\0') {
29 token_str = "";
30 null_match = TRUE;
31 return;
32 }
33
34 if (fixed) {
35 // no regexp
36 fixed_len = strlen(posix_str);
37
38 if (!case_sensitive) {
39 // Can't happen. The compiler should always generate
40 // case sensitive matching for fixed strings.
41 TTCN_EncDec_ErrorContext::error_internal(
42 "Case insensitive fixed string matching not implemented");
43 }
44 }
45 else {
46 int regcomp_flags = REG_EXTENDED;
47 if (!case_sensitive) regcomp_flags |= REG_ICASE;
48 int ret_val = regcomp(&posix_regexp_begin, posix_str, regcomp_flags);
49 if (ret_val != 0) {
50 char msg[ERRMSG_BUFSIZE2];
51 regerror(ret_val, &posix_regexp_begin, msg, ERRMSG_BUFSIZE2);
52 TTCN_error("Internal error: regcomp() failed on posix_regexp_begin when "
53 "constructing Token_Match: %s", msg);
54 }
55 ret_val = regcomp(&posix_regexp_first, posix_str + 1, regcomp_flags);
56 if (ret_val != 0) {
57 regfree(&posix_regexp_begin);
58 char msg[ERRMSG_BUFSIZE2];
59 regerror(ret_val, &posix_regexp_first, msg, ERRMSG_BUFSIZE2);
60 TTCN_error("Internal error: regcomp() failed on posix_regexp_first when "
61 "constructing Token_Match: %s", msg);
62 }
63 }
64 }
65
66 Token_Match::~Token_Match()
67 {
68 if (!null_match && fixed_len == 0) {
69 regfree(&posix_regexp_begin);
70 regfree(&posix_regexp_first);
71 }
72 }
73
74 int Token_Match::match_begin(TTCN_Buffer& buff) const
75 {
76 int retval=-1;
77 int ret_val=-1;
78 if(null_match){
79 if (TTCN_EncDec::get_error_behavior(TTCN_EncDec::ET_LOG_MATCHING) !=
80 TTCN_EncDec::EB_IGNORE) {
81 char msg[ERRMSG_BUFSIZE2];
82 regerror(ret_val, &posix_regexp_begin, msg, ERRMSG_BUFSIZE2);
83 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_begin data: %s",
84 (const char*)buff.get_read_data());
85 TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
86 TTCN_Logger::log_event_str("match_begin token: null_match");
87 TTCN_Logger::end_event();
88 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_begin result: 0");
89 }
90
91 return 0;
92 }
93 if (fixed_len != 0) { //
94 retval=strncmp((const char*)buff.get_read_data(), token_str, fixed_len)
95 ? -1 // not matched
96 : fixed_len;
97 } else {
98 regmatch_t pmatch[2];
99 ret_val=regexec(&posix_regexp_begin,(const char*)buff.get_read_data(),
100 2, pmatch, 0);
101 if(ret_val==0) {
102 retval=pmatch[1].rm_eo-pmatch[1].rm_so; // pmatch[1] is the capture group
103 } else if (ret_val==REG_NOMATCH) {
104 retval=-1;
105 } else {
106 /* regexp error */
107 char msg[ERRMSG_BUFSIZE2];
108 regerror(ret_val, &posix_regexp_begin, msg, ERRMSG_BUFSIZE2);
109 TTCN_error("Internal error: regexec() failed in "
110 "Token_Match::match_begin(): %s", msg);
111 }
112 }
113 if (TTCN_EncDec::get_error_behavior(TTCN_EncDec::ET_LOG_MATCHING) !=
114 TTCN_EncDec::EB_IGNORE) {
115 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_begin data: %s",
116 (const char*)buff.get_read_data());
117 TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
118 TTCN_Logger::log_event_str("match_begin token: \"");
119 for (size_t i = 0; token_str[i] != '\0'; i++)
120 TTCN_Logger::log_char_escaped(token_str[i]);
121 TTCN_Logger::log_char('"');
122 TTCN_Logger::end_event();
123 if(fixed_len == 0){
124 char msg[ERRMSG_BUFSIZE2];
125 regerror(ret_val, &posix_regexp_begin, msg, ERRMSG_BUFSIZE2);
126 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_begin regexec result: %d, %s",
127 ret_val,msg);
128 }
129 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_begin result: %d",
130 retval);
131 }
132 return retval;
133 }
134
135 int Token_Match::match_first(TTCN_Buffer& buff) const
136 {
137 int retval=-1;
138 int ret_val=-1;
139 if(null_match){
140 if (TTCN_EncDec::get_error_behavior(TTCN_EncDec::ET_LOG_MATCHING) !=
141 TTCN_EncDec::EB_IGNORE) {
142 char msg[ERRMSG_BUFSIZE2];
143 regerror(ret_val, &posix_regexp_begin, msg, ERRMSG_BUFSIZE2);
144 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_first data: %s",
145 (const char*)buff.get_read_data());
146 TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
147 TTCN_Logger::log_event_str("match_first token: null_match");
148 TTCN_Logger::end_event();
149 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_first result: 0");
150 }
151
152 return 0;
153 }
154 //TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC,"match_first data: %s\n\r",(const char*)buff.get_read_data());
155 //TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC,"match_first token: %s\n\r",token);
156 if (fixed_len != 0) {
157 const char *haystack = (const char*)buff.get_read_data();
158 const char *pos = strstr(haystack, token_str); // TODO smarter search: Boyer-Moore / Shift-Or
159 retval = (pos == NULL) ? -1 : (pos - haystack);
160 } else {
161 regmatch_t pmatch[2];
162 ret_val=regexec(&posix_regexp_first,(const char*)buff.get_read_data(),
163 2, pmatch, REG_NOTBOL);
164 if(ret_val==0) {
165 retval=pmatch[1].rm_so;
166 } else if (ret_val==REG_NOMATCH) {
167 retval=-1;
168 } else {
169 /* regexp error */
170 char msg[ERRMSG_BUFSIZE2];
171 regerror(ret_val, &posix_regexp_begin, msg, ERRMSG_BUFSIZE2);
172 TTCN_error("Internal error: regexec() failed in "
173 "Token_Match::match_first(): %s", msg);
174 }
175 }
176 if (TTCN_EncDec::get_error_behavior(TTCN_EncDec::ET_LOG_MATCHING) !=
177 TTCN_EncDec::EB_IGNORE) {
178 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_first data: %s",
179 (const char*)buff.get_read_data());
180 TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
181 TTCN_Logger::log_event_str("match_first token: \"");
182 for (size_t i = 0; token_str[i] != '\0'; i++)
183 TTCN_Logger::log_char_escaped(token_str[i]);
184 TTCN_Logger::log_char('"');
185 TTCN_Logger::end_event();
186 if (fixed_len == 0) {
187 char msg[ERRMSG_BUFSIZE2];
188 regerror(ret_val, &posix_regexp_begin, msg, ERRMSG_BUFSIZE2);
189
190 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_begin regexec result: %d, %s",
191 ret_val,msg);
192 }
193 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC, "match_first result: %d",
194 retval);
195 }
196 return retval;
197 }
198
199 Limit_Token_List::Limit_Token_List(){
200 num_of_tokens=0;
201 size_of_list=16;
202 list=(const Token_Match **)Malloc(size_of_list*sizeof(Token_Match *));
203 last_match=(int *)Malloc(size_of_list*sizeof(int));
204 last_ret_val=-1;
205 last_pos=NULL;
206 }
207
208 Limit_Token_List::~Limit_Token_List(){
209 Free(list);
210 Free(last_match);
211 }
212
213 void Limit_Token_List::add_token(const Token_Match *token){
214 if(num_of_tokens==size_of_list){
215 size_of_list*=2;
216 list=(const Token_Match **)Realloc(list,size_of_list*sizeof(Token_Match *));
217 last_match=(int *)Realloc(last_match,size_of_list*sizeof(int));
218 }
219 list[num_of_tokens]=token;
220 last_match[num_of_tokens]=-1;
221 num_of_tokens++;
222 }
223
224 void Limit_Token_List::remove_tokens(size_t num){
225 if(num_of_tokens<num) num_of_tokens=0;
226 else num_of_tokens-=num;
227 }
228
229 int Limit_Token_List::match(TTCN_Buffer& buff, size_t lim){
230 int ret_val=-1;
231 const char* curr_pos=(const char*)buff.get_read_data();
232 //TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC,"Limit Token begin: %s\n\r",(const char*)buff.get_read_data());
233 if(last_pos!=NULL){
234 int diff=curr_pos-last_pos;
235 if(diff){
236 for(size_t a=0;a<num_of_tokens;a++){
237 last_match[a]-=diff;
238 }
239 last_ret_val-=diff;
240 }
241 }
242 last_pos=curr_pos;
243 // if(last_ret_val<0){
244 for(size_t a=0;a<num_of_tokens-lim;a++){
245 if(last_match[a]<0) last_match[a]=list[a]->match_first(buff);
246 if(last_match[a]>=0){
247 if(ret_val==-1) ret_val=last_match[a];
248 else if(last_match[a]<ret_val) ret_val=last_match[a];
249 }
250 }
251 last_ret_val=ret_val;
252 // }
253 if (TTCN_EncDec::get_error_behavior(TTCN_EncDec::ET_LOG_MATCHING)!=
254 TTCN_EncDec::EB_IGNORE) {
255 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC,
256 "match_list data: %s",(const char*)buff.get_read_data());
257 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC,"match_list result: %d",ret_val);
258 }
259 return ret_val;
260 }
261
262 const TTCN_TEXTdescriptor_t INTEGER_text_ = { NULL, NULL, NULL, NULL,
263 NULL, NULL, NULL, { NULL } };
264
265 const TTCN_TEXTdescriptor_t BOOLEAN_text_ = { NULL, NULL, NULL, NULL,
266 NULL, NULL, NULL, { NULL } };
267
268 const TTCN_TEXTdescriptor_t CHARSTRING_text_ = { NULL, NULL, NULL, NULL,
269 NULL, NULL, NULL, { NULL } };
270
271 const TTCN_TEXTdescriptor_t UNIVERSAL_CHARSTRING_text_ = { NULL, NULL, NULL, NULL,
272 NULL, NULL, NULL, { NULL } };
273
274 const TTCN_TEXTdescriptor_t BITSTRING_text_ = { NULL, NULL, NULL, NULL,
275 NULL, NULL, NULL, { NULL } };
276
277 const TTCN_TEXTdescriptor_t HEXSTRING_text_ = { NULL, NULL, NULL, NULL,
278 NULL, NULL, NULL, { NULL } };
279
280 const TTCN_TEXTdescriptor_t OCTETSTRING_text_ = { NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, { NULL } };
This page took 0.037008 seconds and 5 git commands to generate.