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
13 * Szabo, Janos Zoltan – initial implementation
16 ******************************************************************************/
18 #include <sys/types.h>
20 #include "../common/memory.h"
21 #include "../common/pattern.hh"
26 #include "Charstring.hh"
27 #define ERRMSG_BUFSIZE2 500
29 Token_Match::Token_Match(const char *posix_str
, boolean case_sensitive
,
31 : posix_regexp_begin()
32 , posix_regexp_first()
33 , token_str(posix_str
)
37 if (posix_str
== NULL
|| posix_str
[0] == '\0') {
45 fixed_len
= strlen(posix_str
);
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");
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
);
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
);
64 ret_val
= regcomp(&posix_regexp_first
, posix_str
+ 1, regcomp_flags
);
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
);
75 Token_Match::~Token_Match()
77 if (!null_match
&& fixed_len
== 0) {
78 regfree(&posix_regexp_begin
);
79 regfree(&posix_regexp_first
);
83 int Token_Match::match_begin(TTCN_Buffer
& buff
) const
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");
102 if (fixed_len
!= 0) { //
103 retval
=strncmp((const char*)buff
.get_read_data(), token_str
, fixed_len
)
107 regmatch_t pmatch
[2];
108 ret_val
=regexec(&posix_regexp_begin
,(const char*)buff
.get_read_data(),
111 retval
=pmatch
[1].rm_eo
-pmatch
[1].rm_so
; // pmatch[1] is the capture group
112 } else if (ret_val
==REG_NOMATCH
) {
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
);
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();
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",
138 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC
, "match_begin result: %d",
144 int Token_Match::match_first(TTCN_Buffer
& buff
) const
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");
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
);
170 regmatch_t pmatch
[2];
171 ret_val
=regexec(&posix_regexp_first
,(const char*)buff
.get_read_data(),
172 2, pmatch
, REG_NOTBOL
);
174 retval
=pmatch
[1].rm_so
;
175 } else if (ret_val
==REG_NOMATCH
) {
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
);
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
);
199 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC
, "match_begin regexec result: %d, %s",
202 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC
, "match_first result: %d",
208 Limit_Token_List::Limit_Token_List(){
211 list
=(const Token_Match
**)Malloc(size_of_list
*sizeof(Token_Match
*));
212 last_match
=(int *)Malloc(size_of_list
*sizeof(int));
217 Limit_Token_List::~Limit_Token_List(){
222 void Limit_Token_List::add_token(const Token_Match
*token
){
223 if(num_of_tokens
==size_of_list
){
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));
228 list
[num_of_tokens
]=token
;
229 last_match
[num_of_tokens
]=-1;
233 void Limit_Token_List::remove_tokens(size_t num
){
234 if(num_of_tokens
<num
) num_of_tokens
=0;
235 else num_of_tokens
-=num
;
238 int Limit_Token_List::match(TTCN_Buffer
& buff
, size_t lim
){
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());
243 int diff
=curr_pos
-last_pos
;
245 for(size_t a
=0;a
<num_of_tokens
;a
++){
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
];
260 last_ret_val
=ret_val
;
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
);
271 const TTCN_TEXTdescriptor_t INTEGER_text_
= { NULL
, NULL
, NULL
, NULL
,
272 NULL
, NULL
, NULL
, { NULL
} };
274 const TTCN_TEXTdescriptor_t BOOLEAN_text_
= { NULL
, NULL
, NULL
, NULL
,
275 NULL
, NULL
, NULL
, { NULL
} };
277 const TTCN_TEXTdescriptor_t CHARSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
278 NULL
, NULL
, NULL
, { NULL
} };
280 const TTCN_TEXTdescriptor_t UNIVERSAL_CHARSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
281 NULL
, NULL
, NULL
, { NULL
} };
283 const TTCN_TEXTdescriptor_t BITSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
284 NULL
, NULL
, NULL
, { NULL
} };
286 const TTCN_TEXTdescriptor_t HEXSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
287 NULL
, NULL
, NULL
, { NULL
} };
289 const TTCN_TEXTdescriptor_t OCTETSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
290 NULL
, NULL
, NULL
, { NULL
} };