1 /*----------------------------------------------------------------------------
2 conttoken.cc (control script flow)
3 This file is a part of topaz systems
4 Copyright: Hisao Kawaura, All rights reserved
5 1997 - 98
6
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 ----------------------------------------------------------------------------*/
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <math.h>
27 #include <stdlib.h>
28 #include <string>
29 #include <ctype.h>
30 #include <string.h>
31
32 #include "script.h"
33 #include "system.h"
34 #include "tokenbuff.h"
35 #include "graph.h"
36 #include "buffarray.h"
37 #include "cui.h"
38 #include "browse.h"
39 #include "objectlist.h"
40 #include "pipecall.h"
41 #include "topazvalues.h"
42 #include "convtxt.h"
43
44 extern void message(const char *msg);
45 extern WINDOW *menuwin, *msgwin, *sepwin ,*titlewin;
46 extern bool fileexist(char *file);
47 extern char confpath[1000];
48 extern char tmppath[1000];
49 extern char pid[100];
50 extern bool isabort();
51 extern void resetabort();
52 extern char **envp;
53
54
controltoken()55 int script::controltoken()
56 {
57 int i, itemp, iOparenfound, iCparenfound, iObracefound, iCbracefound, iblocklast, if_or_ifelse_bracestatus = 0\
58 ,commacount, iOcontbracefound, iCcontbracefound, iOUTblockstart;
59 int commaposition[5];
60 std::string conditionvalue;
61 tokenbuff* curtoken;
62 tokenbuff basetoken, commatoken, conditionvariant, setoperand, oparentoken, cparentoken;
63 std::string str1, str2, str3;
64 int length;
65 int tempparenseslevel;
66 int exectokenflag;
67 int lin;
68
69 //initialize
70
71 basetoken.priority = -100;
72 basetoken.status = 0;
73 basetoken.value->add("0");
74 *basetoken.label = std::string("");
75 basetoken.strstatus = 0;
76 basetoken.bracestatus = 0;
77 basetoken.bracenestlevel = 0;
78 basetoken.parentheseslevel = 0;
79 basetoken.jumpindex = 0;
80 basetoken.lineno = 0;
81 basetoken.count = -1;
82
83 stack->push1(&basetoken);
84
85 commatoken.priority = PRI_SEMICOLON;
86 commatoken.status = SEMICOLON;
87
88 conditionvariant.priority = PRI_OPERAND;
89 conditionvariant.status = VARIANT;
90 *conditionvariant.label = std::string("$reserved_by_system_for_evaluation");
91 conditionvariant.value->add("");
92
93 setoperand.priority = PRI_SET;
94 setoperand.status = SET;
95 *setoperand.label = std::string("");
96 setoperand.value->add("");
97
98 oparentoken.priority = PRI_OPAREN;
99 oparentoken.status = OPAREN;
100 *oparentoken.label = std::string("");
101 oparentoken.value->add("");
102 oparentoken.bracenestlevel = BRC_OPENPAREN;
103
104 cparentoken.priority = PRI_CPAREN;
105 cparentoken.status = CPAREN;
106 *cparentoken.label = std::string("");
107 cparentoken.value->add("");
108 cparentoken.bracenestlevel = BRC_CLOSEDPAREN;
109
110
111 resetabort();
112 for (i = 0; i < buff->getarraylength(); i++)
113 {
114 if (isabort())
115 {
116 message("User interruption. Macroscript aborted.\n");
117 return false;
118 }
119
120 curtoken = &(*buff)[i];
121 lin = curtoken->lineno;
122
123 // '}'
124 if (curtoken->status == CPAREN && curtoken->jumpindex != -1)
125 {
126 i = curtoken->jumpindex;
127 curtoken = &(*buff)[i];
128 }
129
130 if (curtoken->status == LAST || curtoken->status == NEXT)
131 {
132 //search start point of out block
133 //last is not in the any blocks
134 if (curtoken->parentheseslevel == 0)
135 return errormessage(lin, "invalid arguments", "next / last");
136
137 //"last" is not a last token
138 if (i < buff->getarraylength() - 1)
139 {
140 // next token is in the while/until or for loop
141 if ((*buff)[i + 1].bracestatus == BRC_WHILE
142 || (*buff)[i + 1].bracestatus == BRC_FOR
143 || (*buff)[i + 1].bracestatus == BRC_FOREACH
144 )
145 {
146 iOUTblockstart = i + 1;
147 }
148 else
149 {
150 iOUTblockstart = -1;
151 tempparenseslevel = curtoken->parentheseslevel;
152 for (itemp = i + 1; itemp < buff->getarraylength(); itemp++)
153 {
154 if ((*buff)[itemp].parentheseslevel <= tempparenseslevel)
155 {
156 if ((*buff)[itemp].bracestatus == BRC_WHILE
157 || (*buff)[itemp].bracestatus == BRC_FOR
158 || (*buff)[itemp].bracestatus == BRC_FOREACH
159 )
160 {
161 iOUTblockstart = itemp;
162 break;
163 }
164 else
165 tempparenseslevel = (*buff)[itemp].parentheseslevel;
166 }
167 }
168 }
169
170 //start point is found
171 if (iOUTblockstart != -1)
172 {
173 iCbracefound = -1;
174 //search the out position
175 for (itemp = iOUTblockstart; itemp < buff->getarraylength(); itemp++)
176 {
177 if ((*buff)[itemp].bracestatus == (*buff)[iOUTblockstart].bracestatus
178 && (*buff)[itemp].status == CPAREN
179 && (*buff)[itemp].parentheseslevel == (*buff)[iOUTblockstart].parentheseslevel
180 )
181 {
182 iCbracefound = itemp;
183 break;
184 }
185 }
186
187 //closed brace found
188 if (iCbracefound != -1)
189 {
190 if (curtoken->status == LAST)
191 {
192
193 //search "continue"
194 //"continue" may exit
195 if((iCbracefound + 2) <= buff->getarraylength() - 1)
196 {
197 //"continue" exist
198 if ((*buff)[iCbracefound + 1].status == CONTINUE
199 && (*buff)[iCbracefound + 2].status == OPAREN
200 && (*buff)[iOUTblockstart].bracestatus == BRC_WHILE
201 )
202 {
203 iOcontbracefound = iCbracefound + 2;
204 //search the position of closed parensis
205 iCcontbracefound = -1;
206 for (itemp = iOcontbracefound; itemp < buff->getarraylength(); itemp++)
207 {
208 if ((*buff)[itemp].status == CPAREN \
209 && (*buff)[itemp].bracestatus == BRC_CONTINUE\
210 && (*buff)[itemp].parentheseslevel == (*buff)[iOcontbracefound].parentheseslevel)
211 {
212 iCcontbracefound = itemp;
213 break;
214 }
215 }
216 //closed brace of continue loop is found
217 if (iCcontbracefound != -1)
218 i = iCcontbracefound;
219 else
220 return errormessage(lin, "cannot find brace close for 'continue'", "next / last");
221 }
222 //"continue" does not exist
223 else
224 i = iCbracefound;
225 }
226 //"continue" cannot exit
227 else
228 i = iCbracefound;
229 }
230 else
231 i = iCbracefound;
232 }
233 else
234 return errormessage(lin, "cannot find brace close", "next / last");
235
236 }
237 else
238 return errormessage(lin, "cannot find brace open", "next / last");
239 }
240 else
241 return errormessage(lin, "last token is not allowed", "next / last");
242 }
243 // if, elseif
244 else if (curtoken->status == IF || curtoken->status == ELSEIF)
245 {
246
247 if (curtoken->status == IF)
248 if_or_ifelse_bracestatus = BRC_IF;
249 else if (curtoken->status == ELSEIF)
250 if_or_ifelse_bracestatus = BRC_ELSEIF;
251
252 //in case of 'elseif'
253 if (curtoken->status == ELSEIF)
254 {
255 if (i <= 0)
256 return errormessage(lin, "invalid position", "elsif");
257 else
258 {
259 // closed parentheses of 'if' must be exist just before 'elseif'
260 if (!((*buff)[i - 1].status == CPAREN \
261 && ((*buff)[i - 1].bracestatus == BRC_IF\
262 || (*buff)[i - 1].bracestatus == BRC_ELSEIF)))
263 return errormessage(lin, "cannot find brace close just before elsif", "elsif");
264 }
265 }
266
267 //check the nextoken to be open parentheses
268 //closed parentheses must be in buffer
269 if((i + 2) > buff->getarraylength() - 1)
270 return errormessage(lin, "cannot find parenthesis open / close", "if / elsif");
271 //open parentheses must be followed by 'if' or 'elseif'
272 if ((*buff)[i + 1].status == OPAREN)
273 {
274 //search the position of closed parensis
275 iCparenfound = -1;
276 for (itemp = i + 2; itemp < buff->getarraylength(); itemp++)
277 {
278 if ((*buff)[itemp].status == CPAREN \
279 && (*buff)[itemp].bracestatus == if_or_ifelse_bracestatus\
280 && (*buff)[itemp].parentheseslevel == (*buff)[i + 1].parentheseslevel)
281 {
282 iCparenfound = itemp;
283 break;
284 }
285 }
286
287 //closed parentheses is found
288 if (iCparenfound != -1)
289 {
290 //expression is executed
291 conditionvariant.lineno = i;
292 exectoken(&conditionvariant);
293 setoperand.lineno = i;
294 exectoken(&setoperand);
295 oparentoken.lineno = i;
296 exectoken(&oparentoken);
297 for (itemp = i + 2; itemp < iCparenfound; itemp++)
298 exectoken(&(*buff)[itemp]);
299 cparentoken.lineno = i;
300 exectoken(&cparentoken);
301 commatoken.lineno = i;
302 exectoken(&commatoken);
303 str3 = std::string("$reserved_by_system_for_evaluation");
304 vbuff->GetScalar(&str3, &conditionvalue);
305
306 //if results true
307 if (atoi(conditionvalue.c_str()) != 0)
308 {
309 //confirm open brace
310 iObracefound = iCparenfound + 1;
311
312 //open brace must exist
313 if (iObracefound > buff->getarraylength() - 2)
314 return errormessage(lin, "cannot find brace open / close", "if / elsif");
315 if ((*buff)[iObracefound].status == OPAREN\
316 && (*buff)[iObracefound].bracestatus == if_or_ifelse_bracestatus)
317 {
318 //search the position of closed brace
319 iCbracefound = -1;
320 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
321 {
322 if ((*buff)[itemp].status == CPAREN \
323 && (*buff)[itemp].bracestatus == if_or_ifelse_bracestatus\
324 && (*buff)[itemp].parentheseslevel\
325 == (*buff)[iObracefound].parentheseslevel)
326 {
327 iCbracefound = itemp;
328 break;
329 }
330 }
331
332 //closed brace exist!!
333 if (iCbracefound != -1)
334 {
335 // goto end of if block
336 iblocklast = -1;
337 for (itemp = iCbracefound; itemp <= buff->getarraylength() - 1; itemp++)
338 {
339 if ((*buff)[itemp].status == CPAREN
340 && ((*buff)[itemp].bracestatus == BRC_IF
341 || (*buff)[itemp].bracestatus == BRC_ELSEIF
342 || (*buff)[itemp].bracestatus == BRC_ELSE)
343 && (*buff)[itemp].parentheseslevel == (*buff)[iCbracefound].parentheseslevel
344 && (*buff)[itemp].bracenestlevel == BRC_CLOSEDBRACE
345 && (
346 (
347 (itemp < buff->getarraylength() - 1)
348 && ((*buff)[itemp + 1].status != ELSEIF
349 && (*buff)[itemp + 1].status != ELSE)
350 )
351 || (itemp == buff->getarraylength() - 1)
352 )
353 )
354
355 {
356 iblocklast = itemp;
357 break;
358 }
359 }
360
361 //last block exist
362 if (iblocklast != -1)
363 {
364 (*buff)[iCbracefound].jumpindex = iblocklast;
365 i = iObracefound;
366 }
367 else
368 return errormessage(lin, "cannot find the end of 'if' block", "if / elsif");
369 }
370 else
371 return errormessage(lin, "cannot find brace close", "if / elsif");
372
373 }
374 else
375 return errormessage(lin, "cannot find brace open", "if / elsif");
376 }
377 //if results false
378 else
379 {
380 //search closed brace of if block
381 iObracefound = iCparenfound + 1;
382 iCbracefound = -1;
383 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
384 {
385 if ((*buff)[itemp].status == CPAREN \
386 && (*buff)[itemp].bracestatus == if_or_ifelse_bracestatus\
387 && (*buff)[itemp].parentheseslevel\
388 == (*buff)[iObracefound].parentheseslevel)
389 {
390 iCbracefound = itemp;
391 break;
392 }
393 }
394
395
396 if (iCbracefound != -1)
397 i = iCbracefound;
398 else
399 return errormessage(lin, "cannot find the end of 'if' block", "if / elsif");
400 }
401 }
402 else
403 return errormessage(lin, "cannot find parenthesis close", "if / elsif");
404 }
405 else
406 return errormessage(lin, "cannot find parenthesis open", "if / elsif");
407 }
408 // else
409 else if (curtoken->status == ELSE)
410 {
411 }
412 else if (curtoken->status == WHILE || curtoken->status == UNTIL)
413 {
414 //check the nextoken to be open parentheses
415 //closed parentheses must be in buffer
416 if((i + 2) > buff->getarraylength() - 1)
417 return errormessage(lin, "cannot find parenthesis close", "while / until");
418 //open parentheses must be followed by 'while'
419 if ((*buff)[i + 1].status == OPAREN)
420 {
421 //search the position of closed parensis
422 iCparenfound = -1;
423 for (itemp = i + 2; itemp < buff->getarraylength(); itemp++)
424 {
425 if ((*buff)[itemp].status == CPAREN \
426 && (*buff)[itemp].bracestatus == BRC_WHILE\
427 && (*buff)[itemp].parentheseslevel == (*buff)[i + 1].parentheseslevel)
428 {
429 iCparenfound = itemp;
430 break;
431 }
432 }
433
434 //closed parentheses is found
435 if (iCparenfound != -1)
436 {
437 //expression is executed
438 conditionvariant.lineno = i;
439 exectoken(&conditionvariant);
440 setoperand.lineno = i;
441 exectoken(&setoperand);
442 oparentoken.lineno = i;
443 exectoken(&oparentoken);
444 for (itemp = i + 2; itemp < iCparenfound; itemp++)
445 exectoken(&(*buff)[itemp]);
446 cparentoken.lineno = i;
447 exectoken(&cparentoken);
448 commatoken.lineno = i;
449 exectoken(&commatoken);
450 str3 = std::string("$reserved_by_system_for_evaluation");
451 vbuff->GetScalar(&str3, &conditionvalue);
452
453 itemp = atoi(conditionvalue.c_str());
454 if (curtoken->status == UNTIL)
455 {
456 if (itemp)
457 itemp = 0;
458 else
459 itemp = 1;
460 }
461
462 //while results true / until results false
463 if (itemp != 0)
464 {
465 //confirm open brace
466 iObracefound = iCparenfound + 1;
467
468 //open brace must exist
469 if (iObracefound > buff->getarraylength() - 2)
470 return errormessage(lin, "cannot find brace open / close", "while / until");
471 if ((*buff)[iObracefound].status == OPAREN\
472 && (*buff)[iObracefound].bracestatus == BRC_WHILE)
473 {
474 //search the position of closed brace
475 iCbracefound = -1;
476 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
477 {
478 if ((*buff)[itemp].status == CPAREN \
479 && (*buff)[itemp].bracestatus == BRC_WHILE\
480 && (*buff)[itemp].parentheseslevel\
481 == (*buff)[iObracefound].parentheseslevel)
482 {
483 iCbracefound = itemp;
484 break;
485 }
486 }
487
488 //closed brace exist!!
489 if (iCbracefound != -1)
490 {
491 //search "continue"
492 //"continue" may exit
493 if((iCbracefound + 2) <= buff->getarraylength() - 1)
494 {
495 //"continue" exist
496 if ((*buff)[iCbracefound + 1].status == CONTINUE
497 && (*buff)[iCbracefound + 2].status == OPAREN)
498 {
499 iOcontbracefound = iCbracefound + 2;
500 //search the position of closed parensis
501 iCcontbracefound = -1;
502 for (itemp = iOcontbracefound; itemp < buff->getarraylength(); itemp++)
503 {
504 if ((*buff)[itemp].status == CPAREN \
505 && (*buff)[itemp].bracestatus == BRC_CONTINUE\
506 && (*buff)[itemp].parentheseslevel == (*buff)[iOcontbracefound].parentheseslevel)
507 {
508 iCcontbracefound = itemp;
509 break;
510 }
511 }
512 //closed brace of continue loop is found
513 if (iCcontbracefound != -1)
514 {
515 (*buff)[iCcontbracefound].jumpindex = i;
516 i = iObracefound;
517 }
518 else
519 return errormessage(lin, "cannot find brace close for 'continue' loop", "while / until");
520 }
521 //"continue" does not exist
522 else
523 {
524 (*buff)[iCbracefound].jumpindex = i;
525 i = iObracefound;
526 }
527 }
528 //"continue" cannot exit
529 else
530 {
531 (*buff)[iCbracefound].jumpindex = i;
532 i = iObracefound;
533 }
534 }
535 else
536 return errormessage(lin, "cannot find brace close", "while / until");
537 }
538 else
539 return errormessage(lin, "cannot find brace open", "while / until");
540 }
541 //while results false / until results true
542 else
543 {
544 //search closed brace of if block
545 iObracefound = iCparenfound + 1;
546 iCbracefound = -1;
547 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
548 {
549 if ((*buff)[itemp].status == CPAREN \
550 && (*buff)[itemp].bracestatus == BRC_WHILE\
551 && (*buff)[itemp].parentheseslevel\
552 == (*buff)[iObracefound].parentheseslevel)
553 {
554 iCbracefound = itemp;
555 break;
556 }
557 }
558
559 //closed brace found
560 if (iCbracefound != -1)
561 {
562 //search "continue"
563 //"continue" may exit
564 if((iCbracefound + 2) <= buff->getarraylength() - 1)
565 {
566 //"continue" exist
567 if ((*buff)[iCbracefound + 1].status == CONTINUE
568 && (*buff)[iCbracefound + 2].status == OPAREN)
569 {
570 iOcontbracefound = iCbracefound + 2;
571 //search the position of closed parensis
572 iCcontbracefound = -1;
573 for (itemp = iOcontbracefound; itemp < buff->getarraylength(); itemp++)
574 {
575 if ((*buff)[itemp].status == CPAREN \
576 && (*buff)[itemp].bracestatus == BRC_CONTINUE\
577 && (*buff)[itemp].parentheseslevel == (*buff)[iOcontbracefound].parentheseslevel)
578 {
579 iCcontbracefound = itemp;
580 break;
581 }
582 }
583
584 //closed brace of continue loop is found
585 if (iCcontbracefound != -1)
586 i = iCcontbracefound;
587 else
588 return errormessage(lin, "cannot find brace close for 'continue' loop", "while / until");
589 }
590 //"continue" does not exist
591 else
592 i = iCbracefound;
593 }
594 //"continue" cannot exit
595 else
596 i = iCbracefound;
597 }
598 else
599 return errormessage(lin, "cannot find brace close", "while / until");
600 }
601 }
602 else
603 return errormessage(lin, "cannot find parenthesis close", "while / until");
604 }
605 else
606 return errormessage(lin, "cannot find parenthesis open", "while / until");
607 }
608 else if (curtoken->status == FOR)
609 {
610 //closed parentheses must be in buffer
611 if((i + 3) > buff->getarraylength() - 1)
612 return errormessage(lin, "cannot find parenthesis close", "for");
613 //nextfor and open parentheses must be followed by 'for'
614 if ((*buff)[i + 1].status == NEXTFOR\
615 && (*buff)[i + 2].status == OPAREN)
616 {
617 iOparenfound = i + 2;
618 //search the position of closed parensis
619 iCparenfound = -1;
620 for (itemp = iOparenfound + 1; itemp < buff->getarraylength(); itemp++)
621 {
622 if ((*buff)[itemp].status == CPAREN \
623 && (*buff)[itemp].bracestatus == BRC_FOR\
624 && ((*buff)[itemp].parentheseslevel == (*buff)[iOparenfound].parentheseslevel))
625 {
626 iCparenfound = itemp;
627 break;
628 }
629 }
630
631 //closed parentheses is found
632 if (iCparenfound != -1)
633 {
634 //condition expression must contain three 'comma's
635 commacount = 0;
636 for (itemp = iOparenfound; itemp < iCparenfound; itemp++)
637 {
638 if ((*buff)[itemp].status == SEMICOLON)
639 commacount++;
640 }
641
642 if (commacount != 2)
643 return errormessage(lin, "invalid 'for' condition", "for");
644
645 //search comma position
646 commacount = 0;
647 for (itemp = iOparenfound; itemp < iCparenfound; itemp++)
648 {
649 if ((*buff)[itemp].status == SEMICOLON)
650 commaposition[commacount++] = itemp;
651 }
652
653 //intialization (ex. i = 1;)
654 for (itemp = iOparenfound + 1; itemp <= commaposition[0]; itemp++)
655 exectoken(&(*buff)[itemp]);
656
657 //condition (ex. i < 100)
658 conditionvariant.lineno = i;
659 exectoken(&conditionvariant);
660 setoperand.lineno = i;
661 exectoken(&setoperand);
662
663 for (itemp = commaposition[0] + 1; itemp <= commaposition[1]; itemp++)
664 exectoken(&(*buff)[itemp]);
665 str3 = std::string("$reserved_by_system_for_evaluation");
666 vbuff->GetScalar(&str3, &conditionvalue);
667
668 //for results true
669 if (atoi(conditionvalue.c_str()) != 0)
670 {
671
672 //confirm open brace
673 iObracefound = iCparenfound + 1;
674
675 //open brace must exist
676 if (iObracefound > buff->getarraylength() - 2)
677 return errormessage(lin, "cannot find brace open / close", "for");
678
679 if ((*buff)[iObracefound].status == OPAREN\
680 && (*buff)[iObracefound].bracestatus == BRC_FOR)
681 {
682 //search the position of closed brace
683 iCbracefound = -1;
684 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
685 {
686 if ((*buff)[itemp].status == CPAREN \
687 && (*buff)[itemp].bracestatus == BRC_FOR\
688 && ((*buff)[itemp].parentheseslevel == (*buff)[iObracefound].parentheseslevel))
689 {
690 iCbracefound = itemp;
691 break;
692 }
693 }
694
695 //closed brace exist!!
696 if (iCbracefound != -1)
697 {
698 (*buff)[iCbracefound].jumpindex = i + 1;
699 i = iObracefound;
700 }
701 else
702 return errormessage(lin, "cannot find brace close", "for");
703 }
704 else
705 return errormessage(lin, "cannot find brace open", "for");
706 }
707 //for results false
708 else
709 {
710 //search closed brace of for block
711 iObracefound = iCparenfound + 1;
712 iCbracefound = -1;
713 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
714 {
715 if ((*buff)[itemp].status == CPAREN \
716 && (*buff)[itemp].bracestatus == BRC_FOR\
717 && (*buff)[itemp].parentheseslevel\
718 == (*buff)[iObracefound].parentheseslevel)
719 {
720 iCbracefound = itemp;
721 break;
722 }
723 }
724
725 if (iCbracefound != -1)
726 i = iCbracefound;
727 else
728 return errormessage(lin, "cannot find brace close", "for");
729 }
730 }
731 else
732 return errormessage(lin, "cannot find parenthesis close", "for");
733 }
734 else
735 return errormessage(lin, "cannot find parenthesis open", "for");
736 }
737 else if (curtoken->status == NEXTFOR)
738 {
739 //closed parentheses must be in buffer
740 if((i + 2) > buff->getarraylength() - 1)
741 return errormessage(lin, "cannot find parenthesis close", "for");
742 //open parentheses must be followed by 'nextfor'
743 if ((*buff)[i + 1].status == OPAREN)
744 {
745 iOparenfound = i + 1;
746 //search the position of closed parensis
747 iCparenfound = -1;
748 for (itemp = i + 2; itemp < buff->getarraylength(); itemp++)
749 {
750 if ((*buff)[itemp].status == CPAREN \
751 && (*buff)[itemp].bracestatus == BRC_FOR\
752 && (*buff)[itemp].parentheseslevel == (*buff)[i + 1].parentheseslevel)
753 {
754 iCparenfound = itemp;
755 break;
756 }
757 }
758
759 //closed parentheses is found
760 if (iCparenfound != -1)
761 {
762 //condition expression must contain three 'comma's
763 commacount = 0;
764 for (itemp = iOparenfound; itemp <iCparenfound; itemp++)
765 {
766 if ((*buff)[itemp].status == SEMICOLON)
767 commacount++;
768 }
769
770 if (commacount != 2)
771 return errormessage(lin, "invalid 'for' condition", "for");
772
773 //search comma position
774 commacount = 0;
775 for (itemp = iOparenfound; itemp <iCparenfound; itemp++)
776 {
777 if ((*buff)[itemp].status == SEMICOLON)
778 commaposition[commacount++] = itemp;
779 }
780
781 //incremet (ex. i = i + 1;)
782 for (itemp = commaposition[1] + 1; itemp < iCparenfound; itemp++)
783 exectoken(&(*buff)[itemp]);
784 commatoken.lineno = i;
785 exectoken(&commatoken);
786
787 //condition (ex. i < 100)
788 conditionvariant.lineno = i;
789 exectoken(&conditionvariant);
790 setoperand.lineno = i;
791 exectoken(&setoperand);
792 for (itemp = commaposition[0] + 1; itemp <= commaposition[1]; itemp++)
793 exectoken(&(*buff)[itemp]);
794 str3 = std::string("$reserved_by_system_for_evaluation");
795 vbuff->GetScalar(&str3, &conditionvalue);
796
797 //for results true
798 if (atoi(conditionvalue.c_str()) != 0)
799 {
800 //confirm open brace
801 iObracefound = iCparenfound + 1;
802
803 //open brace must exist
804 if (iObracefound > buff->getarraylength() - 2)
805 return errormessage(lin, "cannot fine brace open / close", "for");
806
807 if ((*buff)[iObracefound].status == OPAREN\
808 && (*buff)[iObracefound].bracestatus == BRC_FOR)
809 {
810 //search the position of closed brace
811 iCbracefound = -1;
812 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
813 {
814 if ((*buff)[itemp].status == CPAREN \
815 && (*buff)[itemp].bracestatus == BRC_FOR\
816 && (*buff)[itemp].parentheseslevel\
817 == (*buff)[iObracefound].parentheseslevel)
818 {
819 iCbracefound = itemp;
820 break;
821 }
822 }
823
824 //closed brace exist!!
825 if (iCbracefound != -1)
826 {
827 (*buff)[iCbracefound].jumpindex = i;
828 i = iObracefound;
829 }
830 else
831 return errormessage(lin, "cannot fine brace close", "for");
832 }
833 else
834 return errormessage(lin, "cannot fine brace open", "for");
835 }
836 //for results false
837 else
838 {
839 //search closed brace of if block
840 iObracefound = iCparenfound + 1;
841 iCbracefound = -1;
842 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
843 {
844 if ((*buff)[itemp].status == CPAREN \
845 && (*buff)[itemp].bracestatus == BRC_FOR\
846 && (*buff)[itemp].parentheseslevel\
847 == (*buff)[iObracefound].parentheseslevel)
848 {
849 iCbracefound = itemp;
850 break;
851 }
852 }
853
854 if (iCbracefound != -1)
855 i = iCbracefound;
856 else
857 return errormessage(lin, "cannot fine brace close", "for");
858 }
859 }
860 else
861 return errormessage(lin, "cannot fine parenthesis close", "for");
862 }
863 else
864 return errormessage(lin, "cannot fine parenthesis open", "for");
865 }
866 else if (curtoken->status == FOREACH)
867 {
868 //closed parentheses must be in buffer
869 if((i + 4) > buff->getarraylength() - 1)
870 return errormessage(lin, "cannot fine parenthesis close", "foreach");
871
872 //"nextforeach" and "variant" and "open parentheses" must be followed by 'foreach'
873 if ((*buff)[i + 1].status == NEXTFOREACH
874 && (*buff)[i + 2].status == VARIANT
875 && (*buff)[i + 3].status == OPAREN)
876 {
877 iOparenfound = i + 3;
878 //search the position of closed parensis
879 iCparenfound = -1;
880 for (itemp = iOparenfound + 1; itemp < buff->getarraylength(); itemp++)
881 {
882 if ((*buff)[itemp].status == CPAREN \
883 && (*buff)[itemp].bracestatus == BRC_FOREACH\
884 && ((*buff)[itemp].parentheseslevel == (*buff)[iOparenfound].parentheseslevel))
885 {
886 iCparenfound = itemp;
887 break;
888 }
889 }
890
891 //closed parentheses is found
892 if (iCparenfound != -1)
893 {
894 //exec between open parentheses and closed parenses
895 v->setbuff(0);
896 for (itemp = iOparenfound; itemp <= iCparenfound; itemp++)
897 exectoken(&(*buff)[itemp]);
898 if (calc() == false)
899 return errormessage(lin, "invalid array or list", "foreach");
900
901 if ((*v)[v->getarraylength() - 1].status == ARRAY)
902 {
903 (*buff)[i + 1].count = 0;
904 (*buff)[i + 1].value->setbuff(0);
905 for (int j = 0; j < vbuff->ArrayLength((*v)[v->getarraylength() - 1].label); j++)
906 {
907 vbuff->Get((*v)[v->getarraylength() - 1].label, j, &str1);
908 (*buff)[i + 1].value->add(str1.c_str());
909 }
910 vbuff->Get((*v)[v->getarraylength() - 1].label, (*buff)[i + 1].count, &str1);
911 vbuff->SetScalar((*buff)[i + 2].label, &str1);
912 length = vbuff->ArrayLength((*v)[v->getarraylength() - 1].label);
913 v->pop();
914 }
915 else if ((*v)[v->getarraylength() - 1].status == IMPLICITARRAY)
916 {
917 (*buff)[i + 1].count = 0;
918 (*buff)[i + 1].value->setbuff(0);
919 for (int j = 0; j < (*v)[v->getarraylength() - 1].value->getarraylength(); j++)
920 {
921 str1 = (*v)[v->getarraylength() - 1].value->getdata(j);
922 (*buff)[i + 1].value->add(str1.c_str());
923 }
924 str1 = (*v)[v->getarraylength() - 1].value->getdata((*buff)[i + 1].count);
925 vbuff->SetScalar((*buff)[i + 2].label, &str1);
926 length = (*v)[v->getarraylength() - 1].value->getarraylength();
927 v->pop();
928 }
929 else
930 return false;
931
932 //count is less than array length
933 if ((*buff)[i].count < length)
934 {
935
936 //confirm open brace
937 iObracefound = iCparenfound + 1;
938
939 //open brace must exist
940 if (iObracefound > buff->getarraylength() - 2)
941 return errormessage(lin, "cannot fine brace open / close", "foreach");
942
943 if ((*buff)[iObracefound].status == OPAREN\
944 && (*buff)[iObracefound].bracestatus == BRC_FOREACH)
945 {
946 //search the position of closed brace
947 iCbracefound = -1;
948 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
949 {
950 if ((*buff)[itemp].status == CPAREN \
951 && (*buff)[itemp].bracestatus == BRC_FOREACH\
952 && ((*buff)[itemp].parentheseslevel == (*buff)[iObracefound].parentheseslevel))
953 {
954 iCbracefound = itemp;
955 break;
956 }
957 }
958
959 //closed brace exist!!
960 if (iCbracefound != -1)
961 {
962 (*buff)[iCbracefound].jumpindex = i + 1;
963 i = iObracefound;
964 }
965 else
966 return errormessage(lin, "cannot fine brace close", "foreach");
967 }
968 else
969 return errormessage(lin, "cannot fine brace open", "foreach");
970 }
971 //count is greater than array length
972 else
973 {
974 //search closed brace of for block
975 iObracefound = iCparenfound + 1;
976 iCbracefound = -1;
977 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
978 {
979 if ((*buff)[itemp].status == CPAREN \
980 && (*buff)[itemp].bracestatus == BRC_FOREACH\
981 && (*buff)[itemp].parentheseslevel\
982 == (*buff)[iObracefound].parentheseslevel)
983 {
984 iCbracefound = itemp;
985 break;
986 }
987 }
988
989 if (iCbracefound != -1)
990 i = iCbracefound;
991 else
992 return errormessage(lin, "cannot fine brace close", "foreach");
993 }
994 }
995 else
996 return errormessage(lin, "cannot fine parenthesis close", "foreach");
997 }
998 else
999 return errormessage(lin, "cannot fine parenthesis open", "foreach");
1000 }
1001 else if (curtoken->status == NEXTFOREACH)
1002 {
1003
1004 //closed parentheses must be in buffer
1005 if((i + 3) > buff->getarraylength() - 1)
1006 return errormessage(lin, "cannot fine parenthesis close", "foreach");
1007
1008 //"nextfor" and "variant" and "open parentheses" must be followed by 'for'
1009 if ((*buff)[i + 1].status == VARIANT
1010 && (*buff)[i + 2].status == OPAREN)
1011 {
1012 iOparenfound = i + 2;
1013 //search the position of closed parensis
1014 iCparenfound = -1;
1015 for (itemp = iOparenfound + 1; itemp < buff->getarraylength(); itemp++)
1016 {
1017 if ((*buff)[itemp].status == CPAREN \
1018 && (*buff)[itemp].bracestatus == BRC_FOREACH\
1019 && ((*buff)[itemp].parentheseslevel == (*buff)[iOparenfound].parentheseslevel))
1020 {
1021 iCparenfound = itemp;
1022 break;
1023 }
1024 }
1025
1026 //closed parentheses is found
1027 if (iCparenfound != -1)
1028 {
1029 (*buff)[i].count++;
1030 length = (*buff)[i].value->getarraylength();
1031
1032 //count is less than array length
1033 if ((*buff)[i].count < length)
1034 {
1035 str1 = (*buff)[i].value->getdata((*buff)[i].count);
1036 vbuff->SetScalar((*buff)[i + 1].label, &str1);
1037
1038 //confirm open brace
1039 iObracefound = iCparenfound + 1;
1040
1041 //open brace must exist
1042 if (iObracefound > buff->getarraylength() - 2)
1043 return errormessage(lin, "cannot find brace open / close", "foreach");
1044
1045 if ((*buff)[iObracefound].status == OPAREN\
1046 && (*buff)[iObracefound].bracestatus == BRC_FOREACH)
1047 {
1048 //search the position of closed brace
1049 iCbracefound = -1;
1050 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
1051 {
1052 if ((*buff)[itemp].status == CPAREN \
1053 && (*buff)[itemp].bracestatus == BRC_FOREACH\
1054 && ((*buff)[itemp].parentheseslevel == (*buff)[iObracefound].parentheseslevel))
1055 {
1056 iCbracefound = itemp;
1057 break;
1058 }
1059 }
1060
1061 //closed brace exist!!
1062 if (iCbracefound != -1)
1063 {
1064 (*buff)[iCbracefound].jumpindex = i;
1065 i = iObracefound;
1066 }
1067 else
1068 return errormessage(lin, "cannot find brace close", "foreach");
1069 }
1070 else
1071 return errormessage(lin, "cannot find brace open", "foreach");
1072 }
1073 //count is greater than array length
1074 else
1075 {
1076 //search closed brace of for block
1077 iObracefound = iCparenfound + 1;
1078 iCbracefound = -1;
1079 for (itemp = iObracefound; itemp <= buff->getarraylength() - 1; itemp++)
1080 {
1081 if ((*buff)[itemp].status == CPAREN \
1082 && (*buff)[itemp].bracestatus == BRC_FOREACH\
1083 && (*buff)[itemp].parentheseslevel\
1084 == (*buff)[iObracefound].parentheseslevel)
1085 {
1086 iCbracefound = itemp;
1087 break;
1088 }
1089 }
1090
1091 if (iCbracefound != -1)
1092 i = iCbracefound;
1093 else
1094 return errormessage(lin, "cannot find brace close", "foreach");
1095 }
1096 }
1097 else
1098 return errormessage(lin, "cannot find parenthesis close", "foreach");
1099 }
1100 else
1101 return errormessage(lin, "cannot find parenthesis open", "foreach");
1102 }
1103 else
1104 {
1105 exectokenflag = exectoken(curtoken);
1106 if (exectokenflag != true)
1107 return exectokenflag;
1108 }
1109 }
1110
1111 return true;
1112 }
1113
1114
1115
exectoken(tokenbuff * token)1116 int script::exectoken(tokenbuff *token)
1117 {
1118 int status;
1119
1120 while (token->priority <= (*stack)[stack->getarraylength() - 1].priority \
1121 && (*stack)[stack->getarraylength() - 1].status != OPAREN)
1122 {
1123
1124 polish->push1(&(*stack)[stack->getarraylength() - 1]); stack->pop();
1125 }
1126
1127 if (token->status != CPAREN)
1128 {
1129 if (token->status != SEMICOLON)
1130 stack->push1(token);
1131 else
1132 {
1133 status = calc();
1134 if (status == false)
1135 return false;
1136 else if (status == exitscriptstatus)
1137 return exitscriptstatus;
1138
1139 v->setbuff(0);
1140 polish->setbuff(0);
1141 }
1142 }
1143 else if (token->status == CPAREN && (*stack)[stack->getarraylength() - 1].status == OPAREN)
1144 stack->pop();
1145
1146 return true;
1147 }
1148
1149
execscript(std::string * inputstr,std::string * out,buffarray * arg)1150 int script::execscript(std::string *inputstr, std::string *out, buffarray* arg)
1151 {
1152 std::string returnvalue, str;
1153
1154 initparse(arg, 0);
1155
1156 if (parsetoken(inputstr) == false)
1157 return false;
1158
1159 switch (controltoken())
1160 {
1161 case exitscriptstatus:
1162 if (out == 0)
1163 return exitscriptstatus;
1164 else
1165 {
1166 str = std::string("$_EXIT");
1167 if (vbuff->GetScalar(&str, &returnvalue))
1168 {
1169 *out = returnvalue;
1170 return exitscriptstatus;
1171 }
1172 else
1173 return false;
1174 }
1175 case true:
1176 return true;
1177 case false:
1178 return false;
1179 }
1180 return true;
1181 }
1182
getmacroname(std::string * file,std::string * out)1183 bool getmacroname(std::string *file, std::string *out)
1184 {
1185 std::string str;
1186 if (getenv("TOPAZINIDIR") == NULL)
1187 return false;
1188
1189 if (fileexist((char *)file->c_str()))
1190 {
1191 *out = *file;
1192 return true;
1193 }
1194 else
1195 {
1196 str = std::string(getenv("TOPAZINIDIR")) + std::string("/") + *file;
1197 if (fileexist((char *)str.c_str()))
1198 {
1199 *out = str;
1200 return true;
1201 }
1202 else
1203 {
1204 if (getenv("TOPAZMACRODIR") == NULL)
1205 str = std::string("");
1206 else
1207 str = std::string(getenv("TOPAZMACRODIR")) + std::string("/") + *file;
1208 if (fileexist((char *)str.c_str()))
1209 {
1210 *out = str;
1211 return true;
1212 }
1213 else
1214 {
1215 if (getenv("TOPAZDIR") == NULL)
1216 return false;
1217 str = std::string(getenv("TOPAZDIR")) + std::string("/_topaz/") + *file;
1218 if (fileexist((char *)str.c_str()))
1219 {
1220 *out = str;
1221 return true;
1222 }
1223 else
1224 return false;
1225 }
1226 }
1227 }
1228 return true;
1229 }
1230
execscriptfile(std::string * inputfile,std::string * out,buffarray * arg)1231 int script::execscriptfile(std::string *inputfile, std::string *out, buffarray* arg)
1232 {
1233 FILE *fp;
1234 char stemp[1000];
1235 std::string tempstr;
1236 std::string returnvalue,str;
1237
1238 if (!getmacroname(inputfile, &tempstr))
1239 return NOTEXISTSCRIPT;
1240
1241 *scriptname = *inputfile;
1242 if ((fp = fopen((char *)tempstr.c_str(), "r")) != 0)
1243 {
1244 initparse(arg, &tempstr);
1245 while (topazfgets(stemp, sizeof(stemp), fp) != NULL)
1246 {
1247 tempstr = std::string(stemp);
1248 if (!parsetoken(&tempstr))
1249 return false;
1250 lineno++;
1251 }
1252 fclose(fp);
1253
1254 switch (controltoken())
1255 {
1256 case exitscriptstatus:
1257 if (out == 0)
1258 return exitscriptstatus;
1259 else
1260 {
1261 str = std::string("$_EXIT");
1262 if (vbuff->GetScalar(&str, &returnvalue))
1263 {
1264 *out = returnvalue;
1265 return exitscriptstatus;
1266 }
1267 else
1268 return false;
1269 }
1270 case true:
1271 return true;
1272 case false:
1273 return false;
1274 }
1275 }
1276 else
1277 return NOTEXISTSCRIPT;
1278 return true;
1279 }
1280
1281
sepenvvalue(char * in,std::string * label,std::string * value)1282 bool sepenvvalue(char *in, std::string *label, std::string *value)
1283 {
1284 char *p = in;
1285 std::string str;
1286 char stemp[10];
1287
1288 str = std::string("");
1289 while (*p != 0)
1290 {
1291 if (*p != '=')
1292 {
1293 stemp[0] = *p; stemp[1] = 0;
1294 str += std::string(stemp);
1295 }
1296 else
1297 {
1298 *label = str;
1299 *value = std::string(p + 1);
1300 return true;
1301 }
1302 p++;
1303 }
1304 return false;
1305 }
1306
getenvstring()1307 void script::getenvstring()
1308 {
1309 std::string label, value, lbl;
1310
1311 for (int i = 0; envp[i] != NULL; i++)
1312 {
1313 if (sepenvvalue(envp[i], &label, &value))
1314 {
1315 lbl = std::string("$") + label;
1316 vbuff->SetSystemScalar(&lbl, &value);
1317 }
1318 }
1319 }
1320
1321
1322
initparse(buffarray * arg,std::string * scrfile)1323 void script::initparse(buffarray* arg, std::string *scrfile)
1324 {
1325 int argno;
1326 char stemp[1000];
1327 std::string str1, str2;
1328
1329 // initialize status
1330 strstatusbuffpoint = 0;
1331 bracestatusbuffpoint = 0;
1332 parentheseslevel = 0;
1333 lineno = 1;
1334
1335 //special variables
1336 // separation of print
1337 str1 = std::string("$,"); str2 = std::string("");
1338 vbuff->SetScalar(&str1, &str2); // print separator
1339 str1 = std::string("$\""); str2 = std::string(" ");
1340 vbuff->SetScalar(&str1, &str2); // separator for array in "..."
1341 str1 = std::string("$/"); str2 = std::string("\n");
1342 vbuff->SetScalar(&str1, &str2); // chomp character
1343 str1 = std::string("$_EXIT"); str2 = std::string("");
1344 vbuff->SetScalar(&str1, &str2); // exit value
1345 str1 = std::string("$&"); str2 = std::string("");
1346 vbuff->SetScalar(&str1, &str2); // match pattern
1347 str1 = std::string("$`"); str2 = std::string("");
1348 vbuff->SetScalar(&str1, &str2); // match before
1349 str1 = std::string("$'"); str2 = std::string("");
1350 vbuff->SetScalar(&str1, &str2); // match after
1351 str1 = std::string("$|"); str2 = std::string("0");
1352 vbuff->SetScalar(&str1, &str2); // print flush after "print"
1353 str1 = std::string("$_RET"); str2 = std::string("");
1354 vbuff->SetScalar(&str1, &str2);
1355 str1 = std::string("$_CUR"); str2 = std::string("-2");
1356 vbuff->SetSystemScalar(&str1, &str2);
1357 str1 = std::string("$_SEL"); str2 = std::string("-3");
1358 vbuff->SetSystemScalar(&str1, &str2);
1359 str1 = std::string("$_ALL"); str2 = std::string("-4");
1360 vbuff->SetSystemScalar(&str1, &str2);
1361 str1 = std::string("$_FSL"); str2 = std::string("-5");
1362 vbuff->SetSystemScalar(&str1, &str2);
1363 sprintf(stemp, "%u", (unsigned int)getpid());
1364 str1 = std::string("$PID"); str2 = std::string(stemp);
1365 vbuff->SetSystemScalar(&str1, &str2);
1366 str1 = std::string("@_RET");
1367 vbuff->SetArray(&str1, 0);
1368
1369 // set environ values as readonly value
1370 getenvstring();
1371
1372 // set initfile dir
1373 str1 = std::string("$TOPAZTMP"); str2 = std::string(tmppath);
1374 vbuff->SetSystemScalar(&str1, &str2);
1375
1376 // set numerical
1377 sprintf(stemp, "%.15g", M_PI);
1378 str1 = std::string("$PI"); str2 = std::string(stemp);
1379 vbuff->SetSystemScalar(&str1, &str2);
1380
1381 // set scriptfilename
1382 str1 = std::string("$0"); str2 = std::string("");
1383 if (scrfile != 0)
1384 vbuff->SetSystemScalar(&str1, scrfile);
1385 else
1386 vbuff->SetSystemScalar(&str1, &str2);
1387
1388 // set argument
1389 if (arg != 0)
1390 {
1391 argno = arg->getarraylength();
1392 str1 = std::string("@ARGV");
1393 vbuff->SystemSetArray(&str1, argno);
1394 for (int i = 0; i < argno; i++)
1395 vbuff->SystemSet(&str1, i, &(*arg)[i]);
1396 }
1397 }
1398
1399
1400
1401
1402
1403
1404
1405