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 ///////////////////////////////////////////////////////////////////////////////
11 #include "../common/memory.h"
12 #include "../common/pattern.hh"
17 #include "Charstring.hh"
18 #define ERRMSG_BUFSIZE2 500
20 Token_Match::Token_Match(const char *posix_str
, boolean case_sensitive
,
22 : posix_regexp_begin()
23 , posix_regexp_first()
24 , token_str(posix_str
)
28 if (posix_str
== NULL
|| posix_str
[0] == '\0') {
36 fixed_len
= strlen(posix_str
);
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");
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
);
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
);
55 ret_val
= regcomp(&posix_regexp_first
, posix_str
+ 1, regcomp_flags
);
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
);
66 Token_Match::~Token_Match()
68 if (!null_match
&& fixed_len
== 0) {
69 regfree(&posix_regexp_begin
);
70 regfree(&posix_regexp_first
);
74 int Token_Match::match_begin(TTCN_Buffer
& buff
) const
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");
93 if (fixed_len
!= 0) { //
94 retval
=strncmp((const char*)buff
.get_read_data(), token_str
, fixed_len
)
99 ret_val
=regexec(&posix_regexp_begin
,(const char*)buff
.get_read_data(),
102 retval
=pmatch
[1].rm_eo
-pmatch
[1].rm_so
; // pmatch[1] is the capture group
103 } else if (ret_val
==REG_NOMATCH
) {
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
);
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();
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",
129 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC
, "match_begin result: %d",
135 int Token_Match::match_first(TTCN_Buffer
& buff
) const
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");
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
);
161 regmatch_t pmatch
[2];
162 ret_val
=regexec(&posix_regexp_first
,(const char*)buff
.get_read_data(),
163 2, pmatch
, REG_NOTBOL
);
165 retval
=pmatch
[1].rm_so
;
166 } else if (ret_val
==REG_NOMATCH
) {
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
);
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
);
190 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC
, "match_begin regexec result: %d, %s",
193 TTCN_Logger::log(TTCN_Logger::DEBUG_ENCDEC
, "match_first result: %d",
199 Limit_Token_List::Limit_Token_List(){
202 list
=(const Token_Match
**)Malloc(size_of_list
*sizeof(Token_Match
*));
203 last_match
=(int *)Malloc(size_of_list
*sizeof(int));
208 Limit_Token_List::~Limit_Token_List(){
213 void Limit_Token_List::add_token(const Token_Match
*token
){
214 if(num_of_tokens
==size_of_list
){
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));
219 list
[num_of_tokens
]=token
;
220 last_match
[num_of_tokens
]=-1;
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
;
229 int Limit_Token_List::match(TTCN_Buffer
& buff
, size_t lim
){
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());
234 int diff
=curr_pos
-last_pos
;
236 for(size_t a
=0;a
<num_of_tokens
;a
++){
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
];
251 last_ret_val
=ret_val
;
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
);
262 const TTCN_TEXTdescriptor_t INTEGER_text_
= { NULL
, NULL
, NULL
, NULL
,
263 NULL
, NULL
, NULL
, { NULL
} };
265 const TTCN_TEXTdescriptor_t BOOLEAN_text_
= { NULL
, NULL
, NULL
, NULL
,
266 NULL
, NULL
, NULL
, { NULL
} };
268 const TTCN_TEXTdescriptor_t CHARSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
269 NULL
, NULL
, NULL
, { NULL
} };
271 const TTCN_TEXTdescriptor_t UNIVERSAL_CHARSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
272 NULL
, NULL
, NULL
, { NULL
} };
274 const TTCN_TEXTdescriptor_t BITSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
275 NULL
, NULL
, NULL
, { NULL
} };
277 const TTCN_TEXTdescriptor_t HEXSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
278 NULL
, NULL
, NULL
, { NULL
} };
280 const TTCN_TEXTdescriptor_t OCTETSTRING_text_
= { NULL
, NULL
, NULL
, NULL
,
281 NULL
, NULL
, NULL
, { NULL
} };