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