1 : /*
2 : * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
3 : * and/or its subsidiary(-ies).
4 : * Contact: Konrad Marek Zapalowicz
5 : * Contact e-mail: DG.MIN-Support@nokia.com
6 : *
7 : * This program is free software: you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the Free
9 : * Software Foundation, version 2 of the License.
10 : *
11 : * This program is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 : * more details. You should have received a copy of the GNU General Public
15 : * License along with this program. If not, see
16 : * <http://www.gnu.org/licenses/>.
17 : */
18 :
19 : /**
20 : * @file scripter_plugin.c
21 : * @version 0.1
22 : * @brief This file contains implementation of MIN Scripter plugin.
23 : */
24 :
25 : /* ------------------------------------------------------------------------- */
26 : /* INCLUDE FILES */
27 : #include <ctype.h>
28 : #include <string.h>
29 :
30 : #include <scripter_plugin.h>
31 : #include <min_logger.h>
32 : /* ------------------------------------------------------------------------- */
33 : /* EXTERNAL DATA STRUCTURES */
34 : /* None */
35 :
36 : /* ------------------------------------------------------------------------- */
37 : /* EXTERNAL GLOBAL VARIABLES */
38 : extern DLList *defines;
39 : /* ------------------------------------------------------------------------- */
40 : /* EXTERNAL FUNCTION PROTOTYPES */
41 : //extern char *strcasestr (const char *haystack,const char *needle);
42 : //extern char *strchr(const char *s, int c);
43 :
44 : /* ------------------------------------------------------------------------- */
45 : /* GLOBAL VARIABLES */
46 : /* None */
47 :
48 : /* ------------------------------------------------------------------------- */
49 : /* CONSTANTS */
50 : /* None */
51 :
52 : /* ------------------------------------------------------------------------- */
53 : /* MACROS */
54 : #define SCRIPTER_SYNTAX_ERROR(__keyword__,__errstr__)\
55 : do {\
56 : MIN_ERROR ("Test case \"%s\": line %d: %s keyword syntax error - %s.",\
57 : tc_title ? tc_title : "<null>", line_number, __keyword__, \
58 : __errstr__ );\
59 : tm_print_err ("Test case \"%s\": line %d:"\
60 : " %s keyword syntax error - %s.", \
61 : tc_title ? tc_title : "<null>", line_number, __keyword__,\
62 : __errstr__);\
63 : } while (0)
64 :
65 : #define SCRIPTER_SYNTAX_ERROR_ARG(__keyword__,__errstr__,__arg__) \
66 : do {\
67 : MIN_ERROR ("Test case \"%s\": line %d: %s keyword syntax error - "\
68 : "%s:%s",tc_title ? tc_title : "<null>", line_number, \
69 : __keyword__,__errstr__, __arg__); \
70 : tm_print_err ("Test case \"%s\": line %d: %s keyword syntax error - " \
71 : "%s:%s", tc_title ? tc_title : "<null>", line_number, \
72 : __keyword__, __errstr__, __arg__); \
73 : } while (0)
74 :
75 : #define SCRIPTER_ERROR(__errstr__,__arg__)\
76 : do {\
77 : MIN_ERROR ("Test case \"%s\": line %d: error - " \
78 : "%s %s", tc_title ? tc_title : "<null>", line_number,\
79 : __errstr__, __arg__); \
80 : tm_print_err ("Test case \"%s\": line %d: error - " \
81 : "%s %s", tc_title ? tc_title : "<null>", line_number, \
82 : __errstr__, __arg__); \
83 : } while (0)
84 :
85 : /* ------------------------------------------------------------------------- */
86 : /* LOCAL GLOBAL VARIABLES */
87 : /* ------------------------------------------------------------------------- */
88 : /** list of allocated slaves. Used during the validation process. */
89 : static LegoBasicType *current = INITPTR;
90 : /** used for validation of stopping interference */
91 : /* ------------------------------------------------------------------------- */
92 : /* LOCAL CONSTANTS AND MACROS */
93 : /* None */
94 :
95 : /* ------------------------------------------------------------------------- */
96 : /* MODULE DATA STRUCTURES */
97 : /* None */
98 : /* ------------------------------------------------------------------------- */
99 : /* LOCAL FUNCTION PROTOTYPES */
100 : /* ------------------------------------------------------------------------- */
101 : LOCAL int look4slave (const void *a, const void *b);
102 : /* ------------------------------------------------------------------------- */
103 : /** Handles keyword
104 : * @param keyword [in] keyword to be handled
105 : * @param mip [in] item parser which contains the rest of the line
106 : *
107 : * NOTE: Item parser should be rewinded after usage in order to be able
108 : * to correctly handle loops.
109 : */
110 : LOCAL void interpreter_handle_keyword (TScripterKeyword keyword,
111 : MinItemParser * mip);
112 : /* ------------------------------------------------------------------------- */
113 : /** Checks validity of line with "run" keyword
114 : * @param line - min item parser containing line. Assume that
115 : * mip_get_line was executed once to extract first keyword
116 : * @param line_number - line number for debug messages
117 : * @param tc_title - title of validated test case
118 : * @return 0 if line is valid*/
119 : LOCAL int check_run_line (MinItemParser * line, int line_number,
120 : char * tc_title);
121 : /* ------------------------------------------------------------------------- */
122 : /** Checks validitye of line with "pause" keyword
123 : * @param line - min item parser containing line. Assume that
124 : * mip_get_line was executed once to extract first keyword
125 : * @param line_number - line number for debug messages
126 : * @param tc_title - title of validated test case
127 : * @return 0 if line is valid*/
128 : LOCAL int check_pause_line (MinItemParser * line, int line_number,
129 : char * tc_title);
130 : /* ------------------------------------------------------------------------- */
131 : /** Checks validity of line with "loop" keyword
132 : * @param line - min item parser containing line. Assume that
133 : * mip_get_line was executed once to extract first keyword
134 : * @param line_number - line number for debug messages
135 : * @param tc_title - title of validated test case
136 : * @return 0 if line is valid*/
137 : LOCAL int check_loop_line (MinItemParser * line, int line_number,
138 : char * tc_title);
139 : /* ------------------------------------------------------------------------- */
140 : /** Checks validity of line with "allocate" keyword
141 : * @param line [in] MinItemParser containing line.
142 : * @param line_number - line number for debug messages
143 : * @param slaves [in] list of slaves
144 : * @param tc_title - title of validated test case
145 : * @return ENOERR if line is valid, -1 otherwise.
146 : *
147 : * NOTE: mip_get_line was executed once to extract first keyword.
148 : */
149 : LOCAL int check_allocate_line (MinItemParser * line, int line_number,
150 : DLList * slaves, char * tc_title);
151 : /* ------------------------------------------------------------------------- */
152 : /** Checks validity of line with "free" keyword
153 : * @param line [in] MinItemParser containing line.
154 : * @param line_number - line number for debug messages
155 : * @param slaves [in] list of slaves
156 : * @param tc_title - title of validated test case
157 : * @return ENOERR if line is valid, -1 otherwise.
158 : *
159 : * NOTE: mip_get_line was executed once to extract first keyword.
160 : */
161 : LOCAL int check_free_line (MinItemParser * line, int line_number,
162 : DLList * slaves, char * tc_title);
163 : /* ------------------------------------------------------------------------- */
164 : /** Checks validity of line with "remote" keyword
165 : * @param line [in] MinItemParser containing line.
166 : * @param variables [in] list of variables
167 : * @param line_number - line number for debug messages
168 : * @param slaves [in] list of slaves
169 : * @param tc_title - title of validated test case
170 : * @return ENOERR if line is valid, -1 otherwise.
171 : *
172 : * NOTE: mip_get_line was executed once to extract first keyword.
173 : */
174 : LOCAL int check_remote_line (MinItemParser * line, DLList * variables,
175 : int line_number, DLList * slaves,
176 : char * tc_title);
177 : /* ------------------------------------------------------------------------- */
178 : /** Checks validity of line with "allownextresult" keyword
179 : * @param line [in] MinItemParser containing line.
180 : * @param line_number - line number for debug messages
181 : * @param tc_title - title of validated test case
182 : * @return ENOERR if line is valid, -1 otherwise.
183 : *
184 : * NOTE: mip_get_line was executed once to extract first keyword.
185 : */
186 : LOCAL int check_allownextresult_line (MinItemParser * line,
187 : int line_number,
188 : char * tc_title);
189 : /* ------------------------------------------------------------------------- */
190 : /** Checks validity of line with "complete" keyword
191 : * @param line [in] MinItemParser containing line.
192 : * @param line_number - line number for debug messages
193 : * @param tc_title - title of validated test case
194 : * @return ENOERR if line is valid, -1 otherwise.
195 : *
196 : * NOTE: mip_get_line was executed once to extract first keyword.
197 : */
198 : LOCAL int check_complete_line (MinItemParser * line, int line_number,
199 : char * tc_title);
200 : /* ------------------------------------------------------------------------- */
201 : /** Checks validity of line with "timeout" keyword
202 : * @param line [in] MinItemParser containing line.
203 : * @param line_number - line number for debug messages
204 : * @param tc_title - title of validated test case
205 : * @return ENOERR if line is valid, -1 otherwise.
206 : *
207 : * NOTE: mip_get_line was executed once to extract first keyword.
208 : */
209 : LOCAL int check_timeout_line (MinItemParser * line, int line_number,
210 : char * tc_title);
211 : /* ------------------------------------------------------------------------- */
212 : /** Checks validity of line with "sleep" keyword
213 : * @param line [in] MinItemParser containing line.
214 : * @param line_number - line number for debug messages
215 : * @param tc_title - title of validated test case
216 : * @return ENOERR if line is valid, -1 otherwise.
217 : *
218 : * NOTE: mip_get_line was executed once to extract first keyword.
219 : */
220 : LOCAL int check_sleep_line (MinItemParser * line, int line_number,
221 : char * tc_title);
222 : /* ------------------------------------------------------------------------- */
223 : /** Checks validity of line with "testinterference" keyword
224 : * @param line [in] MinItemParser containing line.
225 : * @param line_number - line number for debug messages
226 : * @param interf_objs list of interference objects
227 : * @param tc_title - title of validated test case
228 : * @return ENOERR if line is valid, -1 otherwise.
229 : *
230 : * NOTE: mip_get_line was executed once to extract first keyword.
231 : */
232 : LOCAL int check_interference_line (MinItemParser * line,
233 : int line_number,
234 : DLList * interf_objs,
235 : char * tc_title);
236 : /* ------------------------------------------------------------------------- */
237 : /** Checks validity of line with "expect" keyword
238 : * @param line [in] MinItemParser containing line.
239 : * @param line_number - line number for debug messages
240 : * @param tc_title - title of validated test case
241 : * @return ENOERR if line is valid, -1 otherwise.
242 : *
243 : * NOTE: mip_get_line was executed once to extract first keyword.
244 : */
245 : LOCAL int check_expect_line (MinItemParser * line, DLList * varnames,
246 : int line_number, char * tc_title);
247 : /* ------------------------------------------------------------------------- */
248 : /** Checks validity of line with "if" keyword
249 : * @param line [in] MinItemParser containing line.
250 : * @param line_number - line number for debug messages
251 : * @param tc_title - title of validated test case
252 : * @return ENOERR if line is valid, -1 otherwise.
253 : */
254 : LOCAL int check_if_line (MinItemParser * line, int line_number,
255 : char * tc_title);
256 :
257 : /* ------------------------------------------------------------------------- */
258 : /* FORWARD DECLARATIONS */
259 : /* None */
260 : /* ------------------------------------------------------------------------- */
261 : /* ==================== LOCAL FUNCTIONS ==================================== */
262 : /* ------------------------------------------------------------------------- */
263 : LOCAL int check_expect_line (MinItemParser * line, DLList * varnames,
264 : int line_number, char *tc_title)
265 0 : {
266 0 : char *varname = NULL;
267 0 : char *workstring = NULL;
268 0 : int retval = ENOERR;
269 :
270 0 : DLListIterator it = DLListNULLIterator;
271 0 : mip_get_next_string (line, &varname);
272 0 : it = dl_list_head (varnames);
273 0 : while (it != DLListNULLIterator) {
274 0 : workstring = (char *)dl_list_data (it);
275 0 : if (strcmp (workstring, varname) == 0) {
276 0 : break;
277 : }
278 0 : it = dl_list_next (it);
279 : }
280 0 : if (it == DLListNULLIterator) {
281 0 : SCRIPTER_SYNTAX_ERROR ("expect",
282 : "Expecting undeclared variable");
283 0 : retval = -1;
284 : }
285 0 : return retval;
286 : }
287 :
288 : /* ------------------------------------------------------------------------- */
289 : LOCAL int look4slave (const void *a, const void *b)
290 227 : {
291 227 : return strcmp ((char *)a, (char *)b);
292 : }
293 :
294 : /* ------------------------------------------------------------------------- */
295 : LOCAL void interpreter_handle_keyword (TScripterKeyword keyword,
296 : MinItemParser * mip)
297 207 : {
298 207 : char *parser_pos = mip->item_skip_and_mark_pos_;
299 207 : char *token = INITPTR;
300 207 : char *token2 = INITPTR;
301 : char *p;
302 207 : int ival = -1;
303 :
304 207 : if (mip == INITPTR) {
305 0 : errno = EINVAL;
306 0 : goto EXIT;
307 : }
308 :
309 : /* Handle keyword */
310 207 : switch (keyword) {
311 : case EKeywordTitle:
312 39 : MIN_DEBUG ("EKeywordTitle");
313 : /* "title <testcasename>" */
314 39 : mip_get_next_string (mip, &token);
315 39 : break;
316 : case EKeywordSkipIt:
317 0 : MIN_DEBUG ("EKeywordSkipIt");
318 : /* "waittestclass <testcasename>" */
319 0 : mip_get_next_string (mip, &token);
320 0 : break;
321 : case EKeywordCreate:
322 15 : MIN_DEBUG ("EKeywordCreate");
323 : /* "create <dllname> <classname>" */
324 15 : mip_get_next_string (mip, &token);
325 15 : mip_get_next_string (mip, &token2);
326 15 : testclass_create (token, token2);
327 9 : break;
328 : case EKeywordClassName:
329 27 : MIN_DEBUG ("EKeywordClassName");
330 : /* "<classname> <functionname> [parameters]" */
331 : /* We need to goto beginning of the line to get the
332 : * classname. */
333 27 : mip->item_skip_and_mark_pos_ = &mip->item_line_section_[0];
334 27 : mip_get_next_string (mip, &token);
335 27 : testclass_call_function (token, mip);
336 27 : break;
337 : case EKeywordDelete:
338 6 : MIN_DEBUG ("EKeywordDelete");
339 : /* "delete <classname>" */
340 6 : mip_get_next_string (mip, &token);
341 6 : testclass_destroy (token);
342 6 : break;
343 : case EKeywordPause:
344 2 : MIN_DEBUG ("EKeywordPause");
345 2 : mip_get_next_string (mip, &token);
346 2 : test_pause (token, mip);
347 2 : break;
348 : case EKeywordPrint:
349 41 : MIN_DEBUG ("EKeywordPrint");
350 : /* "print <text>" */
351 41 : testclass_print (mip);
352 41 : break;
353 : case EKeywordResume:
354 1 : MIN_DEBUG ("EKeywordResume");
355 : /* "resume <testid>" */
356 1 : mip_get_next_string (mip, &token);
357 1 : test_resume (token);
358 1 : break;
359 : case EKeywordCancel:
360 1 : MIN_DEBUG ("EKeywordCancel");
361 : /* "cancel <testid>" */
362 1 : mip_get_next_string (mip, &token);
363 1 : test_cancel (token);
364 1 : break;
365 : case EKeywordRelease:
366 1 : MIN_DEBUG ("EKeywordRelease");
367 : /* "release <eventname>" */
368 1 : mip_get_next_string (mip, &token);
369 1 : event_release (token);
370 1 : break;
371 : case EKeywordRequest:
372 1 : MIN_DEBUG ("EKeywordRequest");
373 : /* "request <eventname> [state]" */
374 1 : mip_get_next_string (mip, &token);
375 1 : mip_get_next_string (mip, &token2);
376 2 : if (token2 != INITPTR && !strcmp (token2, "state"))
377 1 : event_request (token, 1);
378 : else
379 0 : event_request (token, 0);
380 :
381 1 : break;
382 : case EKeywordRun:
383 14 : MIN_DEBUG ("EKeywordRun");
384 : /* "run <modulename> <config> <id> " */
385 14 : mip_get_next_string (mip, &token);
386 14 : mip_get_next_string (mip, &token2);
387 14 : mip_get_next_int (mip, &ival);
388 14 : test_run (token, token2, ival, mip);
389 8 : break;
390 : case EKeywordSet:
391 1 : MIN_DEBUG ("EKeywordSet");
392 : /* "set <eventname> [state]" */
393 1 : mip_get_next_string (mip, &token);
394 1 : mip_get_next_string (mip, &token2);
395 2 : if (token2 != INITPTR && !strcmp (token2, "state"))
396 1 : event_set (token, 1);
397 : else
398 0 : event_set (token, 0);
399 1 : break;
400 : case EKeywordUnset:
401 1 : MIN_DEBUG ("EKeywordUnset");
402 : /* "unset <eventname>" */
403 1 : mip_get_next_string (mip, &token);
404 1 : event_unset (token);
405 1 : break;
406 : case EKeywordWait:
407 1 : MIN_DEBUG ("EKeywordWait");
408 : /* "wait <eventname>" */
409 1 : mip_get_next_string (mip, &token);
410 1 : event_wait (token);
411 1 : break;
412 : case EKeywordAllocate:
413 3 : MIN_DEBUG ("EKeywordAllocate");
414 : /* "allocate phone <slave_name> */
415 3 : mip_get_next_string (mip, &token);
416 3 : mip_get_next_string (mip, &token2);
417 3 : test_allocate_slave (token, token2);
418 3 : break;
419 : case EKeywordFree:
420 3 : MIN_DEBUG ("EKeywordFree");
421 : /* free <slave_name> */
422 3 : mip_get_next_string (mip, &token);
423 3 : test_free_slave (token);
424 3 : break;
425 : case EKeywordRemote:
426 3 : MIN_DEBUG ("EKeywordRemote");
427 : /* remote <slave_name> <command> */
428 3 : mip_get_next_string (mip, &token);
429 3 : test_remote_exe (token, mip);
430 3 : break;
431 : case EKeywordAllowNextResult:
432 2 : MIN_DEBUG ("EKeywordAllowNextResult");
433 : /* allownextresult <result> [result2] ... [resultN] */
434 2 : mip_get_next_int (mip, &ival);
435 2 : testclass_allownextresult (ival, mip);
436 2 : break;
437 : case EKeywordComplete:
438 0 : MIN_DEBUG ("EKeywordComplete");
439 : /* complete <testid> */
440 0 : mip_get_next_string (mip, &token);
441 0 : test_complete (token);
442 0 : break;
443 : case EKeywordCancelIfError:
444 3 : MIN_DEBUG ("EKeywordCancelIfError");
445 : /* canceliferror */
446 3 : test_canceliferror ();
447 3 : break;
448 : case EKeywordTimeout:
449 0 : MIN_DEBUG ("EKeywordTimeout");
450 : /* timeout <interval in ms> */
451 0 : mip_get_next_int (mip, &ival);
452 0 : testclass_test_timeout ((unsigned long)ival);
453 0 : break;
454 : case EKeywordSleep:
455 10 : MIN_DEBUG ("EKeywordSleep");
456 : /* sleep <interval in ms> */
457 10 : mip_get_next_int (mip, &ival);
458 10 : testclass_test_sleep ((unsigned long)ival);
459 10 : break;
460 : case EKeywordVar:
461 5 : MIN_DEBUG ("EKeywordVar");
462 : /* var <name> [value] */
463 5 : mip_get_next_string (mip, &token);
464 5 : mip_get_next_string (mip, &token2);
465 5 : if (token2 != INITPTR) {
466 5 : declare_var (token, ESTrue, token2);
467 : } else {
468 0 : declare_var (token, ESFalse, NULL);
469 : }
470 5 : token = token2 = INITPTR;
471 5 : break;
472 : case EKeywordSendreceive:
473 0 : MIN_DEBUG ("EKeywordSendrecieve");
474 : /* sendreceive <variable>=<value> */
475 0 : mip_get_next_string (mip, &token);
476 0 : p = strchr (token, '=');
477 0 : *p = '\0';
478 0 : p++;
479 0 : sendreceive_slave_send (token, p);
480 0 : break;
481 : case EKeywordExpect:
482 0 : MIN_DEBUG ("EKeywordExpect");
483 : /* expect <variable> */
484 0 : mip_get_next_string (mip, &token);
485 0 : sendreceive_slave_expect (token);
486 0 : token = INITPTR;
487 0 : break;
488 : case EKeywordInterference:
489 27 : test_interference (mip);
490 24 : break;
491 : case EKeywordUnknown:
492 0 : MIN_WARN ("Unknown keyword [INITPTR]");
493 0 : break;
494 : default:
495 0 : mip_get_next_string (mip, &token);
496 0 : MIN_WARN ("Unknown keyword [%s]", token);
497 : break;
498 : }
499 192 : EXIT:
500 : /* Clean-up */
501 192 : if (token != INITPTR) {
502 107 : DELETE (token);
503 107 : token = INITPTR;
504 : }
505 192 : if (token2 != INITPTR) {
506 22 : DELETE (token2);
507 22 : token2 = INITPTR;
508 : }
509 : /* Rewind item parser */
510 192 : mip->item_skip_and_mark_pos_ = parser_pos;
511 : return;
512 : }
513 :
514 : /* ------------------------------------------------------------------------- */
515 : LOCAL int check_run_line (MinItemParser * line, int line_number, char *tc_title)
516 266 : {
517 266 : char *lib_name = NULL;
518 266 : char *cfg_name = NULL;
519 266 : int case_id = -1;
520 266 : int opresult = 0;
521 266 : char *case_title = NULL;
522 266 : TSBool case_title_given = ESFalse;
523 266 : TSChar *f_path = NULL;
524 266 : DLList *module_cases = dl_list_create ();
525 266 : ptr2case get_cases = NULL;
526 266 : ptr2run run_case = NULL;
527 266 : void *dll_handle = NULL;
528 266 : DLListIterator work_case_item = DLListNULLIterator;
529 266 : TestCaseInfo *work_case = INITPTR;
530 :
531 266 : opresult = mip_get_next_string (line, &lib_name);
532 266 : if (opresult != 0) {
533 0 : SCRIPTER_SYNTAX_ERROR ("run",
534 : "test module is not defined");
535 0 : goto EXIT;
536 : }
537 :
538 266 : opresult = mip_get_next_string (line, &cfg_name);
539 266 : if (opresult != 0) {
540 0 : SCRIPTER_SYNTAX_ERROR ("run",
541 : "test case id is not defined");
542 0 : goto EXIT;
543 : }
544 :
545 266 : opresult = mip_get_string (line, "title", &case_title);
546 266 : if (case_title != NULL) {
547 152 : case_title_given = ESTrue;
548 : }
549 266 : if (strstr (lib_name, ".so") == NULL) {
550 266 : f_path = NEW2 (char, strlen (lib_name) + 4);
551 266 : sprintf (f_path, "%s.so", lib_name);
552 : } else {
553 0 : f_path = NEW2 (char, strlen (lib_name) + 1);
554 0 : sprintf (f_path, "%s", lib_name);
555 : }
556 :
557 266 : dll_handle = tl_open_tc (f_path);
558 266 : if (dll_handle == INITPTR) {
559 0 : opresult = -1;
560 0 : SCRIPTER_SYNTAX_ERROR_ARG ("run",
561 : "library not opened", lib_name);
562 0 : goto EXIT;
563 : }
564 :
565 266 : run_case = (ptr2run) dlsym (dll_handle, "tm_run_test_case");
566 266 : if (run_case == NULL) {
567 0 : SCRIPTER_SYNTAX_ERROR_ARG ("run",
568 : "run_case() unresolved", dlerror());
569 0 : opresult = -1;
570 0 : goto EXIT;
571 : }
572 :
573 266 : get_cases = (ptr2case) dlsym (dll_handle, "tm_get_test_cases");
574 266 : if (get_cases == NULL) {
575 0 : SCRIPTER_SYNTAX_ERROR_ARG ("run",
576 : "get_cases() unresolved", dlerror);
577 0 : dlclose (dll_handle);
578 0 : goto EXIT;
579 : }
580 :
581 266 : opresult = get_cases (cfg_name, &module_cases);
582 266 : if ((dl_list_size (module_cases) == 0) || (opresult != 0)) {
583 :
584 0 : SCRIPTER_SYNTAX_ERROR_ARG ("run", "Failed to get test "
585 : "cases from module",
586 : lib_name);
587 0 : dlclose (dll_handle);
588 0 : goto EXIT;
589 : }
590 266 : if (case_title_given == ESFalse) {
591 114 : if ((dl_list_size (module_cases) + 1) >= case_id) {
592 114 : opresult = 0;
593 : } else {
594 0 : SCRIPTER_SYNTAX_ERROR ("run",
595 : "Test case id out of range.");
596 0 : opresult = -1;
597 : }
598 114 : goto EXIT;
599 : }
600 :
601 152 : work_case_item = dl_list_head (module_cases);
602 456 : while (work_case_item != DLListNULLIterator) {
603 304 : work_case = (TestCaseInfo *) dl_list_data (work_case_item);
604 304 : if (strcmp (work_case->name_, case_title) == 0) {
605 : /*case with matching title found */
606 152 : opresult = 0;
607 152 : goto EXIT;
608 : }
609 152 : work_case_item = dl_list_next (work_case_item);
610 152 : if (work_case_item == DLListNULLIterator) {
611 : /* whole list has been searched, case with matching
612 : title was not found */
613 0 : opresult = -1;
614 0 : SCRIPTER_SYNTAX_ERROR ("run",
615 : "case with matching title not"
616 : " found.");
617 0 : goto EXIT;
618 : }
619 : }
620 266 : EXIT:
621 266 : DELETE (f_path);
622 266 : DELETE (lib_name);
623 266 : DELETE (case_title);
624 266 : DELETE (cfg_name);
625 266 : if (dl_list_size (module_cases) != 0) {
626 : /*free memory allocated for test cases */
627 266 : work_case_item = dl_list_head (module_cases);
628 1064 : while (work_case_item != DLListNULLIterator) {
629 532 : work_case =
630 : (TestCaseInfo *) dl_list_data (work_case_item);
631 532 : DELETE (work_case);
632 532 : dl_list_remove_it (work_case_item);
633 532 : work_case_item = dl_list_head (module_cases);
634 : }
635 : }
636 266 : dl_list_free (&module_cases);
637 266 : return opresult;
638 : }
639 :
640 : /*------------------------------------------------------------------------- */
641 : LOCAL int check_pause_line (MinItemParser * line, int line_number,
642 : char *tc_title)
643 76 : {
644 76 : char *string = INITPTR;
645 76 : int result = -1;
646 :
647 76 : result = mip_get_next_string (line, &string);
648 76 : if (result != 0) {
649 0 : SCRIPTER_SYNTAX_ERROR ("pause",
650 : "test id is not defined");
651 0 : return -1;
652 : }
653 76 : DELETE (string);
654 76 : return 0;
655 : }
656 :
657 : /*------------------------------------------------------------------------- */
658 : LOCAL int check_loop_line (MinItemParser * line, int line_number,
659 : char * tc_title)
660 228 : {
661 228 : int param1 = 0;
662 228 : char *opt_msec = NULL;
663 228 : int result = -1;
664 :
665 : /*check value of int after "loop" */
666 228 : result = mip_get_int (line, "", ¶m1);
667 228 : if (result != 0) {
668 0 : SCRIPTER_SYNTAX_ERROR ("loop",
669 : "number of iterations/time is "
670 : "not defined");
671 0 : return (-1);
672 : }
673 :
674 : /* check if the "msec" is stated */
675 228 : result = mip_get_next_string (line, &opt_msec);
676 228 : if (result == 0) {
677 0 : if (strcmp (opt_msec, "msec") == 0) {
678 0 : return 0;
679 : } else {
680 0 : SCRIPTER_SYNTAX_ERROR ("loop",
681 : "wrong keyword in loop "
682 : "statement");
683 0 : return (-1);
684 : }
685 : }
686 228 : return 0;
687 : }
688 :
689 : /*------------------------------------------------------------------------- */
690 : LOCAL int check_allocate_line (MinItemParser * line, int line_number,
691 : DLList * slaves, char * tc_title)
692 88 : {
693 88 : int retval = ENOERR;
694 88 : int result = 0;
695 88 : char *token = INITPTR;
696 88 : DLListIterator it = DLListNULLIterator;
697 :
698 : /* Check syntax: allocate <slave type> <slave name> */
699 88 : result = mip_get_next_string (line, &token);
700 88 : if (result != ENOERR) {
701 0 : SCRIPTER_SYNTAX_ERROR ("allocate",
702 : "slave type is not defined");
703 0 : retval = -1;
704 0 : goto EXIT;
705 : }
706 88 : DELETE (token);
707 88 : result = mip_get_next_string (line, &token);
708 88 : if (result != ENOERR) {
709 0 : SCRIPTER_SYNTAX_ERROR ("allocate",
710 : "slave name is not defined");
711 0 : retval = -1;
712 0 : goto EXIT;
713 : }
714 :
715 : /* Check if slave of this name was already allocated. */
716 88 : it = dl_list_find (dl_list_head (slaves)
717 : , dl_list_tail (slaves)
718 : , look4slave, (const void *)token);
719 88 : if (it != DLListNULLIterator) {
720 0 : SCRIPTER_SYNTAX_ERROR ("allocate",
721 : "slave with selected name "
722 : "already exists");
723 0 : retval = -1;
724 0 : DELETE (token);
725 0 : goto EXIT;
726 : }
727 :
728 : /* If slave not allocated than add it to the allocated slaves list. */
729 88 : dl_list_add (slaves, (void *)token);
730 88 : EXIT:
731 88 : return retval;
732 : }
733 :
734 : /*------------------------------------------------------------------------- */
735 : LOCAL int check_free_line (MinItemParser * line, int line_number,
736 : DLList *slaves, char * tc_title)
737 88 : {
738 88 : int retval = ENOERR;
739 88 : int result = 0;
740 88 : char *token = INITPTR;
741 88 : DLListIterator it = DLListNULLIterator;
742 :
743 : /* Check syntax. */
744 88 : result = mip_get_next_string (line, &token);
745 88 : if (result != ENOERR) {
746 0 : retval = -1;
747 0 : DELETE (token);
748 0 : SCRIPTER_SYNTAX_ERROR ("free",
749 : "slave name is not defined");
750 0 : goto EXIT;
751 : }
752 :
753 : /* Check if slave of this name was already allocated. */
754 88 : it = dl_list_find (dl_list_head (slaves)
755 : , dl_list_tail (slaves)
756 : , look4slave, (const void *)token);
757 88 : if (it == DLListNULLIterator) {
758 0 : retval = -1;
759 0 : DELETE (token);
760 0 : SCRIPTER_SYNTAX_ERROR ("free",
761 : "slave not allocated");
762 0 : goto EXIT;
763 : }
764 88 : DELETE (token);
765 :
766 : /* If slave allocated and this is free command then remove slave */
767 88 : token = (char *)dl_list_data (it);
768 88 : DELETE (token);
769 88 : dl_list_remove_it (it);
770 88 : EXIT:
771 88 : return retval;
772 : }
773 :
774 : /*------------------------------------------------------------------------- */
775 : LOCAL int check_remote_line (MinItemParser * line, DLList * variables,
776 : int line_number, DLList * slaves, char * tc_title)
777 101 : {
778 101 : int retval = ENOERR;
779 101 : int result = 0;
780 101 : char *token = INITPTR;
781 101 : char *arg = NULL;
782 101 : DLListIterator it = DLListNULLIterator;
783 101 : TScripterKeyword command = EKeywordUnknown;
784 :
785 : /* check syntax: remote <slave name> <command> */
786 101 : result = mip_get_next_string (line, &token);
787 101 : if (result != ENOERR) {
788 0 : retval = -1;
789 0 : DELETE (token);
790 0 : SCRIPTER_SYNTAX_ERROR ("remote",
791 : "slave name is not defined");
792 0 : goto EXIT;
793 : }
794 : /* Check if slave of this name was already allocated. */
795 101 : it = dl_list_find (dl_list_head (slaves)
796 : , dl_list_tail (slaves)
797 : , look4slave, (const void *)token);
798 101 : if (it == DLListNULLIterator) {
799 0 : retval = -1;
800 0 : DELETE (token);
801 0 : SCRIPTER_SYNTAX_ERROR ("remote",
802 : "slave not allocated");
803 0 : goto EXIT;
804 : }
805 101 : DELETE (token);
806 :
807 : /* Go back to syntax checking */
808 101 : result = mip_get_next_string (line, &token);
809 101 : if (result != ENOERR) {
810 0 : retval = -1;
811 0 : DELETE (token);
812 0 : SCRIPTER_SYNTAX_ERROR ("remote",
813 : "remote command is not defined");
814 0 : goto EXIT;
815 : }
816 :
817 101 : command = get_keyword (token);
818 101 : switch (command) {
819 : case EKeywordSendreceive:
820 0 : mip_get_next_string (line, &arg);
821 0 : if (strchr (arg, '=') == NULL) {
822 0 : SCRIPTER_SYNTAX_ERROR("remote",
823 : "wrong argument for remote "
824 : "sendreceive (no \"=\")");
825 0 : retval = -1;
826 : } else
827 0 : retval = 0;
828 0 : DELETE (arg);
829 0 : break;
830 : case EKeywordExpect:
831 :
832 38 : mip_get_next_string (line, &arg);
833 38 : it = dl_list_find (dl_list_head (variables)
834 : , dl_list_tail (variables)
835 : , look4slave, (const void *)arg);
836 38 : if (it == DLListNULLIterator) {
837 0 : SCRIPTER_SYNTAX_ERROR ("remote",
838 : "remote expect for unknown var");
839 0 : retval = -1;
840 : } else
841 38 : retval = 0;
842 38 : DELETE (arg);
843 : break;
844 : default:
845 : break;
846 : }
847 101 : DELETE (token);
848 101 : EXIT:
849 101 : return retval;
850 : }
851 :
852 : /*------------------------------------------------------------------------- */
853 : LOCAL int check_allownextresult_line (MinItemParser * line, int line_number,
854 : char * tc_title)
855 76 : {
856 76 : int retval = ENOERR;
857 76 : int tmp = 0;
858 :
859 76 : if (line == INITPTR) {
860 0 : retval = -1;
861 0 : errno = EINVAL;
862 0 : goto EXIT;
863 : }
864 :
865 76 : retval = mip_get_next_int (line, &tmp);
866 :
867 76 : if (retval != ENOERR) {
868 0 : SCRIPTER_SYNTAX_ERROR ("allownextresult",
869 : "result code is not defined");
870 0 : retval = -1;
871 0 : goto EXIT;
872 : }
873 76 : EXIT:
874 76 : return retval;
875 : }
876 :
877 : /*------------------------------------------------------------------------- */
878 : LOCAL int check_complete_line (MinItemParser * line, int line_number,
879 : char * tc_title)
880 0 : {
881 0 : int retval = ENOERR;
882 0 : char *token = INITPTR;
883 :
884 0 : if (line == INITPTR) {
885 0 : retval = -1;
886 0 : errno = EINVAL;
887 0 : goto EXIT;
888 : }
889 :
890 0 : retval = mip_get_next_string (line, &token);
891 :
892 : /* Check syntax */
893 0 : if (retval != ENOERR) {
894 0 : SCRIPTER_SYNTAX_ERROR ("complete",
895 : "testid is not defined");
896 0 : retval = -1;
897 0 : goto EXIT;
898 : }
899 :
900 0 : DELETE (token);
901 0 : EXIT:
902 0 : return retval;
903 : }
904 :
905 : /* ------------------------------------------------------------------------- */
906 : LOCAL int check_timeout_line (MinItemParser * line, int line_number,
907 : char * tc_title)
908 0 : {
909 0 : int retval = ENOERR;
910 0 : int tmp = 0;
911 :
912 0 : if (line == INITPTR) {
913 0 : retval = -1;
914 0 : errno = EINVAL;
915 0 : goto EXIT;
916 : }
917 :
918 0 : retval = mip_get_next_int (line, &tmp);
919 :
920 : /* Check syntax */
921 0 : if (retval != ENOERR) {
922 0 : SCRIPTER_SYNTAX_ERROR ("timeout",
923 : "timeout interval is not defined");
924 0 : retval = -1;
925 0 : goto EXIT;
926 : }
927 0 : if (tmp < 1) {
928 0 : SCRIPTER_SYNTAX_ERROR ("timeout",
929 : "invalid interval value");
930 0 : retval = -1;
931 0 : goto EXIT;
932 : }
933 :
934 0 : EXIT:
935 0 : return retval;
936 : }
937 :
938 : /* ------------------------------------------------------------------------- */
939 : LOCAL int check_interference_line (MinItemParser * line, int line_number,
940 : DLList * interf_objs, char * tc_title)
941 684 : {
942 684 : int retval = ENOERR;
943 684 : char *name = INITPTR;
944 684 : char *command = INITPTR;
945 684 : char *tmp = INITPTR;
946 684 : char *type = INITPTR;
947 684 : int value = 0;
948 684 : int idle_time = 0;
949 684 : int busy_time = 0;
950 684 : DLListIterator work_inter = DLListNULLIterator;
951 :
952 684 : if (line == INITPTR) {
953 0 : retval = -1;
954 0 : errno = EINVAL;
955 0 : goto EXIT;
956 : }
957 : /*first check if sp-stress is available at all
958 : this will be done by checking if execs exist in
959 : /usr/bin */
960 684 : if ((access ("/usr/bin/cpuload", X_OK) != 0) ||
961 : (access ("/usr/bin/memload", X_OK) != 0) ||
962 : (access ("/usr/bin/ioload", X_OK))) {
963 0 : SCRIPTER_SYNTAX_ERROR ("testinterference", "check if sp-stress"
964 : " is installed properly");
965 0 : retval = -1;
966 0 : goto EXIT;
967 : }
968 684 : retval = mip_get_next_string (line, &name);
969 :
970 : /* check syntax */
971 684 : if (retval != ENOERR) {
972 0 : SCRIPTER_SYNTAX_ERROR ("testinterference","name missing");
973 0 : retval = -1;
974 0 : goto EXIT;
975 : }
976 :
977 684 : retval = mip_get_next_string (line, &command);
978 :
979 684 : if (retval != ENOERR) {
980 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
981 : "command not specified");
982 0 : retval = -1;
983 0 : goto EXIT;
984 : }
985 684 : if (strcasecmp (command, "start") == 0) {
986 :
987 342 : retval = mip_get_next_string (line, &type);
988 342 : if (retval != ENOERR) {
989 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
990 : "type not specified");
991 0 : retval = -1;
992 0 : goto EXIT;
993 : }
994 342 : if ((strcmp (type, "cpuload") != 0) &&
995 : (strcmp (type, "memload") != 0) &&
996 : (strcmp (type, "ioload") != 0)) {
997 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
998 : "type not specified correctly");
999 0 : retval = -1;
1000 0 : goto EXIT;
1001 : }
1002 342 : retval = mip_get_next_int (line, &value);
1003 :
1004 342 : if (retval != ENOERR) {
1005 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
1006 : "value not specified");
1007 0 : retval = -1;
1008 0 : goto EXIT;
1009 : }
1010 342 : retval = mip_get_next_int (line, &idle_time);
1011 :
1012 342 : if (retval != ENOERR) {
1013 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
1014 : "idle time not specified");
1015 0 : retval = -1;
1016 0 : goto EXIT;
1017 : }
1018 342 : retval = mip_get_next_int (line, &busy_time);
1019 :
1020 342 : if (retval != ENOERR) {
1021 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
1022 : "busy time not specified");
1023 0 : retval = -1;
1024 0 : goto EXIT;
1025 : }
1026 342 : retval = ENOERR;
1027 :
1028 342 : tmp = NEW2 (char, strlen (name) + 1);
1029 342 : sprintf (tmp, "%s", name);
1030 342 : dl_list_add (interf_objs, (void *)tmp);
1031 342 : } else if (strcasecmp (command, "stop") == 0) {
1032 342 : if (interf_objs == INITPTR) {
1033 0 : retval = -1;
1034 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
1035 : "mo interferences started at "
1036 : "this point");
1037 0 : goto EXIT;
1038 : }
1039 :
1040 342 : work_inter = dl_list_head (interf_objs);
1041 684 : while (work_inter != DLListNULLIterator) {
1042 342 : tmp = (char *)dl_list_data (work_inter);
1043 342 : if (strcmp (tmp, name) == 0)
1044 342 : break;
1045 0 : work_inter = dl_list_next (work_inter);
1046 : }
1047 342 : if (work_inter == DLListNULLIterator) {
1048 0 : retval = -1;
1049 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
1050 : "no such interference started "
1051 : "at this point");
1052 0 : goto EXIT;
1053 : } else {
1054 342 : tmp = (char *)dl_list_data (work_inter);
1055 342 : DELETE (tmp);
1056 342 : dl_list_remove_it (work_inter);
1057 :
1058 : }
1059 342 : retval = ENOERR;
1060 342 : goto EXIT;
1061 : } else {
1062 0 : retval = -1;
1063 0 : SCRIPTER_SYNTAX_ERROR ("testinterference",
1064 : "wrong command name");
1065 0 : goto EXIT;
1066 : }
1067 :
1068 :
1069 684 : EXIT:
1070 684 : if (name != INITPTR)
1071 684 : DELETE (name);
1072 684 : if (command != INITPTR)
1073 684 : DELETE (command);
1074 684 : if (type != INITPTR)
1075 342 : DELETE (type);
1076 684 : return retval;
1077 : }
1078 :
1079 : /* ------------------------------------------------------------------------- */
1080 : LOCAL int check_sleep_line (MinItemParser * line, int line_number,
1081 : char * tc_title)
1082 291 : {
1083 291 : int retval = ENOERR;
1084 291 : int tmp = 0;
1085 :
1086 291 : if (line == INITPTR) {
1087 0 : retval = -1;
1088 0 : errno = EINVAL;
1089 0 : goto EXIT;
1090 : }
1091 :
1092 291 : retval = mip_get_next_int (line, &tmp);
1093 :
1094 : /* check syntax */
1095 291 : if (retval != ENOERR) {
1096 0 : SCRIPTER_SYNTAX_ERROR ("sleep",
1097 : "sleep interval is not defined");
1098 0 : retval = -1;
1099 0 : goto EXIT;
1100 : }
1101 291 : if (tmp < 1) {
1102 0 : SCRIPTER_SYNTAX_ERROR ("sleep",
1103 : "invalid interval value");
1104 0 : retval = -1;
1105 0 : goto EXIT;
1106 : }
1107 291 : EXIT:
1108 291 : return retval;
1109 : }
1110 :
1111 : /* ------------------------------------------------------------------------- */
1112 : LOCAL int check_if_line (MinItemParser * line, int line_number, char * tc_title)
1113 152 : {
1114 : int retval;
1115 152 : char *token = INITPTR;
1116 :
1117 152 : if (line == INITPTR) {
1118 0 : retval = -1;
1119 0 : errno = EINVAL;
1120 0 : goto EXIT;
1121 : }
1122 :
1123 152 : retval = mip_get_next_string (line, &token);
1124 152 : if (retval != ENOERR) {
1125 0 : SCRIPTER_SYNTAX_ERROR ("if",
1126 : "no if condition specified");
1127 : }
1128 152 : DELETE (token);
1129 :
1130 152 : EXIT:
1131 152 : return retval;
1132 : }
1133 :
1134 : /* ------------------------------------------------------------------------- */
1135 : /* ======================== FUNCTIONS ====================================== */
1136 : /* ------------------------------------------------------------------------- */
1137 : TSBool validate_define (MinSectionParser * define)
1138 0 : {
1139 0 : TSBool retval = ESTrue;
1140 0 : MinItemParser *line = INITPTR;
1141 0 : char *str1 = INITPTR;
1142 0 : char *str2 = INITPTR;
1143 0 : int pom = 0;
1144 0 : unsigned int line_number = 1;
1145 0 : char *tc_title = "Define Section";
1146 0 : if (define == INITPTR) {
1147 0 : retval = ESFalse;
1148 0 : goto EXIT;
1149 : }
1150 :
1151 0 : line = mmp_get_item_line (define, "", ESNoTag);
1152 :
1153 0 : while (line != INITPTR) {
1154 :
1155 0 : mip_set_parsing_type (line, EQuoteStyleParsing);
1156 :
1157 : /* Correct line in define section consist of two strings
1158 : * that are separated by space */
1159 0 : pom = mip_get_string (line, "", &str1);
1160 0 : if (pom != ENOERR) {
1161 0 : SCRIPTER_SYNTAX_ERROR ("define section",
1162 : "identifier was expected");
1163 0 : retval = ESFalse;
1164 0 : mip_destroy (&line);
1165 0 : goto EXIT;
1166 : }
1167 :
1168 0 : pom = mip_get_next_string (line, &str2);
1169 0 : if (pom == ENOERR) {
1170 0 : struct define *def = NEW (struct define);
1171 0 : memset (def, '\0', sizeof (struct define));
1172 0 : STRCPY (def->label_, str1, strlen (str1) + 1);
1173 0 : STRCPY (def->value_, str2, strlen (str2) + 1);
1174 0 : dl_list_add (defines, (void *)def);
1175 0 : DELETE (str1);
1176 0 : DELETE (str2);
1177 : } else {
1178 0 : SCRIPTER_SYNTAX_ERROR ("define section ",
1179 : "definition value was expected");
1180 0 : retval = ESFalse;
1181 0 : mip_destroy (&line);
1182 0 : goto EXIT;
1183 : }
1184 :
1185 0 : pom = mip_get_next_string (line, &str1);
1186 0 : if (pom == ENOERR) {
1187 0 : DELETE (str1);
1188 0 : MIN_ERROR ("Syntax warning on line %d of Define section"
1189 : " unexpected literal", line_number);
1190 : }
1191 :
1192 0 : mip_destroy (&line);
1193 0 : line = mmp_get_next_item_line (define);
1194 0 : line_number ++;
1195 : }
1196 :
1197 0 : EXIT:
1198 0 : return retval;
1199 : }
1200 :
1201 : /* ------------------------------------------------------------------------- */
1202 : char *validate_test_case (MinSectionParser * testcase)
1203 962 : {
1204 962 : MinItemParser *line = INITPTR;
1205 962 : char *token = INITPTR;
1206 962 : int line_number = -1; // Line number in test case
1207 :
1208 962 : TestClassDetails *test_class = INITPTR;
1209 : /*association lists, assoc_cnames holds class names defined
1210 : in script, assoc_lnames holds library namse in corresponding
1211 : positions */
1212 962 : DLList *assoc_cnames = dl_list_create ();
1213 962 : DLList *assoc_lnames = dl_list_create ();
1214 962 : int loopcounter = 0;
1215 962 : int check_result = -1;
1216 : int lib_already_found;
1217 962 : char *ass_lname = NULL;
1218 962 : char *ass_evname = NULL;
1219 962 : char *ass_cname = NULL;
1220 962 : char *libname = NULL;
1221 962 : char *classname = NULL;
1222 962 : char *callname = NULL;
1223 962 : char *symb_callname = NULL;
1224 962 : char *libpath = NULL;
1225 962 : char *varname = NULL;
1226 962 : char *ass_varname = NULL;
1227 : ScripterDataItem *library;
1228 962 : DLListIterator library_item = DLListNULLIterator;
1229 962 : DLListIterator var_item = DLListNULLIterator;
1230 962 : DLList *symblist = dl_list_create ();
1231 962 : DLList *var_list = dl_list_create (); /*holds "variable"
1232 : names, for validating
1233 : var and expect
1234 : keywords */
1235 962 : DLList *class_methods = INITPTR;
1236 962 : DLListIterator call_item = INITPTR;
1237 962 : DLListIterator tc_item = INITPTR;
1238 : DLList *slaves;
1239 962 : DLList *interf_objs = INITPTR;
1240 : TestCaseInfo *tc;
1241 962 : char *tc_title = NULL;
1242 962 : DLList *testclasses = dl_list_create ();
1243 962 : void *dll_handle = NULL;
1244 962 : unsigned int len = 0;
1245 : /* this will hold names of requested events,
1246 : * to validate "wait" statements */
1247 962 : DLList *requested_events = dl_list_create ();
1248 : enum nesting_type {
1249 : IF = 1,
1250 : LOOP
1251 : };
1252 962 : int nest_level = 0;
1253 : char nesting [255];
1254 : TSBool in_loop;
1255 962 : int errors = 0;
1256 :
1257 : /* allocate place for allocated slaves. */
1258 962 : slaves = dl_list_create ();
1259 962 : line = mmp_get_item_line (testcase, "", ESNoTag);
1260 : //mmp_get_line(testcase,"",&line,ESNoTag);
1261 7292 : while (line != INITPTR) {
1262 5368 : line_number++; // increment line number
1263 5368 : line->parsing_type_ = EQuoteStyleParsing;
1264 :
1265 5368 : if (token != INITPTR)
1266 4406 : DELETE (token);
1267 5368 : mip_get_string (line, "", &token);
1268 5368 : switch (get_keyword (token)) {
1269 : case EKeywordSet:
1270 : case EKeywordUnset:
1271 : case EKeywordSkipIt:
1272 : /* currently this handles set and unset lines
1273 : since we are not really able to validate them */
1274 76 : mip_destroy (&line);
1275 76 : line = mmp_get_next_item_line (testcase);
1276 76 : continue;
1277 : break;
1278 : case EKeywordTitle:
1279 962 : len = strlen (line->item_skip_and_mark_pos_);
1280 962 : if (len == 0) {
1281 0 : SCRIPTER_SYNTAX_ERROR ("title",
1282 : "Test case "
1283 : "title is not defined");
1284 0 : errors ++;
1285 0 : goto EXIT_VALIDATE;
1286 : }
1287 962 : tc_title = NEW2 (char, len + 1);
1288 962 : STRCPY (tc_title, line->item_skip_and_mark_pos_,
1289 : len + 1);
1290 962 : mip_destroy (&line);
1291 962 : line = mmp_get_next_item_line (testcase);
1292 962 : continue;
1293 : break;
1294 : case EKeywordCreate:
1295 : /*class and dll names are writen to assoc_ lists */
1296 304 : if (mip_get_next_string (line, &libname) != 0) {
1297 0 : SCRIPTER_SYNTAX_ERROR ("createx",
1298 : "library name "
1299 : "is not defined");
1300 0 : errors ++;
1301 0 : goto EXIT_VALIDATE;
1302 : }
1303 :
1304 304 : ass_lname = NEW2 (char, strlen (libname) + 1);
1305 304 : sprintf (ass_lname, "%s", libname);
1306 304 : DELETE (libname);
1307 304 : dl_list_add (assoc_lnames, (void *)ass_lname);
1308 304 : if (mip_get_next_string (line, &classname) != 0) {
1309 0 : SCRIPTER_SYNTAX_ERROR ("createx",
1310 : "class name is"
1311 : " not defined");
1312 0 : errors ++;
1313 0 : goto EXIT_VALIDATE;
1314 : }
1315 304 : ass_cname = NEW2 (char, strlen (classname) + 1);
1316 304 : sprintf (ass_cname, "%s", classname);
1317 304 : dl_list_add (assoc_cnames, (void *)ass_cname);
1318 304 : DELETE (classname);
1319 304 : lib_already_found = 0;
1320 304 : library_item = dl_list_head (symblist);
1321 608 : while (library_item != DLListNULLIterator) {
1322 76 : library = (ScripterDataItem *)
1323 : dl_list_data (library_item);
1324 76 : if (strcmp (library->DLL_name_, ass_lname) ==
1325 : 0) {
1326 76 : lib_already_found = 1;
1327 76 : break;
1328 : }
1329 0 : library_item = dl_list_next (library_item);
1330 : }
1331 304 : if (lib_already_found == 0) {
1332 228 : library =
1333 : scripter_dsa_create (ass_lname, ass_cname,
1334 : EDLLTypeClass);
1335 228 : scripter_dsa_add (symblist, library);
1336 : }
1337 304 : mip_destroy (&line);
1338 304 : line = mmp_get_next_item_line (testcase);
1339 304 : continue;
1340 : break;
1341 : case EKeywordDelete:
1342 266 : if ( mip_get_next_string(line,&classname) != 0 ){
1343 0 : SCRIPTER_SYNTAX_ERROR ("delete", "no classname"
1344 : "to delete specified");
1345 0 : errors ++;
1346 0 : goto EXIT_VALIDATE;
1347 : }
1348 266 : check_result = -1; /*indicate if class was
1349 : created before */
1350 266 : for (loopcounter = 0;
1351 646 : loopcounter < dl_list_size (assoc_cnames);
1352 114 : loopcounter++) {
1353 380 : ass_cname =
1354 : (char *)
1355 : dl_list_data (dl_list_at
1356 : (assoc_cnames,
1357 : loopcounter));
1358 380 : if (strcmp (ass_cname, classname) == 0) {
1359 266 : check_result = 0;
1360 266 : break;
1361 : }
1362 : }
1363 266 : if (check_result !=0 ){
1364 0 : SCRIPTER_SYNTAX_ERROR ("delete",
1365 : "classname not created");
1366 0 : errors ++;
1367 0 : DELETE (classname);
1368 0 : goto EXIT_VALIDATE;
1369 : }
1370 : /*ok, test class was created previously, remove
1371 : information from assoc. lists */
1372 266 : DELETE (ass_cname);
1373 266 : DELETE (classname);
1374 266 : dl_list_remove_it (dl_list_at
1375 : (assoc_cnames, loopcounter));
1376 266 : ass_lname =
1377 : (char *)
1378 : dl_list_data ((dl_list_at
1379 : (assoc_lnames, loopcounter)));
1380 266 : DELETE (ass_lname);
1381 266 : dl_list_remove_it (dl_list_at
1382 : (assoc_lnames, loopcounter));
1383 : /*this way, by the end of validation, assoc_cnames &
1384 : assoc_lnames lists should be empty.
1385 : If they are not, validation fails */
1386 266 : mip_destroy (&line);
1387 266 : line = mmp_get_next_item_line (testcase);
1388 266 : continue;
1389 : break;
1390 : case EKeywordPause:
1391 76 : check_result = check_pause_line (line, line_number,
1392 : tc_title);
1393 76 : if (check_result != 0) {
1394 0 : errors ++;
1395 0 : goto EXIT_VALIDATE;
1396 : }
1397 76 : mip_destroy (&line);
1398 76 : line = mmp_get_next_item_line (testcase);
1399 76 : continue;
1400 : break;
1401 : case EKeywordLoop:
1402 228 : check_result = check_loop_line (line, line_number,
1403 : tc_title);
1404 228 : if (check_result == 0) {
1405 228 : nest_level++;
1406 228 : nesting [nest_level] = LOOP;
1407 : } else {
1408 0 : errors ++;
1409 0 : goto EXIT_VALIDATE;
1410 : }
1411 228 : mip_destroy (&line);
1412 228 : line = mmp_get_next_item_line (testcase);
1413 228 : continue;
1414 : break;
1415 : case EKeywordEndloop:
1416 228 : if (nest_level <= 0 || nesting [nest_level] != LOOP) {
1417 0 : SCRIPTER_SYNTAX_ERROR ("endloop","unexpected");
1418 0 : errors ++;
1419 0 : goto EXIT_VALIDATE;
1420 : }
1421 228 : nest_level--;
1422 228 : mip_destroy (&line);
1423 228 : line = mmp_get_next_item_line (testcase);
1424 228 : continue;
1425 : break;
1426 : case EKeywordBreakloop:
1427 38 : loopcounter = nest_level;
1428 38 : in_loop = ESFalse;
1429 114 : while (loopcounter > 0) {
1430 76 : if (nesting [loopcounter] == LOOP) {
1431 38 : in_loop = ESTrue;
1432 38 : break;
1433 : }
1434 38 : loopcounter --;
1435 : }
1436 38 : if (in_loop == ESFalse) {
1437 0 : SCRIPTER_SYNTAX_ERROR ("breakloop",
1438 : "no loop to break");
1439 0 : errors ++;
1440 0 : goto EXIT_VALIDATE;
1441 : }
1442 38 : mip_destroy (&line);
1443 38 : line = mmp_get_next_item_line (testcase);
1444 38 : continue;
1445 : break;
1446 : case EKeywordRequest:
1447 38 : check_result = mip_get_next_string (line, &callname);
1448 38 : if (check_result != 0) {
1449 0 : SCRIPTER_SYNTAX_ERROR ("request",
1450 : "event name is not "
1451 : "defined");
1452 0 : errors ++;
1453 0 : goto EXIT_VALIDATE;
1454 : }
1455 :
1456 38 : ass_evname = NEW2 (char, strlen (callname) + 1);
1457 38 : sprintf (ass_evname, "%s", callname);
1458 38 : dl_list_add (requested_events, (void *)ass_evname);
1459 38 : mip_destroy (&line);
1460 38 : line = mmp_get_next_item_line (testcase);
1461 38 : continue;
1462 : break;
1463 : case EKeywordRelease:
1464 38 : check_result = mip_get_next_string (line, &callname);
1465 38 : if (check_result != 0) {
1466 0 : SCRIPTER_SYNTAX_ERROR ("release",
1467 : "event name is not "
1468 : "defined");
1469 0 : errors++;
1470 0 : DELETE (callname);
1471 0 : goto EXIT_VALIDATE;
1472 : }
1473 38 : DELETE (callname);
1474 38 : mip_destroy (&line);
1475 38 : line = mmp_get_next_item_line (testcase);
1476 38 : continue;
1477 : break;
1478 : case EKeywordWait:
1479 38 : check_result = mip_get_next_string (line, &callname);
1480 38 : if (check_result != 0) {
1481 0 : SCRIPTER_SYNTAX_ERROR ("wait",
1482 : "event name is "
1483 : "not defined");
1484 0 : errors ++;
1485 0 : goto EXIT_VALIDATE;
1486 : }
1487 :
1488 38 : call_item = dl_list_head (requested_events);
1489 38 : if (call_item == DLListNULLIterator) {
1490 0 : SCRIPTER_SYNTAX_ERROR ("wait",
1491 : "eait for not "
1492 : "requested event");
1493 0 : errors ++;
1494 0 : goto EXIT_VALIDATE;
1495 : }
1496 76 : while (call_item != DLListNULLIterator) {
1497 38 : ass_evname = (char *)dl_list_data (call_item);
1498 38 : if (strcmp (ass_evname, callname) == 0) {
1499 38 : break;
1500 : }
1501 0 : call_item = dl_list_next (call_item);
1502 0 : if (call_item == DLListNULLIterator) {
1503 0 : SCRIPTER_SYNTAX_ERROR ("wait",
1504 : "wait for not "
1505 : "requested event"
1506 : );
1507 0 : errors ++;
1508 0 : goto EXIT_VALIDATE;
1509 :
1510 : }
1511 :
1512 : }
1513 38 : mip_destroy (&line);
1514 38 : line = mmp_get_next_item_line (testcase);
1515 38 : continue;
1516 : break;
1517 : case EKeywordClassName:
1518 418 : ass_lname = NULL;
1519 418 : for (loopcounter = 0;
1520 950 : loopcounter < dl_list_size (assoc_cnames);
1521 114 : loopcounter++) {
1522 532 : ass_cname = (char *)
1523 : dl_list_data (dl_list_at
1524 : (assoc_cnames,
1525 : loopcounter));
1526 532 : if (strcmp (ass_cname, token) == 0) {
1527 418 : ass_lname = (char *)
1528 : dl_list_data (dl_list_at
1529 : (assoc_lnames,
1530 : loopcounter));
1531 418 : break;
1532 : }
1533 : }
1534 :
1535 418 : if (ass_lname == NULL) {
1536 0 : SCRIPTER_SYNTAX_ERROR ("<method call>",
1537 : "call for method of "
1538 : "non existing class");
1539 0 : errors ++;
1540 0 : goto EXIT_VALIDATE;
1541 : };
1542 :
1543 418 : mip_get_next_string (line, &callname);
1544 418 : if (callname == NULL) {
1545 0 : SCRIPTER_SYNTAX_ERROR ("<method call>",
1546 : "method name is not"
1547 : " defined");
1548 0 : errors ++;
1549 0 : goto EXIT_VALIDATE;
1550 : }
1551 418 : symb_callname = NEW2 (char, strlen (callname) + 1);
1552 418 : STRCPY (symb_callname, callname,
1553 : strlen (callname) + 1);
1554 418 : DELETE (callname);
1555 418 : library_item = dl_list_head (symblist);
1556 :
1557 418 : lib_already_found = 0;
1558 836 : while (library_item != DLListNULLIterator) {
1559 418 : library = (ScripterDataItem *)
1560 : dl_list_data (library_item);
1561 418 : if (strcmp (ass_lname, library->DLL_name_) ==
1562 : 0) {
1563 418 : lib_already_found = 1;
1564 418 : scripter_dsa_add_symbol (library_item,
1565 : symb_callname);
1566 418 : break;
1567 : }
1568 0 : library_item = dl_list_next (library_item);
1569 : }
1570 418 : if (lib_already_found == 0) {
1571 0 : SCRIPTER_SYNTAX_ERROR ("<method call>",
1572 : "Selected library "
1573 : "was not found");
1574 0 : errors ++;
1575 0 : goto EXIT_VALIDATE;
1576 : }
1577 418 : mip_destroy (&line);
1578 418 : line = mmp_get_next_item_line (testcase);
1579 418 : break;
1580 : case EKeywordRun:
1581 266 : check_result = check_run_line (line, line_number,
1582 : tc_title);
1583 266 : mip_destroy (&line);
1584 :
1585 266 : if (check_result != 0) {
1586 0 : errors ++;
1587 0 : goto EXIT_VALIDATE;
1588 : }
1589 :
1590 266 : line = mmp_get_next_item_line (testcase);
1591 266 : continue;
1592 : break;
1593 : case EKeywordPrint:
1594 : /*we don't care about it at this point */
1595 456 : mip_destroy (&line);
1596 456 : line = mmp_get_next_item_line (testcase);
1597 456 : continue;
1598 : break;
1599 : case EKeywordResume:
1600 : /*we don't care about it at this point */
1601 38 : mip_destroy (&line);
1602 38 : line = mmp_get_next_item_line (testcase);
1603 38 : continue;
1604 : break;
1605 : case EKeywordCancel:
1606 : /*we don't care about it at this point */
1607 38 : mip_destroy (&line);
1608 38 : line = mmp_get_next_item_line (testcase);
1609 38 : continue;
1610 : break;
1611 : case EKeywordAllocate:
1612 88 : check_result =
1613 : check_allocate_line (line, line_number, slaves,
1614 : tc_title);
1615 88 : mip_destroy (&line);
1616 :
1617 88 : if (check_result != ENOERR) {
1618 0 : errors ++;
1619 0 : goto EXIT_VALIDATE;
1620 : }
1621 :
1622 88 : line = mmp_get_next_item_line (testcase);
1623 88 : continue;
1624 : break;
1625 : case EKeywordFree:
1626 88 : check_result = check_free_line (line, line_number,
1627 : slaves, tc_title);
1628 88 : mip_destroy (&line);
1629 :
1630 88 : if (check_result != ENOERR) {
1631 0 : errors ++;
1632 0 : goto EXIT_VALIDATE;
1633 : }
1634 :
1635 88 : line = mmp_get_next_item_line (testcase);
1636 88 : continue;
1637 : break;
1638 : case EKeywordRemote:
1639 :
1640 101 : check_result =
1641 : check_remote_line (line, var_list, line_number,
1642 : slaves, tc_title);
1643 101 : mip_destroy (&line);
1644 :
1645 101 : if (check_result != ENOERR) {
1646 0 : errors ++;
1647 0 : goto EXIT_VALIDATE;
1648 : }
1649 :
1650 101 : line = mmp_get_next_item_line (testcase);
1651 101 : continue;
1652 : break;
1653 : case EKeywordAllowNextResult:
1654 76 : check_result =
1655 : check_allownextresult_line (line, line_number,
1656 : tc_title);
1657 76 : mip_destroy (&line);
1658 76 : if (check_result != ENOERR) {
1659 0 : errors ++;
1660 0 : goto EXIT_VALIDATE;
1661 : }
1662 :
1663 76 : line = mmp_get_next_item_line (testcase);
1664 76 : continue;
1665 : break;
1666 : case EKeywordComplete:
1667 0 : check_result =
1668 : check_complete_line (line, line_number,
1669 : tc_title);
1670 0 : mip_destroy (&line);
1671 :
1672 0 : if (check_result != ENOERR) {
1673 0 : errors ++;
1674 0 : goto EXIT_VALIDATE;
1675 : }
1676 :
1677 0 : line = mmp_get_next_item_line (testcase);
1678 0 : continue;
1679 : break;
1680 : case EKeywordCancelIfError:
1681 38 : mip_destroy (&line);
1682 :
1683 : /* No need to check because canceliferror keyword
1684 : * does not have any parameters. */
1685 38 : line = mmp_get_next_item_line (testcase);
1686 38 : continue;
1687 : break;
1688 : case EKeywordTimeout:
1689 0 : check_result = check_timeout_line (line, line_number,
1690 : tc_title);
1691 0 : mip_destroy (&line);
1692 :
1693 0 : if (check_result != ENOERR) {
1694 0 : errors ++;
1695 0 : goto EXIT_VALIDATE;
1696 : }
1697 :
1698 0 : line = mmp_get_next_item_line (testcase);
1699 0 : continue;
1700 : break;
1701 : case EKeywordSleep:
1702 291 : check_result = check_sleep_line (line, line_number,
1703 : tc_title);
1704 291 : mip_destroy (&line);
1705 :
1706 291 : if (check_result != ENOERR) {
1707 0 : errors ++;
1708 0 : goto EXIT_VALIDATE;
1709 : }
1710 :
1711 291 : line = mmp_get_next_item_line (testcase);
1712 291 : continue;
1713 : break;
1714 : case EKeywordVar:
1715 :
1716 152 : mip_get_next_string (line, &varname);
1717 152 : if ((varname != NULL) || (varname != INITPTR)) {
1718 152 : ass_varname =
1719 : NEW2 (char, strlen (varname) + 1);
1720 152 : sprintf (ass_varname, "%s", varname);
1721 152 : dl_list_add (var_list, (void *)ass_varname);
1722 152 : mip_destroy (&line);
1723 152 : DELETE (varname);
1724 : } else {
1725 0 : SCRIPTER_SYNTAX_ERROR ("var",
1726 : "variable name not "
1727 : "specified");
1728 0 : mip_destroy (&line);
1729 0 : errors ++;
1730 0 : goto EXIT_VALIDATE;
1731 : }
1732 152 : line = mmp_get_next_item_line (testcase);
1733 152 : continue;
1734 : break;
1735 :
1736 : case EKeywordSendreceive:
1737 0 : mip_get_next_string (line, &varname);
1738 0 : if ((varname != NULL) && (varname != INITPTR)) {
1739 0 : if (strchr (varname, '=') == NULL) {
1740 0 : SCRIPTER_SYNTAX_ERROR ("sendrecive",
1741 : "Argument has "
1742 : "faulty syntax "
1743 : "(no '=' "
1744 : "character)");
1745 0 : mip_destroy (&line);
1746 0 : errors ++;
1747 0 : goto EXIT_VALIDATE;
1748 : }
1749 : }
1750 0 : mip_destroy (&line);
1751 0 : line = mmp_get_next_item_line (testcase);
1752 0 : continue;
1753 : break;
1754 : case EKeywordExpect:
1755 :
1756 0 : check_result =
1757 : check_expect_line (line, var_list, line_number,
1758 : tc_title);
1759 0 : mip_destroy (&line);
1760 :
1761 0 : if (check_result != ENOERR) {
1762 0 : errors ++;
1763 0 : goto EXIT_VALIDATE;
1764 : }
1765 0 : line = mmp_get_next_item_line (testcase);
1766 0 : continue;
1767 : break;
1768 : case EKeywordInterference:
1769 684 : if (interf_objs == INITPTR) {
1770 114 : interf_objs = dl_list_create ();
1771 : }
1772 684 : check_result =
1773 : check_interference_line (line, line_number,
1774 : interf_objs,
1775 : tc_title);
1776 684 : if (check_result != ENOERR) {
1777 0 : MIN_ERROR ("Test Interference Fault");
1778 0 : errors ++;
1779 0 : goto EXIT_VALIDATE;
1780 : }
1781 684 : line = mmp_get_next_item_line (testcase);
1782 684 : continue;
1783 : break;
1784 : case EKeywordIf:
1785 152 : check_result = check_if_line (line, line_number,
1786 : tc_title);
1787 152 : if (check_result != ENOERR) {
1788 0 : MIN_ERROR ("Syntax error in line %d. "
1789 : "Invalid if statement",
1790 : line_number);
1791 0 : errors ++;
1792 0 : goto EXIT_VALIDATE;
1793 : }
1794 152 : nest_level++;
1795 152 : nesting [nest_level] = IF;
1796 152 : mip_destroy (&line);
1797 152 : line = mmp_get_next_item_line (testcase);
1798 152 : continue;
1799 : break;
1800 : case EKeywordElse:
1801 38 : if (nesting [nest_level] != IF) {
1802 0 : SCRIPTER_SYNTAX_ERROR ("else",
1803 : "unexpected else");
1804 0 : errors ++;
1805 0 : goto EXIT_VALIDATE;
1806 : }
1807 38 : mip_destroy (&line);
1808 38 : line = mmp_get_next_item_line (testcase);
1809 38 : continue;
1810 : break;
1811 : case EKeywordEndif:
1812 152 : if (nest_level <= 0 || nesting [nest_level] != IF) {
1813 0 : SCRIPTER_SYNTAX_ERROR ("endif",
1814 : "unexpected");
1815 0 : errors ++;
1816 0 : goto EXIT_VALIDATE;
1817 : }
1818 152 : nest_level--;
1819 152 : mip_destroy (&line);
1820 152 : line = mmp_get_next_item_line (testcase);
1821 152 : continue;
1822 : break;
1823 : case EKeywordUnknown:
1824 0 : SCRIPTER_SYNTAX_ERROR_ARG ("<unknown>",
1825 : "[%s]", token);
1826 0 : mip_destroy (&line);
1827 0 : line = mmp_get_next_item_line (testcase);
1828 0 : break;
1829 : default:
1830 0 : SCRIPTER_SYNTAX_ERROR_ARG ("<unknown>",
1831 : "[%s]", token);
1832 0 : mip_destroy (&line);
1833 0 : line = mmp_get_next_item_line (testcase);
1834 : continue;
1835 : break;
1836 : }
1837 : }
1838 962 : if (token != INITPTR)
1839 962 : DELETE (token);
1840 :
1841 : /* check if script's loop counter is 0, otherwise fail syntax check */
1842 962 : if (nest_level != 0) {
1843 0 : errors ++;
1844 0 : SCRIPTER_SYNTAX_ERROR (nesting [nest_level] == IF ? "endif"
1845 : : "endloop", "missing");
1846 0 : goto EXIT_VALIDATE;
1847 : }
1848 :
1849 : /*now check if all interference objects have been stopped (this is
1850 : very important!) */
1851 962 : if ((interf_objs != INITPTR)&&(dl_list_size (interf_objs) != 0)) {
1852 0 : MIN_WARN ("Not all test interference instances stopped!");
1853 0 : var_item = dl_list_head (interf_objs);
1854 0 : while (var_item != DLListNULLIterator) {
1855 0 : varname = (char *)dl_list_data (var_item);
1856 0 : DELETE (varname);
1857 0 : dl_list_remove_it (var_item);
1858 0 : var_item = dl_list_head (interf_objs);
1859 : }
1860 0 : errors ++;
1861 0 : goto EXIT_VALIDATE;
1862 : }
1863 : /*ok, finished fetching symbols from script, now let's validate them */
1864 962 : library_item = dl_list_head (symblist);
1865 :
1866 2114 : while (library_item != DLListNULLIterator) {
1867 228 : library = (ScripterDataItem *) dl_list_data (library_item);
1868 :
1869 228 : switch (library->DLL_type_) {
1870 :
1871 : case EDLLTypeClass:
1872 228 : if (strstr (library->DLL_name_, ".so") == NULL) {
1873 228 : libpath =
1874 : NEW2 (char,
1875 : strlen (library->DLL_name_) + 4);
1876 228 : sprintf (libpath, "%s.so",
1877 : library->DLL_name_);
1878 : } else {
1879 0 : libpath =
1880 : NEW2 (char,
1881 : strlen (library->DLL_name_) + 1);
1882 0 : sprintf (libpath, "%s", library->DLL_name_);
1883 : }
1884 228 : dll_handle = tl_open_tc (libpath);
1885 228 : if (dll_handle == INITPTR) {
1886 0 : SCRIPTER_ERROR ("Unable to load "
1887 : "test library",
1888 : libpath);
1889 0 : errors ++;
1890 0 : goto EXIT_VALIDATE;
1891 : }
1892 228 : test_class = NEW (TestClassDetails);
1893 228 : test_class->dllhandle_ = dll_handle;
1894 228 : test_class->classname_ =
1895 : NEW2 (char, strlen (library->Class_name_) + 1);
1896 228 : STRCPY (test_class->classname_,
1897 : library->Class_name_,
1898 : strlen (library->Class_name_) + 1);
1899 228 : test_class->casetc_ =
1900 : (ptr2casetc) dlsym (dll_handle,
1901 : "ts_get_test_cases");
1902 228 : if (test_class->casetc_ == NULL) {
1903 0 : SCRIPTER_ERROR ("tm_get_cases() unresolved "
1904 : "in Test Library",
1905 : dlerror ());
1906 0 : errors ++;
1907 0 : goto EXIT_VALIDATE;
1908 : }
1909 228 : test_class->runtc_ =
1910 : (ptr2runtc) dlsym (dll_handle, "ts_run_method");
1911 228 : if (test_class->runtc_ == NULL) {
1912 0 : SCRIPTER_ERROR ("tm_run_case() unresolved "
1913 : "in Test Library",
1914 : dlerror ());
1915 0 : errors ++;
1916 0 : goto EXIT_VALIDATE;
1917 : }
1918 228 : dl_list_add (testclasses, (void *)test_class);
1919 228 : class_methods = dl_list_create ();
1920 : /*get test case names */
1921 228 : test_class->casetc_ (&class_methods);
1922 228 : if ((class_methods == INITPTR)
1923 : || (dl_list_size (class_methods) == 0)) {
1924 0 : MIN_WARN ("Could not get list of "
1925 : "functions from %s",
1926 : test_class->classname_);
1927 0 : errors ++;
1928 0 : goto EXIT_VALIDATE;
1929 : }
1930 228 : call_item = dl_list_head (library->symbol_list_);
1931 836 : while (call_item != DLListNULLIterator) {
1932 418 : callname = (char *)dl_list_data (call_item);
1933 418 : tc_item = dl_list_head (class_methods);
1934 1710 : while (tc_item != DLListNULLIterator) {
1935 1292 : tc = (TestCaseInfo *)
1936 : dl_list_data (tc_item);
1937 1292 : if (strcmp (callname, tc->name_) == 0)
1938 380 : break;
1939 912 : tc_item = dl_list_next (tc_item);
1940 912 : if (tc_item == DLListNULLIterator) {
1941 38 : SCRIPTER_ERROR
1942 : ("Symbol not found "
1943 : "in class",
1944 : callname);
1945 38 : dlclose (dll_handle);
1946 38 : errors ++;
1947 38 : goto EXIT_VALIDATE;
1948 : }
1949 :
1950 : }
1951 380 : call_item = dl_list_next (call_item);
1952 : }
1953 :
1954 : case EDLLTypeNormal:
1955 : {
1956 : break;
1957 : }
1958 :
1959 : }
1960 190 : library_item = dl_list_next (library_item);
1961 : }
1962 : /*free all allocated memory */
1963 962 : EXIT_VALIDATE:
1964 :
1965 962 : call_item = dl_list_head (slaves);
1966 1924 : while (call_item != DLListNULLIterator) {
1967 0 : callname = (char *)dl_list_data (call_item);
1968 0 : DELETE (callname);
1969 0 : dl_list_remove_it (call_item);
1970 0 : call_item = dl_list_head (slaves);
1971 : }
1972 :
1973 962 : call_item = dl_list_head (testclasses);
1974 2152 : while (call_item != DLListNULLIterator) {
1975 228 : test_class = dl_list_data (call_item);
1976 228 : DELETE (test_class->classname_);
1977 228 : DELETE (test_class);
1978 228 : call_item = dl_list_next (call_item);
1979 : }
1980 962 : dl_list_free (&testclasses);
1981 :
1982 962 : call_item = dl_list_head (class_methods);
1983 3292 : while (call_item != DLListNULLIterator) {
1984 1368 : tc = (TestCaseInfo *) dl_list_data (call_item);
1985 1368 : DELETE (tc);
1986 1368 : call_item = dl_list_next (call_item);
1987 : }
1988 962 : dl_list_free (&class_methods);
1989 :
1990 :
1991 962 : dl_list_free (&slaves);
1992 962 : free (libpath);
1993 962 : call_item = dl_list_head (assoc_cnames);
1994 1962 : while (call_item != DLListNULLIterator) {
1995 38 : callname = (char *)dl_list_data (call_item);
1996 38 : SCRIPTER_ERROR ("Validation error: testclass not "
1997 : "deleted:",
1998 : callname);
1999 38 : free (callname);
2000 38 : dl_list_remove_it (call_item);
2001 38 : call_item = dl_list_head (assoc_cnames);
2002 : }
2003 962 : dl_list_free (&assoc_cnames);
2004 962 : if (dl_list_size (assoc_lnames) != 0) {
2005 : /*list not empty, so not all classes
2006 : were "deleted" */
2007 38 : if (tc_title != INITPTR) {
2008 38 : errors ++;
2009 : }
2010 : }
2011 :
2012 962 : call_item = dl_list_head (requested_events);
2013 1962 : while (call_item != DLListNULLIterator) {
2014 38 : ass_evname = (char *)dl_list_data (call_item);
2015 38 : free (ass_evname);
2016 38 : dl_list_remove_it (call_item);
2017 38 : call_item = dl_list_head (requested_events);
2018 : }
2019 962 : dl_list_free (&requested_events);
2020 :
2021 962 : call_item = dl_list_head (assoc_lnames);
2022 1962 : while (call_item != DLListNULLIterator) {
2023 38 : callname = (char *)dl_list_data (call_item);
2024 38 : free (callname);
2025 38 : dl_list_remove_it (call_item);
2026 38 : call_item = dl_list_head (assoc_lnames);
2027 : }
2028 962 : dl_list_free (&assoc_lnames);
2029 :
2030 962 : library_item = dl_list_head (symblist);
2031 2152 : while (library_item != DLListNULLIterator) {
2032 228 : scripter_dsa_remove (library_item);
2033 228 : library_item = dl_list_head (symblist);
2034 : }
2035 962 : dl_list_free (&symblist);
2036 :
2037 962 : var_item = dl_list_head (var_list);
2038 2076 : while (var_item != DLListNULLIterator) {
2039 152 : varname = (char *)dl_list_data (var_item);
2040 152 : DELETE (varname);
2041 152 : dl_list_remove_it (var_item);
2042 152 : var_item = dl_list_head (var_list);
2043 : }
2044 962 : dl_list_free (&var_list);
2045 :
2046 962 : if (errors) {
2047 76 : DELETE (tc_title);
2048 76 : tc_title = NULL;
2049 : }
2050 :
2051 962 : return tc_title;
2052 : }
2053 :
2054 : /* ------------------------------------------------------------------------- */
2055 : int interpreter_next ()
2056 359 : {
2057 359 : LegoActiveType *active = INITPTR;
2058 359 : LegoPassiveType *passive = INITPTR;
2059 359 : LegoLoopType *loop = INITPTR;
2060 359 : LegoEndloopType *eloop = INITPTR;
2061 359 : LegoIfBlockType *ifblock = INITPTR;
2062 359 : LegoElseBlockType *elseblock = INITPTR;
2063 :
2064 359 : int retval = ENOERR;
2065 : struct timeval t;
2066 : struct timeval now;
2067 359 : DLListIterator it = DLListNULLIterator;
2068 359 : struct define *def = INITPTR;
2069 :
2070 359 : if (current == INITPTR) {
2071 39 : current = mli_get_legosnake ();
2072 : }
2073 359 : if (current == INITPTR) {
2074 0 : retval = -1;
2075 0 : goto EXIT;
2076 : }
2077 :
2078 359 : switch (current->type_) {
2079 : case ELegoStart:
2080 39 : MIN_DEBUG ("ELegoStart - Script Started");
2081 39 : break;
2082 : case ELegoEnd:
2083 24 : MIN_DEBUG ("ELegoEnd - Script Ended");
2084 24 : script_finish ();
2085 24 : break;
2086 : case ELegoPassive:
2087 :
2088 39 : passive = (LegoPassiveType *) current;
2089 39 : interpreter_handle_keyword (passive->keyword_,
2090 : passive->line_);
2091 39 : break;
2092 : case ELegoActive:
2093 168 : active = (LegoActiveType *) current;
2094 :
2095 :
2096 : /* We are going to also replace defines on runtime
2097 : * because of sendrecieve which sets defines during
2098 : * script execution. */
2099 168 : it = dl_list_head (defines);
2100 336 : while (it != DLListNULLIterator) {
2101 0 : def = (struct define *)dl_list_data (it);
2102 0 : mip_replace (active->line_, def->label_, def->value_);
2103 0 : it = dl_list_next (it);
2104 : }
2105 :
2106 : /* now we can interprete it */
2107 168 : interpreter_handle_keyword (active->keyword_, active->line_);
2108 153 : break;
2109 : case ELegoLoop:
2110 37 : loop = (LegoLoopType *) current;
2111 :
2112 37 : if (loop->timeout_ == ESTrue && loop->started_ == ESFalse) {
2113 0 : gettimeofday (&now, NULL);
2114 0 : loop->endtime_.tv_sec = loop->oryginal2_.tv_sec;
2115 0 : loop->endtime_.tv_sec += now.tv_sec;
2116 0 : loop->endtime_.tv_usec = loop->oryginal2_.tv_usec;
2117 0 : loop->endtime_.tv_usec += now.tv_usec;
2118 :
2119 0 : while (loop->endtime_.tv_usec >= 1000000) {
2120 0 : loop->endtime_.tv_sec++;
2121 0 : loop->endtime_.tv_usec -= 1000000;
2122 : }
2123 : }
2124 :
2125 37 : break;
2126 : case ELegoEndloop:
2127 37 : eloop = (LegoEndloopType *) current;
2128 :
2129 : /* Check mode of the loop:
2130 : * - timeout
2131 : * - iteration
2132 : */
2133 37 : if (eloop->beyondloop_ == INITPTR) {
2134 5 : eloop->beyondloop_ = eloop->next_;
2135 5 : eloop->next_ = (LegoBasicType *) eloop->loopback_;
2136 : }
2137 :
2138 37 : if (eloop->timeout_ == ESFalse) {
2139 : /* Check range */
2140 37 : if (eloop->counter_ == 0) {
2141 9 : eloop->next_ =
2142 : (LegoBasicType *) eloop->loopback_;
2143 9 : eloop->counter_++;
2144 28 : } else if (eloop->counter_ <
2145 : ((*eloop->oryginal_) - 1)) {
2146 : /* Increment 'visited' counter */
2147 19 : eloop->counter_++;
2148 : } else {
2149 9 : eloop->next_ =
2150 : (LegoBasicType *) eloop->beyondloop_;
2151 9 : eloop->counter_ = 0;
2152 : }
2153 : } else {
2154 0 : *eloop->started_ = ESTrue;
2155 0 : gettimeofday (&now, NULL);
2156 :
2157 0 : if (substract_timeval (&t, eloop->endtime_, &now) ==
2158 : 1) {
2159 : /* loop last too long */
2160 0 : eloop->next_ =
2161 : (LegoBasicType *) eloop->beyondloop_;
2162 0 : *eloop->started_ = ESFalse;
2163 : } else {
2164 : /* loop still can operate */
2165 0 : eloop->next_ =
2166 : (LegoBasicType *) eloop->loopback_;
2167 : }
2168 : }
2169 :
2170 37 : break;
2171 : case ELegoBreakloop:
2172 : /*
2173 : ** Fast forward to endloop
2174 : */
2175 0 : while (current->type_ != ELegoEndloop)
2176 0 : current = current->next_;
2177 0 : eloop = (LegoEndloopType *) current;
2178 0 : if (eloop->beyondloop_ != INITPTR) {
2179 0 : current->next_ = eloop->beyondloop_;
2180 : }
2181 0 : break;
2182 : case ELegoIfBlock:
2183 13 : ifblock = (LegoIfBlockType *)current;
2184 13 : if (eval_if (ifblock->condition_) == ESFalse) {
2185 12 : elseblock = (LegoElseBlockType *) ifblock->else_;
2186 12 : if (elseblock != INITPTR) {
2187 1 : current = (LegoBasicType *) elseblock;
2188 : } else {
2189 11 : current = (LegoBasicType *) ifblock->block_end_;
2190 : }
2191 : }
2192 13 : break;
2193 : case ELegoElseBlock:
2194 0 : break;
2195 : case ELegoEndifBlock:
2196 2 : break;
2197 : default:
2198 0 : MIN_ERROR ("Unknown Type of Lego Piece [%d]",
2199 : current->type_);
2200 : }
2201 :
2202 : /* Move forward one element */
2203 344 : current = current->next_;
2204 :
2205 344 : EXIT:
2206 344 : return retval;
2207 : }
2208 :
2209 : /* ------------------------------------------------------------------------- */
2210 :
2211 : int scripter_init (minScripterIf * scripter_if)
2212 102 : {
2213 102 : current = INITPTR;
2214 102 : return 0;
2215 : }
2216 :
2217 : /* ------------------------------------------------------------------------- */
2218 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
2219 : /* None */
2220 :
2221 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
2222 : #ifdef MIN_UNIT_TEST
2223 : #include "min_scripter_if.tests"
2224 : #endif /* MIN_UNIT_TEST */
2225 : /* End of file */
|