36 static UBYTE pushbackchar = 0;
37 static int oldmode = 0;
38 static int stopdelay = 0;
39 static STREAM *oldstream = 0;
40 static UBYTE underscore[2] = {
'_',0};
41 static PREVAR *ThePreVar = 0;
43 static KEYWORD precommands[] = {
44 {
"add" , DoPreAdd , 0, 0}
45 ,{
"addseparator" , DoPreAddSeparator,0,0}
46 ,{
"append" , DoPreAppend , 0, 0}
48 ,{
"assign" , DoPreAssign , 0, 0}
49 ,{
"break" , DoPreBreak , 0, 0}
50 ,{
"breakdo" , DoBreakDo , 0, 0}
51 ,{
"call" , DoCall , 0, 0}
52 ,{
"case" , DoPreCase , 0, 0}
53 ,{
"clearoptimize", DoClearOptimize, 0, 0}
54 ,{
"close" , DoPreClose , 0, 0}
55 ,{
"closedictionary", DoPreCloseDictionary,0,0}
56 ,{
"commentchar" , DoCommentChar , 0, 0}
57 ,{
"create" , DoPreCreate , 0, 0}
58 ,{
"debug" , DoDebug , 0, 0}
59 ,{
"default" , DoPreDefault , 0, 0}
60 ,{
"define" , DoDefine , 0, 0}
62 ,{
"else" , DoElse , 0, 0}
63 ,{
"elseif" , DoElseif , 0, 0}
64 ,{
"enddo" , DoEnddo , 0, 0}
65 ,{
"endif" , DoEndif , 0, 0}
66 ,{
"endinside" , DoEndInside , 0, 0}
67 ,{
"endprocedure" , DoEndprocedure , 0, 0}
68 ,{
"endswitch" , DoPreEndSwitch , 0, 0}
69 ,{
"exchange" , DoPreExchange , 0, 0}
70 ,{
"external" , DoExternal , 0, 0}
71 ,{
"factdollar" , DoFactDollar , 0, 0}
72 ,{
"fromexternal" , DoFromExternal , 0, 0}
74 ,{
"ifdef" , DoIfydef , 0, 0}
75 ,{
"ifndef" , DoIfndef , 0, 0}
76 ,{
"include" , DoInclude , 0, 0}
77 ,{
"inside" , DoInside , 0, 0}
78 ,{
"message" , DoMessage , 0, 0}
79 ,{
"opendictionary", DoPreOpenDictionary,0,0}
80 ,{
"optimize" , DoOptimize , 0, 0}
81 ,{
"pipe" , DoPipe , 0, 0}
82 ,{
"preout" , DoPreOut , 0, 0}
84 ,{
"printtimes" , DoPrePrintTimes, 0, 0}
85 ,{
"procedure" , DoProcedure , 0, 0}
86 ,{
"procedureextension" , DoPrcExtension , 0, 0}
87 ,{
"prompt" , DoPrompt , 0, 0}
88 ,{
"redefine" , DoRedefine , 0, 0}
89 ,{
"remove" , DoPreRemove , 0, 0}
90 ,{
"reset" , DoPreReset , 0, 0}
91 ,{
"reverseinclude" , DoReverseInclude , 0, 0}
92 ,{
"rmexternal" , DoRmExternal , 0, 0}
93 ,{
"rmseparator" , DoPreRmSeparator,0, 0}
94 ,{
"setexternal" , DoSetExternal , 0, 0}
95 ,{
"setexternalattr" , DoSetExternalAttr , 0, 0}
96 ,{
"setrandom" , DoSetRandom , 0, 0}
97 ,{
"show" , DoPreShow , 0, 0}
98 ,{
"skipextrasymbols" , DoSkipExtraSymbols , 0, 0}
99 ,{
"switch" , DoPreSwitch , 0, 0}
100 ,{
"system" , DoSystem , 0, 0}
101 ,{
"terminate" , DoTerminate , 0, 0}
102 ,{
"timeoutafter" , DoTimeOutAfter , 0, 0}
103 ,{
"toexternal" , DoToExternal , 0, 0}
104 ,{
"undefine" , DoUndefine , 0, 0}
105 ,{
"usedictionary", DoPreUseDictionary,0,0}
106 ,{
"write" , DoPreWrite , 0, 0}
122 while ( AC.CurrentStream ) {
123 c = GetFromStream(AC.CurrentStream);
124 if ( c != ENDOFSTREAM ) {
127 && AC.NoShowInput <= 0
128 && AC.CurrentStream->type != PREVARSTREAM )
130 if ( AC.NoShowInput <= 0 && AC.CurrentStream->type != PREVARSTREAM )
135 AC.CurrentStream = CloseStream(AC.CurrentStream);
136 if ( stopdelay && AC.CurrentStream == oldstream ) {
137 stopdelay = 0; AP.AllowDelay = 1;
166 UBYTE GetChar(
int level)
168 UBYTE namebuf[MAXPRENAMESIZE+2], c, *s, *t;
169 static UBYTE lastchar, charinbuf = 0;
170 int i, j, raiselow, olddelay;
176 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0;
return(c); }
177 if ( charinbuf ) { c = charinbuf; charinbuf = 0;
return(c); }
181 charinbuf = GetInput();
182 if ( charinbuf != LINEFEED ) {
183 pushbackchar = charinbuf;
188 while ( ( c = GetInput() ) ==
' ' || c ==
'\t' ) {}
190 else if ( c ==
'\'' || c ==
'`' ) {
191 if ( AP.DelayPrevar == 1 && c ==
'\'' ) {
198 if ( c ==
'!' && lastchar ==
'`' ) {
199 if ( stopdelay == 0 ) oldstream = AC.CurrentStream;
204 if ( c ==
'~' && lastchar ==
'`' ) {
205 if ( AP.AllowDelay ) {
215 olddelay = AP.DelayPrevar;
219 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0; }
220 else { c = GetInput(); }
221 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
222 && lastchar !=
'\\' ) ) {
226 if ( PreCalc() == 0 ) Terminate(-1);
229 MesPrint(
"@Illegal set inside preprocessor variable name");
233 if ( c ==
'`' && lastchar !=
'\\' ) {
235 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
236 && lastchar !=
'\\' ) ) {
240 if ( lastchar ==
'\\' ) { i--; lastchar = 0; }
243 if ( i > MAXPRENAMESIZE ) {
245 Error1(
"Preprocessor variable name too long: ",namebuf);
250 Error1(
"Unmatched quotes for preprocessor variable",namebuf);
252 AP.DelayPrevar = olddelay;
253 if ( namebuf[0] ==
'$' ) {
254 raiselow = PRENOACTION;
255 if ( AP.PreproFlag && *AP.preStart) {
256 s = EndOfToken(AP.preStart);
258 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
259 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
260 && GetDollar(namebuf+1) < 0 ) {
267 s = EndOfToken(namebuf+1);
268 if ( *s ==
'[' ) {
while ( *s ) s++; }
270 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
271 raiselow = PRELOWERAFTER;
272 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
273 raiselow = PRERAISEAFTER;
275 if ( OpenStream(namebuf+1,DOLLARSTREAM,0,raiselow) == 0 ) {
277 MesPrint(
"@Undefined variable %s used as preprocessor variable",
284 raiselow = PRENOACTION;
285 if ( AP.PreproFlag && *AP.preStart) {
286 s = EndOfToken(AP.preStart);
288 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
289 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
296 s = EndOfToken(namebuf);
297 if ( *s ==
'_' ) s++;
298 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
299 raiselow = PRELOWERAFTER;
300 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
301 raiselow = PRERAISEAFTER;
302 else if ( *s ==
'(' && namebuf[i-2] ==
')' ) {
313 *s++ = 0; namebuf[i-2] = 0;
314 if ( StrICmp(namebuf,(UBYTE *)
"random_") == 0 ) {
316 ranvalue = PreRandom(s);
317 PutPreVar(namebuf,ranvalue,(UBYTE *)
"?a",1);
318 M_free(ranvalue,
"PreRandom");
321 else if ( StrICmp(namebuf,(UBYTE *)
"tolower_") == 0 ) {
323 while ( *ss ) { *ss = (UBYTE)(tolower(*ss)); ss++; }
327 else if ( StrICmp(namebuf,(UBYTE *)
"toupper_") == 0 ) {
329 while ( *ss ) { *ss = (UBYTE)(toupper(*ss)); ss++; }
334 if ( *s ==
'\\' ) s++;
335 if ( *s ==
',' ) { *s = 0; nargs++; }
338 GetPreVar(namebuf,WITHERROR);
341 MesPrint(
"@Illegal use of arguments in preprocessor variable %s",namebuf);
345 || ( p->
wildarg > 0 && nargs < p->nargs-1 ) ) {
346 MesPrint(
"@Arguments of macro %s do not match",namebuf);
354 for ( j = 0; j < p->
wildarg; j++ ) {
358 for ( j = 0; j < nargs-p->
nargs; j++ ) {
370 for ( j = 0; j < p->
nargs; j++ ) {
371 if ( ( nargs == p->
nargs-1 ) && ( *t ==
'?' ) ) {
384 if ( ( stream = OpenStream(namebuf,PREVARSTREAM,0,raiselow) ) == 0 ) {
389 else if ( stream->inbuffer == 0 ) {
391 if ( level > 0 && c ==
'\'' )
return(c);
397 else if ( c ==
'{' ) {
398 if ( PreCalc() == 0 ) Terminate(-1);
413 VOID CharOut(UBYTE c)
415 if ( c == LINEFEED ) {
416 AM.OutBuffer[AP.InOutBuf++] = c;
417 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
421 if ( AP.InOutBuf >= AM.OutBufSize || c == LINEFEED ) {
422 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
425 AM.OutBuffer[AP.InOutBuf++] = c;
434 VOID UnsetAllowDelay()
436 if ( ThePreVar != 0 ) {
437 if ( ThePreVar->
nargs > 0 ) AP.AllowDelay = 0;
454 static UBYTE *yes = (UBYTE *)
"1";
455 static UBYTE *no = (UBYTE *)
"0";
456 static UBYTE numintopolynomial[12];
458 static Vector(UBYTE, exprstr);
460 UBYTE *GetPreVar(UBYTE *name,
int flag)
465 UBYTE *t, c = 0, *tt = 0;
466 t = name;
while ( *t ) t++;
467 if ( t[-1] ==
'-' && t[-2] ==
'-' && t-2 > name && t[-3] !=
'_' ) {
468 t -= 2; c = *t; *t = 0; tt = t;
470 else if ( t[-1] ==
'+' && t[-2] ==
'+' && t-2 > name && t[-3] !=
'_' ) {
471 t -= 2; c = *t; *t = 0; tt = t;
473 else if ( StrICmp(name,(UBYTE *)
"time_") == 0 ) {
475 LONG millitime, timepart;
476 int timepart1, timepart2;
477 static char timestring[40];
479 millitime = GetRunningTime();
480 timepart = millitime%1000;
483 timepart1 = timepart / 10;
484 timepart2 = timepart % 10;
485 NumToStr(millibuf,millitime);
486 sprintf(timestring,
"%s.%1d%1d",millibuf,timepart1,timepart2);
487 return((UBYTE *)timestring);
489 else if ( ( StrICmp(name,(UBYTE *)
"timer_") == 0 )
490 || ( StrICmp(name,(UBYTE *)
"stopwatch_") == 0 ) ) {
491 static char timestring[40];
492 sprintf(timestring,
"%ld",(GetRunningTime() - AP.StopWatchZero));
493 return((UBYTE *)timestring);
495 else if ( StrICmp(name, (UBYTE *)
"numactiveexprs_") == 0 ) {
498 for ( i = 0; i < NumExpressions; i++ ) {
500 switch ( e->status ) {
501 case LOCALEXPRESSION:
502 case GLOBALEXPRESSION:
503 case UNHIDELEXPRESSION:
504 case UNHIDEGEXPRESSION:
505 case INTOHIDELEXPRESSION:
506 case INTOHIDEGEXPRESSION:
515 else if ( StrICmp(name, (UBYTE *)
"activeexprnames_") == 0 ) {
519 for ( i = 0; i < NumExpressions; i++ ) {
523 switch ( e->status ) {
524 case LOCALEXPRESSION:
525 case GLOBALEXPRESSION:
526 case UNHIDELEXPRESSION:
527 case UNHIDEGEXPRESSION:
528 case INTOHIDELEXPRESSION:
529 case INTOHIDEGEXPRESSION:
530 s = AC.exprnames->namebuffer + e->name;
535 if ( j > 0 ) p[j++] =
',';
536 for ( k = 0; k < len; k++ ) {
537 if ( s[k] ==
',' || s[k] ==
'|' ) p[j++] =
'\\';
546 else if ( StrICmp(name, (UBYTE *)
"path_") == 0 ) {
556 while ( *t && *t !=
'_' ) t++;
557 for ( i = NumPre-1; i >= 0; i-- ) {
558 if ( *t ==
'_' && ( StrICmp(name,PreVar[i].name) == 0 ) ) {
560 ThePreVar = PreVar+i;
561 return(PreVar[i].value);
563 else if ( StrCmp(name,PreVar[i].name) == 0 ) {
565 ThePreVar = PreVar+i;
566 return(PreVar[i].value);
570 if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS_") == 0 )
goto extrashort;
572 if ( StrICmp(name,(UBYTE *)
"UNCHANGED") == 0 ) mode = 1;
573 else if ( StrICmp(name,(UBYTE *)
"ZERO") == 0 ) mode = 0;
574 else if ( StrICmp(name,(UBYTE *)
"SHOWINPUT") == 0 ) {
577 if ( AC.NoShowInput > 0 )
return(no);
580 else if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS") == 0 ) {
583 number = cbuf[AM.sbufnum].numrhs;
584 t = numintopolynomial;
586 return(numintopolynomial);
593 if ( GetName(AC.exprnames,t,&number,NOAUTO) == CEXPRESSION ) {
595 if ( ( Expressions[number].vflags & ( 1 << mode ) ) != 0 )
606 if ( ( AR.expflags & ( 1 << mode ) ) == 0 )
return(yes);
611 if ( ( t = (UBYTE *)(getenv((
char *)(name))) ) != 0 ) {
617 if ( flag == WITHERROR ) {
618 Error1(
"Undefined preprocessor variable",name);
642 int PutPreVar(UBYTE *name, UBYTE *value, UBYTE *args,
int mode)
644 int i, ii, num = 2, nnum = 2, numargs = 0;
645 UBYTE *s, *t, *u = 0;
647 if ( value == 0 && name[0] !=
'?' ) {
648 MesPrint(
"@Illegal empty value for preprocessor variable %s",name);
654 if ( *s !=
' ' && *s !=
'\t' ) num++;
661 if ( StrCmp(name,PreVar[i].name) == 0 ) {
668 if ( i < 0 ) { p = (
PREVAR *)FromList(&AP.PreVarList); ii = p - PreVar; }
669 else { p = &(PreVar[i]); ii = i; }
671 s = value;
while ( *s ) { s++; num++; }
677 while ( *s ) { s++; nnum++; }
684 if ( value && p->
value ) {
687 while ( *s ) *t++ = *s++;
694 s = name;
while ( *s ) { s++; num++; }
695 t = (UBYTE *)Malloc1(num,
"PreVariable");
697 s = name;
while ( *s ) *t++ = *s++; *t++ = 0;
700 s = value;
while ( *s ) *t++ = *s++; *t = 0;
701 if ( AM.atstartup && t[-1] ==
'\n' ) t[-1] = 0;
710 if ( *s ==
' ' || *s ==
'\t' ) { s++;
continue; }
712 s++; *t++ = 0; numargs++;
713 while ( *s ==
' ' || *s ==
'\t' ) s++;
716 Error0(
"More than one ?var in #define");
721 else if ( *s ==
'?' && first ) {
724 else { *t++ = *s++; }
735 if ( u ) M_free(u,
"replace PreVar value");
744 VOID PopPreVars(
int tonumber)
746 PREVAR *p = &(PreVar[NumPre]);
747 while ( NumPre > tonumber ) {
749 M_free(p->
name,
"popping PreVar");
759 VOID IniModule(
int type)
763 CBUF *C = cbuf+AC.cbufnum;
777 AR.StoreData.dirtyflag = 0;
778 AC.bracketindexflag = 0;
779 AT.bracketindexflag = 0;
784 AC.RhsExprInModuleFlag = 0;
787 PF.slavebuf.PObuffer=NULL;
788 for(i=0; i<NumExpressions; i++)
789 Expressions[i].vflags &= ~ISINRHS;
801 w = C->
rhs; i = C->maxrhs;
802 do { *w++ = 0; }
while ( --i > 0 );
805 w = C->
lhs; i = C->maxlhs;
806 do { *w++ = 0; }
while ( --i > 0 );
809 C->numlhs = C->numrhs = 0;
810 ClearTree(AC.cbufnum);
811 while ( AC.NumLabels > 0 ) {
813 if ( AC.LabelNames[AC.NumLabels] ) M_free(AC.LabelNames[AC.NumLabels],
"LabelName");
818 AC.Commercial[0] = 0;
820 AC.IfStack = AC.IfHeap;
828 AC.MustTestTable = 0;
833 AC.SymChangeFlag = 0;
834 AP.lhdollarerror = 0;
835 AR.PolyFun = AC.lPolyFun;
836 AR.PolyFunInv = AC.lPolyFunInv;
837 AR.PolyFunType = AC.lPolyFunType;
838 AR.PolyFunExp = AC.lPolyFunExp;
839 AR.PolyFunVar = AC.lPolyFunVar;
840 AR.PolyFunPow = AC.lPolyFunPow;
841 AC.mparallelflag = AC.parallelflag | AM.hparallelflag;
842 AC.inparallelflag = 0;
843 AC.mProcessBucketSize = AC.ProcessBucketSize;
844 NumPotModdollars = 0;
845 AC.topolynomialflag = 0;
847 if ( AM.totalnumberofthreads > 1 ) AS.MultiThreaded = 1;
848 else AS.MultiThreaded = 0;
849 for ( i = 1; i < AM.totalnumberofthreads; i++ ) {
850 AB[i]->T.S0->PolyWise = 0;
861 VOID IniSpecialModule(
int type)
873 int moduletype = FIRSTMODULE;
875 int error1 = 0, error2 = 0, retcode, numstatement, retval;
877 AP.StopWatchZero = GetRunningTime();
879 AP.PreContinuation = 0;
880 AP.PreAssignLevel = 0;
882 AC.iPointer = AC.iBuffer;
885 if ( AC.CheckpointFlag == -1 )
DoRecovery(&moduletype);
886 AC.CheckpointStamp = Timer(0);
891 IniModule(moduletype);
897 NumToStr(buf,AC.CModule);
901 if ( specialtype ) IniSpecialModule(specialtype);
906 if ( c == AP.ComChar ) {
908 if ( AC.CurrentStream->FoldName ) {
910 if ( *t && t[1] && t[2] ==
'#' && t[3] ==
']' ) {
912 while ( *t ==
' ' || *t ==
'\t' ) t++;
913 s = AC.CurrentStream->FoldName;
914 while ( *s == *t ) { s++; t++; }
915 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t'
917 while ( *t ==
' ' || *t ==
'\t' ) t++;
919 AC.CurrentStream = CloseStream(AC.CurrentStream);
927 while ( c ==
' ' || c ==
'\t' ) c = GetChar(0);
928 if ( c == LINEFEED )
continue;
929 if ( c == ENDOFINPUT ) {
931 Warning(
".end instruction generated");
932 moduletype = ENDMODULE; specialtype = 0;
936 if ( PreProInstruction() ) { error1++; error2++; AP.preError++; }
939 else if ( c ==
'.' ) {
940 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
941 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
945 if ( ModuleInstruction(&moduletype,&specialtype) ) { error2++; AP.preError++; }
946 if ( specialtype ) SetSpecialMode(moduletype,specialtype);
947 if ( AP.PreInsideLevel != 0 ) {
948 MesPrint(
"@end of module instructions may not be used inside");
949 MesPrint(
"@the scope of a %#inside %#endinside construction.");
952 if ( AC.RepLevel > 0 ) {
953 MesPrint(
"&EndRepeat statement(s) missing");
954 error2++; AP.preError++;
956 if ( AC.tablecheck == 0 ) {
958 if ( TestTables() ) { error2++; AP.preError++; }
960 if ( AP.PreContinuation ) {
962 MesPrint(
"&Unfinished statement. Missing ;?");
964 if ( moduletype == GLOBALMODULE ) MakeGlobal();
966 endmodule:
if ( error2 == 0 && AM.qError == 0 ) {
967 retcode = ExecModule(moduletype);
969 if(PF.slavebuf.PObuffer!=NULL){
970 M_free(PF.slavebuf.PObuffer,
"PF inbuf");
971 PF.slavebuf.PObuffer=NULL;
975 if ( retcode < 0 ) error1++;
976 if ( retcode ) { error2++; AP.preError++; }
981 for ( j = 0, e = Expressions; j < NumExpressions; j++, e++ ) {
982 if ( e->replace == NEWLYDEFINEDEXPRESSION ) e->replace = REGULAREXPRESSION;
985 switch ( moduletype ) {
987 if ( ExecStore() ) error1++;
991 error1 = error2 = AP.preError = 0;
993 PutPreVar((UBYTE *)
"DATE_",(UBYTE *)MakeDate(),0,1);
995 if ( AM.resetTimeOnClear ) {
1002 AP.StopWatchZero = GetRunningTime();
1005 Terminate( -( error1 | error2 ) );
1010 if ( AC.exprfillwarning > 0 ) {
1011 AC.exprfillwarning = 0;
1013 if ( AC.CheckpointFlag && error1 == 0 && error2 == 0 )
DoCheckpoint(moduletype);
1017 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
1018 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
1024 if ( AP.PreContinuation ) {
1025 retval = LoadStatement(OLDSTATEMENT);
1029 AC.CurrentStream->prevline = AC.CurrentStream->linenumber;
1030 retval = LoadStatement(NEWSTATEMENT);
1034 if ( retval == -1 ) AP.PreContinuation = 0;
1035 else AP.PreContinuation = 1;
1038 else if ( retval > 0 ) AP.PreContinuation = 0;
1039 else AP.PreContinuation = 1;
1040 if ( error1 == 0 && !AP.PreContinuation ) {
1041 if ( ( AP.PreDebug & PREPROONLY ) == 0 ) {
1042 int onpmd = NumPotModdollars;
1044 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
1045 if ( AP.PreAssignFlag ) AC.RhsExprInModuleFlag = 0;
1047 if ( AP.PreOut || ( AP.PreDebug & DUMPTOCOMPILER )
1049 MesPrint(
" %s",AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1050 retcode = CompileStatement(AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1051 if ( retcode < 0 ) error1++;
1052 if ( retcode ) { error2++; AP.preError++; }
1053 if ( AP.PreAssignFlag ) {
1054 if ( retcode == 0 ) {
1055 if ( ( retcode = CatchDollar(0) ) < 0 ) error1++;
1056 else if ( retcode > 0 ) { error2++; AP.preError++; }
1058 else CatchDollar(-1);
1060 if ( AP.PreAssignLevel <=0 )
1061 AP.PreAssignFlag = 0;
1062 NumPotModdollars = onpmd;
1064 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
1069 MesPrint(
" %s",AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1072 else if ( !AP.PreContinuation ) {
1073 if ( AP.PreAssignLevel > 0 ) {
1075 if ( AP.PreAssignLevel <=0 )
1076 AP.PreAssignFlag = 0;
1092 int PreProInstruction()
1102 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
1104 if ( ( StrICmp(AP.preStart,(UBYTE *)
"case") == 0
1105 || StrICmp(AP.preStart,(UBYTE *)
"default") == 0 )
1106 && AP.PreSwitchModes[AP.PreSwitchLevel] == SEARCHINGPRECASE ) {
1109 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
1110 else { LoadInstruction(1); }
1112 else if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
1114 if ( ( StrICmp(AP.preStart,(UBYTE *)
"else") == 0
1115 || StrICmp(AP.preStart,(UBYTE *)
"elseif") == 0 )
1116 && AP.PreIfStack[AP.PreIfLevel] == LOOKINGFORELSE ) {
1119 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
1130 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1131 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1134 else if ( *t ==
'+' ) {
1135 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1136 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1139 else if ( *t ==
':' ) {}
1142 key = FindKeyWord(t,precommands,
sizeof(precommands)/
sizeof(
KEYWORD));
1150 MesPrint(
"@Unrecognized preprocessor instruction: %s",t);
1154 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
1157 while ( ( t[-1] ==
';' ) && ( t[-2] !=
'\\' ) ) {
1160 return((key->func)(s));
1180 int LoadInstruction(
int mode)
1182 UBYTE *s, *sstart, *t, c, cp;
1183 LONG position, fillpos = 0;
1184 int bralevel = 0, parlevel = 0, first = 1;
1189 if ( s[1] != LINEFEED && s[1] != ENDOFINPUT ) {
1192 else { oldmode = mode;
return(0); }
1194 else { s = AP.preStart; }
1197 if ( ( mode & 1 ) == 1 ) {
1198 if ( pushbackchar && ( mode == 3 || mode == 5 ) ) {
1199 c = pushbackchar; pushbackchar = 0;
1201 else c = GetInput();
1207 if ( mode == 2 && c ==
';' )
break;
1208 if ( ( mode == 1 || mode == 5 ) && c == LINEFEED )
break;
1209 if ( mode == 3 && FG.cTable[c] != 0 ) {
1212 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1213 *s++ =
'g'; *s++ =
'n'; *s++ =
' '; *s = 0;
1215 AP.preFill = s; *s++ = 0; *s = c;
1219 if ( mode == 0 && first ) {
1221 dodollar: s = sstart;
1222 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1223 *s++ =
'g'; *s++ =
'n'; *s = 0;
1228 if ( c ==
' ' || c ==
'\t' || c ==
',' ) {}
1231 else if ( mode == 1 && first && c ==
'$' && oldmode == 3 )
goto dodollar;
1232 if ( c == ENDOFINPUT || ( c == LINEFEED
1234 && quotelevel == 0 ) ) {
1235 if ( mode == 2 && c == ENDOFINPUT ) {
1236 MesPrint(
"@Unexpected end of instruction");
1247 if ( mode != 2 )
break;
1251 if ( ( mode == 1 ) || ( mode == 5 ) ) c = GetInput();
1255 if ( c == ENDOFINPUT ) {
1256 MesPrint(
"@Unmatched \"");
1257 if ( mode == 2 && c == ENDOFINPUT ) {
1258 MesPrint(
"@Unexpected end of instruction");
1268 else if ( c == LINEFEED ) {}
1269 else if ( c ==
'"' ) { *s++ =
'\\'; }
1274 else if ( c ==
'"' ) {
1279 else if ( c ==
'\\' ) {
1280 if ( ( mode == 1 ) || ( mode == 5 ) ) cp = GetInput();
1284 if ( cp == LINEFEED )
continue;
1285 if ( mode != 2 || cp !=
';' ) *s++ = c;
1288 else if ( c ==
'"' ) {
1294 while ( FG.cTable[*t] <= 1 ) t++;
1296 if ( ( StrICmp(AP.preStart,(UBYTE *)
"define") == 0 )
1297 || ( StrICmp(AP.preStart,(UBYTE *)
"redefine") == 0 ) ) {
1299 oldstream = AC.CurrentStream;
1304 else if ( quotelevel == 0 && bralevel == 0 && c ==
'(' ) {
1306 while ( FG.cTable[*t] <= 1 ) t++;
1308 if ( ( parlevel == 0 )
1309 && ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 ) ) {
1311 oldstream = AC.CurrentStream;
1316 else if ( quotelevel == 0 && bralevel == 0 && c ==
')' ) {
1319 else if ( quotelevel == 0 && parlevel == 0 && c ==
'{' ) {
1321 while ( FG.cTable[*t] <= 1 ) t++;
1323 if ( ( bralevel == 0 )
1324 && ( ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 )
1325 || ( StrICmp(AP.preStart,(UBYTE *)
"do") == 0 ) ) ) {
1327 oldstream = AC.CurrentStream;
1332 else if ( quotelevel == 0 && parlevel == 0 && c ==
'}' ) {
1334 if ( bralevel < 0 ) {
1336 MesPrint(
"@Unmatched brackets");
1343 if ( s >= (AP.preStop-1) ) {
1345 position = s - AP.preStart;
1346 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1347 ppp = &(AP.preStart);
1348 if ( DoubleLList((VOID ***)ppp,&AP.pSize,
sizeof(UBYTE),
1349 "instruction buffer") ) { *s = 0; oldmode = mode;
return(-1); }
1350 AP.preStop = AP.preStart + AP.pSize-3;
1351 s = AP.preStart + position;
1352 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1359 if ( ExpandTripleDots(1) < 0 )
return(-1);
1378 int LoadStatement(
int type)
1381 int retval = 0, stringlevel = 0, newstatement = 0;
1382 if ( type == NEWSTATEMENT ) { AP.eat = 1; newstatement = 1;
1383 s = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; }
1384 else { s = AC.iPointer; *s = 0; c =
' ';
goto blank; }
1388 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1389 if ( stringlevel == 0 ) {
1390 if ( c == LINEFEED ) { retval = 0;
break; }
1392 if ( AP.eat < 0 ) s--;
1393 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1394 if ( c != LINEFEED ) UngetChar(c);
1401 if ( cp == LINEFEED )
continue;
1406 if ( stringlevel == 0 ) stringlevel = 1;
1407 else stringlevel = 0;
1410 else if ( stringlevel == 0 ) {
1411 if ( c ==
'\t' ) c =
' ';
1413 blank:
if ( newstatement < 0 ) newstatement = 0;
1414 if ( AP.eat && ( newstatement == 0 ) )
continue;
1417 if ( newstatement > 0 ) newstatement = -1;
1419 else if ( chartype[c] <= 3 ) {
1421 if ( newstatement < 0 ) newstatement = 0;
1423 else if ( c ==
',' ) {
1424 if ( newstatement > 0 ) {
1429 else if ( AP.eat == -2 ) { AP.eat = 1;
continue; }
1430 else {
goto doall; }
1433 doall:;
if ( AP.eat < 0 ) {
1434 if ( newstatement == 0 ) s--;
1435 else { newstatement = 0; }
1437 else if ( newstatement == 1 ) newstatement = 0;
1439 if ( c ==
'*' && s > AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] && s[-1] ==
'*' ) {
1445 if ( s >= AC.iStop ) {
1446 if ( !AP.iBufError ) {
1447 LONG position = s - AC.iBuffer;
1448 LONG position2 = AC.iPointer - AC.iBuffer;
1449 UBYTE **ppp = &(AC.iBuffer);
1450 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1451 ,
sizeof(UBYTE),
"statement buffer") ) {
1452 *s = 0; retval = -1; AP.iBufError = 1;
1454 AC.iPointer = AC.iBuffer + position2;
1455 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1456 s = AC.iBuffer + position;
1458 if ( AP.iBufError ) {
1461 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1463 if ( stringlevel > 0 ) stringlevel = 0;
1464 else stringlevel = 1;
1466 else if ( c == LINEFEED && !stringlevel ) { retval = -2;
break; }
1467 else if ( c ==
';' && !stringlevel ) {
1468 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1469 if ( c != LINEFEED ) UngetChar(c);
1473 else if ( c ==
'\\' ) c = GetChar(0);
1482 if ( stringlevel > 0 ) {
1483 MesPrint(
"@Unbalanced \". Runaway string");
1486 if ( retval == 1 ) {
1487 if ( ExpandTripleDots(0) < 0 ) retval = -1;
1497 static inline int IsSignChar(UBYTE c)
1499 return c ==
'+' || c ==
'-';
1502 static inline int IsAlphanumericChar(UBYTE c)
1504 return FG.cTable[c] == 0 || FG.cTable[c] == 1;
1507 static inline int CanParseSignedNumber(
const UBYTE *s)
1509 while ( IsSignChar(*s) ) s++;
1510 return FG.cTable[*s] == 1;
1513 int ExpandTripleDots(
int par)
1515 UBYTE *s, *s1, *s2, *n1, *n2, *t1, *t2, *startp, operator1, operator2, c, cc;
1516 UBYTE *nBuffer, *strngs, *Buffer, *Stop;
1517 LONG withquestion, x1, x2, y1, y2, number, inc, newsize, pow, fullsize;
1518 int i, error = 0, i1 ,i2, ii, *nums = 0;
1521 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1524 Buffer = AP.preStart; Stop = AP.preStop;
1526 s = Buffer;
while ( *s ) s++;
1527 fullsize = s - Buffer;
1528 if ( fullsize < 7 )
return(error);
1532 if ( *s !=
'.' || ( s[-1] !=
',' && FG.cTable[s[-1]] != 5 ) )
1534 if ( s[-1] ==
'%' || s[-1] ==
'^' || s[1] !=
'.' || s[2] !=
'.' )
1538 if ( *s != s[-4] && ( *s !=
'+' || s[-4] !=
'-' )
1539 && ( *s !=
'-' || s[-4] !=
'+' ) ) {
1540 MesPrint(
"&Improper operators for ...");
1545 if ( operator1 ==
':' ) operator1 =
'.';
1546 if ( operator2 ==
':' ) operator2 =
'.';
1556 if ( *s2 !=
'<' || *s1 !=
'>' ) {
1558 withquestion = ( *s1 ==
'?' ); s1--;
1559 while ( FG.cTable[*s1] == 1 && s1 >= Buffer ) s1--;
1561 if ( FG.cTable[*n1] != 1 ) {
1562 MesPrint(
"&No first number in ... operator");
1565 while ( FG.cTable[*s1] <= 1 && s1 >= Buffer ) s1--;
1571 while ( t1 < n1 && *t1 == *t2 ) { t1++; t2++; }
1573 if ( FG.cTable[*t2] != 1 ) {
1574 MesPrint(
"&No second number in ... operator");
1578 while ( FG.cTable[*t2] == 1 ) x2 = 10*x2 + *t2++ -
'0';
1580 while ( FG.cTable[*t1] == 1 ) x1 = 10*x1 + *t1++ -
'0';
1581 if ( withquestion != ( *t2 ==
'?' ) ) {
1582 MesPrint(
"&Improper use of ? in ... operator");
1583 if ( *t2 ==
'?' ) t2++;
1586 else if ( withquestion ) t2++;
1587 if ( FG.cTable[*t2] <= 2 ) {
1588 MesPrint(
"&Illegal object after ... construction");
1591 c = *n1; *n1 = 0; s = t2;
1592 if ( error )
continue;
1601 if ( x2 < x1 ) { number = x1-x2; inc = -1; y1 = x2; y2 = x1; }
1602 else { number = x2-x1; inc = 1; y1 = x1; y2 = x2; }
1603 newsize = (number+1)*(n1-s1)
1605 +(number+1)*(withquestion?1:0)
1608 for ( i = 1; i < 10; i++, pow *= 10 ) {
1609 if ( y1 >= pow ) newsize += number+1;
1610 else if ( y2 >= pow ) newsize += y2-pow+1;
1613 while ( Buffer+(fullsize+newsize-(s-s1)) >= Stop ) {
1614 LONG strpos = s1-Buffer;
1615 LONG endstr = n1-Buffer;
1616 LONG startq = startp - Buffer;
1617 LONG position = s - Buffer;
1620 LONG position2 = AC.iPointer - AC.iBuffer;
1621 ppp = &(AC.iBuffer);
1622 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1623 ,
sizeof(UBYTE),
"statement buffer") ) {
1626 AC.iPointer = AC.iBuffer + position2;
1627 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1628 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1632 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1633 ppp = &(AP.preStart);
1634 if ( DoubleLList((VOID ***)ppp,&AP.pSize,
sizeof(UBYTE),
1635 "instruction buffer") ) {
1638 AP.preStop = AP.preStart + AP.pSize-3;
1639 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1640 Buffer = AP.preStart; Stop = AP.preStop;
1642 s = Buffer + position;
1643 n1 = Buffer + endstr;
1644 s1 = Buffer + strpos;
1645 startp = Buffer + startq;
1653 if ( newsize > (s-s1) ) {
1654 t2 = Buffer + fullsize;
1655 t1 = t2 + (newsize - (s-s1));
1657 while ( t2 > s ) { *--t1 = *--t2; }
1659 else if ( newsize < (s-s1) ) {
1660 t1 = s1 + newsize; t2 = s; s = t1;
1661 while ( *t2 ) *t1++ = *t2++;
1664 for ( x1 += inc, t1 = startp; number > 0; number--, x1 += inc ) {
1666 cc = operator1; operator1 = operator2; operator2 = cc;
1667 t2 = s1;
while ( *t2 ) *t1++ = *t2++;
1670 *t1++ =
'0' + x2 % 10;
1674 while ( s2 > n2 ) { cc = *s2; *s2 = *n2; *n2++ = cc; s2--; }
1675 if ( withquestion ) *t1++ =
'?';
1677 fullsize += newsize - ( s - s1 );
1682 while ( s1 > Buffer ) {
1683 if ( *s1 ==
'<' )
break;
1688 if ( *t2 ==
'>' )
break;
1691 if ( *s1 !=
'<' || *t2 !=
'>' ) {
1692 MesPrint(
"&Illegal attempt to use ... operator");
1696 nums = (
int *)Malloc1((t1-s1)*2*(
sizeof(int)+
sizeof(UBYTE))
1698 strngs = (UBYTE *)(nums + 2*(t1-s1));
1699 n1 = s1; n2 = s2; ii = -1; i = 0;
1701 while ( n1 < t1 || n2 < t2 ) {
1703 if ( CanParseSignedNumber(n1) && CanParseSignedNumber(n2) ) {
1712 int sign1 = IsSignChar(*n1);
1713 int sign2 = IsSignChar(*n2);
1714 int inword1 = s1 < n1 && IsAlphanumericChar(n1[-1]);
1715 int inword2 = s2 < n2 && IsAlphanumericChar(n2[-1]);
1716 if ( ( sign1 ^ sign2 ) && ( inword1 || inword2 ) )
break;
1717 if ( sign1 || sign2 ) {
1722 if ( *n1 == *n2 ) { *s++ = *n1++; n2++;
continue; }
1725 ParseSignedNumber(x1,n1)
1726 ParseSignedNumber(x2,n2)
1728 if ( s != strngs && ( s[-1] ==
'+' || s[-1] ==
'-' ) ) {
1738 nums[2*i] = x1; nums[2*i+1] = x2;
1742 if ( n1 < t1 || n2 < t2 ) {
1743 MesPrint(
"&Improper use of ... operator.");
1744 theend: M_free(nums,
"Expand ...");
1748 if ( i == 0 ) ii = 0;
1750 ii = nums[0] - nums[1];
1751 if ( ii < 0 ) ii = -ii;
1752 for ( x1 = 1; x1 < i; x1++ ) {
1753 x2 = nums[2*x1]-nums[2*x1+1];
1754 if ( x2 < 0 ) x2 = -x2;
1756 MesPrint(
"&Improper synchronization of numbers in ... operator");
1771 x2 = s - strngs - i;
1772 for ( i1 = 0; i1 < i; i1++ ) {
1775 if ( i2 < 0 ) i2 = -i2;
1776 if ( x1 < 0 ) x1 = -x1;
1777 if ( x1 > i2 ) i2 = x1;
1779 while ( i2 > 0 ) { i2 /= 10; x1++; }
1785 x2 +=
sizeof(UBYTE *);
1786 x2 = x2 - (x2 & (
sizeof(UBYTE *)-1));
1788 nBuffer = (UBYTE *)Malloc1(x2,
"input buffer");
1789 n1 = nBuffer; s = Buffer; s1--;
1790 while ( s < s1 ) *n1++ = *s++;
1798 if ( ( ( n1 > nBuffer ) && ( ( FG.cTable[n1[-1]] <= 1 )
1799 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1800 ( ( FG.cTable[strngs[0]] <= 1 ) || ( strngs[0] ==
'[' )
1801 || ( strngs[0] ==
'_' ) ) ) *n1++ =
',';
1803 for ( i1 = 0; i1 < ii; i1++ ) {
1804 s = strngs;
while ( *s ) *n1++ = *s++;
1805 for ( i2 = 0; i2 < i; i2++ ) {
1806 if ( n1 > nBuffer && IsSignChar(n1[-1]) ) {
1809 if ( nums[2*i2] >= 0 ) {
1813 n1 = NumCopy((WORD)(nums[2*i2]),n1);
1814 if ( nums[2*i2] > nums[2*i2+1] ) nums[2*i2]--;
1816 s++;
while ( *s ) *n1++ = *s++;
1818 if ( ( i1 & 1 ) == 0 ) *n1++ = operator1;
1819 else *n1++ = operator2;
1822 s = t2 + 1; n2 = n1;
1826 if ( ( ( ( FG.cTable[n1[-1]] <= 1 )
1827 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1828 ( ( FG.cTable[s[0]] <= 1 ) || ( s[0] ==
'[' )
1829 || ( s[0] ==
'_' ) ) ) *n1++ =
',';
1831 while ( *s ) *n1++ = *s++;
1834 LONG nnn1 = n1-nBuffer;
1835 LONG nnn2 = n2-nBuffer;
1837 while ( AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] + x2 >= AC.iStop ) {
1838 LONG position = s-Buffer;
1839 LONG position2 = AC.iPointer - AC.iBuffer;
1841 ppp = &(AC.iBuffer);
1842 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1843 ,
sizeof(UBYTE),
"statement buffer") ) {
1846 AC.iPointer = AC.iBuffer + position2;
1847 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1848 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1849 s = Buffer + position;
1854 for ( nnn3 = 0; nnn3 < nnn1; nnn3++ ) Buffer[nnn3] = nBuffer[nnn3];
1858 M_free(nBuffer,
"input buffer");
1859 M_free(nums,
"Expand ...");
1862 AP.preStop = nBuffer + x2 - 2;
1864 M_free(AP.preStart,
"input buffer");
1865 M_free(nums,
"Expand ...");
1866 AP.preStart = nBuffer;
1867 Buffer = AP.preStart; Stop = AP.preStop;
1869 fullsize = n1 - Buffer;
1887 while ( hi >= low ) {
1889 s1 = (UBYTE *)(table[med].name);
1891 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1897 FG.cTable[*s2] != 0 && FG.cTable[*s2] != 1
1901 if ( tolower(*s2) > tolower(*s1) ) low = med+1;
1916 for ( i = 0; i < size; i++ ) {
1917 s1 = (UBYTE *)(table[i].name);
1919 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1920 if ( *s2 == 0 || *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' )
1944 UBYTE *name, *value, *valpoin, *args = 0, c;
1945 if ( ( mode & 2 ) == 0 ) {
1946 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
1947 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
1949 else { mode &= ~2; }
1951 if ( chartype[*s] != 0 )
goto illname;
1953 while ( chartype[*s] <= 1 ) s++;
1955 while ( *s ==
' ' || *s ==
'\t' ) s++;
1958 if (
PutPreVar(name,(UBYTE *)
"1",0,mode) < 0 )
return(-1);
1964 if ( chartype[*s] != 0 )
goto illarg;
1966 while ( chartype[*s] <= 1 ) s++;
1967 while ( *s ==
' ' || *s ==
'\t' ) s++;
1968 if ( *s ==
')' )
break;
1969 if ( *s !=
',' )
goto illargs;
1971 while ( *s ==
' ' || *s ==
'\t' ) s++;
1974 while ( *s ==
' ' || *s ==
'\t' ) s++;
1978 s++; valpoin = value = s;
1979 while ( *s !=
'"' ) {
1981 if ( s[1] ==
'n' ) { *valpoin++ = LINEFEED; s += 2; }
1982 else if ( s[1] ==
'"' ) { *valpoin++ =
'"'; s += 2; }
1983 else if ( s[1] == 0 )
goto illval;
1984 else { *valpoin++ = *s++; *valpoin++ = *s++; }
1986 else *valpoin++ = *s++;
1989 if (
PutPreVar(name,value,args,mode) < 0 )
return(-1);
1992 MesPrint(
"@Illegal string for preprocessor variable %s. Forgotten double quotes (\") ?",name);
1997 MesPrint(
"@Illegally formed name of preprocessor variable");
2000 MesPrint(
"@Illegally formed name of argument of preprocessor definition");
2003 MesPrint(
"@Illegally formed arguments of preprocessor definition");
2006 MesPrint(
"@Illegal valpoin for preprocessor variable %s",name);
2015 int DoCommentChar(UBYTE *s)
2018 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2019 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2020 while ( *s ==
' ' || *s ==
'\t' ) s++;
2021 if ( *s == 0 || *s ==
'\n' ) {
2022 MesPrint(
"@No valid comment character specified");
2026 while ( *s ==
' ' || *s ==
'\t' ) s++;
2027 if ( *s != 0 && *s !=
'\n' ) {
2028 MesPrint(
"@Comment character should be a single valid character");
2046 int DoPreAssign(UBYTE *s)
2049 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
2052 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
2056 MesPrint(
"@Illegal characters in %#assign instruction");
2060 AP.PreAssignFlag = 1;
2077 int DoDefine(UBYTE *s)
2087 int DoRedefine(UBYTE *s)
2099 int ClearMacro(UBYTE *name)
2104 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2105 if ( StrCmp(name,p->
name) == 0 )
break;
2107 if ( i < 0 )
return(-1);
2108 if ( p->
nargs <= 0 )
return(0);
2110 for ( i = 0; i < p->
nargs; i++ ) {
2127 int TheUndefine(UBYTE *name)
2129 int i, inum, error = 0;
2131 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2132 if ( StrCmp(name,p->
name) == 0 ) {
2133 M_free(p->
name,
"undefining PreVar");
2136 while ( i < NumPre ) {
2143 CBUF *CC = cbuf + AC.cbufnum;
2145 for ( j = 1; j <= CC->numlhs; j++ ) {
2146 if ( CC->
lhs[j][0] == TYPEREDEFPRE ) {
2147 if ( CC->
lhs[j][2] > inum ) CC->
lhs[j][2]--;
2148 else if ( CC->
lhs[j][2] == inum ) {
2149 for ( k = inum - 1; k >= 0; k-- )
2150 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2151 if ( k >= 0 ) CC->
lhs[j][2] = k;
2153 MesPrint(
"@Conflict between undefining a preprocessor variable and a redefine statement");
2160 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2161 if ( AC.pfirstnum[j] > inum ) AC.pfirstnum[j]--;
2162 else if ( AC.pfirstnum[j] == inum ) {
2163 for ( k = inum - 1; k >= 0; k-- )
2164 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2165 if ( k >= 0 ) AC.pfirstnum[j] = k;
2181 int DoUndefine(UBYTE *s)
2184 int error = 0, retval;
2189 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2190 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2192 if ( chartype[*s] != 0 )
goto illname;
2194 while ( chartype[*s] <= 1 ) s++;
2196 if ( *s && *s !=
' ' && *s !=
'\t' )
goto illname;
2197 while ( *s ==
' ' || *s ==
'\t' ) s++;
2199 MesPrint(
"@Undefine should just have a variable name");
2203 if ( ( retval = TheUndefine(name) ) != 0 ) {
2204 if ( error == 0 )
return(retval);
2205 if ( error > 0 ) error = retval;
2224 MesPrint(
"@Illegally formed name of preprocessor variable");
2233 int DoInclude(UBYTE *s) {
return(Include(s,FILESTREAM)); }
2240 int DoReverseInclude(UBYTE *s) {
return(Include(s,REVERSEFILESTREAM)); }
2247 int Include(UBYTE *s,
int type)
2249 UBYTE *name = s, *fold, *t, c, c1 = 0, c2 = 0, c3 = 0;
2250 int str1offset, withnolist = AC.NoShowInput;
2251 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2252 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2253 if ( *s ==
'-' || *s ==
'+' ) {
2254 if ( *s ==
'-' ) withnolist = 1;
2255 else withnolist = 0;
2257 while ( *s ==
' ' || *s ==
'\t' ) s++;
2261 while ( *s && *s !=
'"' ) {
2262 if ( *s ==
'\\' ) s++;
2268 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2269 if ( *s ==
'\\' ) s++;
2274 while ( *s ==
' ' || *s ==
'\t' ) s++;
2278 while ( *s ==
' ' || *s ==
'\t' ) s++;
2281 MesPrint(
"@Empty fold name");
2285 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2286 if ( *s ==
'\\' ) s++;
2290 while ( *s ==
' ' || *s ==
'\t' ) s++;
2298 else if ( *s == 0 ) {
2302 MesPrint(
"@Improper syntax for file name");
2307 fold = strDup1(fold,
"foldname");
2312 if ( OpenStream(name,type,0,PRENOACTION) == 0 ) {
2313 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2319 LONG linenum = 0, prevline = 0;
2320 name = strDup1(name,
"name of include file");
2321 AC.CurrentStream->FoldName = strDup1(fold,
"name of fold");
2324 c = GetFromStream(AC.CurrentStream);
2325 if ( c == ENDOFSTREAM ) {
2326 AC.CurrentStream = CloseStream(AC.CurrentStream);
2329 if ( c == AP.ComChar ) {
2330 str1offset = AC.CurrentStream-AC.Streams;
2332 if ( AC.CurrentStream != str1offset+AC.Streams ) {
2337 if ( t[2] ==
'#' && ( ( t[3] ==
'[' && !foldopen )
2338 || ( t[3] ==
']' && foldopen ) ) ) {
2340 while ( *t ==
' ' || *t ==
'\t' ) t++;
2341 s = AC.CurrentStream->FoldName;
2342 while ( *s == *t ) { s++; t++; }
2343 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t'
2345 while ( *t ==
' ' || *t ==
'\t' ) t++;
2347 if ( foldopen == 0 ) {
2349 position = GetStreamPosition(AC.CurrentStream);
2350 linenum = AC.CurrentStream->linenumber;
2351 prevline = AC.CurrentStream->prevline;
2352 c3 = AC.CurrentStream->isnextchar;
2353 c1 = AC.CurrentStream->nextchar[0];
2354 c2 = AC.CurrentStream->nextchar[1];
2358 PositionStream(AC.CurrentStream,position);
2359 AC.CurrentStream->linenumber = linenum;
2360 AC.CurrentStream->prevline = prevline;
2361 AC.CurrentStream->eqnum = 1;
2363 AC.CurrentStream->isnextchar = c3;
2364 AC.CurrentStream->nextchar[0] = c1;
2365 AC.CurrentStream->nextchar[1] = c2;
2374 while ( c != LINEFEED && c != ENDOFSTREAM ) {
2375 c = GetFromStream(AC.CurrentStream);
2376 if ( c == ENDOFSTREAM ) {
2377 AC.CurrentStream = CloseStream(AC.CurrentStream);
2382 if ( c == ENDOFSTREAM ) {
2384 MesPrint(
"@Cannot find fold %s in file %s",fold,name);
2387 M_free(name,
"name of include file");
2391 M_free(name,
"name of include file");
2393 AC.NoShowInput = withnolist;
2394 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2408 int DoPreExchange(UBYTE *s)
2413 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2414 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2415 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2417 s++; s1 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2418 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2420 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2421 if ( *s !=
'$' )
goto syntax;
2422 s++; s2 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2423 if ( *s != 0 && *s !=
';' )
goto syntax;
2425 if ( ( num1 = GetDollar(s1) ) <= 0 ) {
2426 MesPrint(
"@$%s has not been defined (yet)",s1);
2429 if ( ( num2 = GetDollar(s2) ) <= 0 ) {
2430 MesPrint(
"@$%s has not been defined (yet)",s2);
2434 ExchangeDollars((
int)num1,(
int)num2);
2438 s1 = s; s = SkipAName(s);
2439 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2441 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2442 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
2443 s2 = s; s = SkipAName(s);
2444 if ( *s != 0 && *s !=
';' )
goto syntax;
2446 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
2447 MesPrint(
"@%s is not an expression",s1);
2450 if ( GetName(AC.exprnames,s2,&num2,NOAUTO) != CEXPRESSION ) {
2451 MesPrint(
"@%s is not an expression",s2);
2455 ExchangeExpressions((
int)num1,(
int)num2);
2460 MesPrint(
"@Proper syntax: %#exchange expr1,expr2 or %#exchange $var1,$var2");
2469 int DoCall(UBYTE *s)
2471 UBYTE *t, *u, *v, *name, c, cp, *args1, *args2, *t1, *t2, *wild = 0;
2472 int bratype = 0, wildargs = 0, inwildargs = 0, nwildargs = 0;
2475 int i, namesize, narg1, narg2, bralevel, numpre;
2477 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2478 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2483 name = s; s = EndOfToken(s); c = *s; *s = 0;
2484 for ( i = NumProcedures-1; i >= 0; i-- ) {
2485 if ( StrCmp(Procedures[i].name,name) == 0 )
break;
2487 p = (
PROCEDURE *)FromList(&AP.ProcList);
2491 while ( *t ) { t++; namesize++; }
2492 t = AP.procedureExtension;
2493 while ( *t ) { t++; namesize++; }
2494 t = p->name = (UBYTE *)Malloc1(namesize+2,
"procedure");
2496 while ( *u ) *t++ = *u++;
2498 v = AP.procedureExtension;
2499 while ( *v ) *t++ = *v++;
2502 p->p.buffer = LoadInputFile(p->name,PROCEDUREFILE);
2503 if ( p->p.buffer == 0 )
return(-1);
2507 p->p.buffer = Procedures[i].p.buffer;
2508 p->name = Procedures[i].name;
2513 if ( *t++ != '
#' ) goto wrongfile;
2519 if ( StrCmp(t,name) != 0 ) goto wrongfile;
2527 bralevel = narg1 = narg2 = 0; args2 = u;
2532 while ( *u != ')' ) {
2533 if ( *u ==
'?' ) { wildargs++; u++; nwildargs = narg2+1; }
2534 narg2++; u = EndOfToken(u); SKIPBLANKS(u)
2535 if ( *u == ',' ) { u++; SKIPBLANKS(u) }
2536 else if ( *u !=
')' || ( wildargs > 1 ) ) {
2537 MesPrint(
"@Illegal argument field in procedure %s",p->name);
2542 while ( *u != LINEFEED ) u++;
2545 if ( *s == '(' ) bratype = 1;
2547 if ( *s ==
'{' && bratype == 0 ) bralevel++;
2548 else if ( *s ==
'(' && bratype == 1 ) bralevel++;
2549 else if ( *s ==
'}' && bratype == 0 ) {
2551 if ( bralevel == 0 ) {
2553 if ( wildargs && narg1 == nwildargs ) wild = s;
2556 else if ( *s ==
')' && bratype == 1 ) {
2558 if ( bralevel == 0 ) {
2560 if ( wildargs && narg1 == nwildargs ) wild = s;
2565 else if (set_in(*s,AC.separators)) {
2569 if ( wildargs && narg1 == nwildargs ) wild = s;
2571 else if ( *s ==
'\\' ) s++;
2573 }
while ( bralevel > 0 );
2574 if ( wildargs && narg1 >= narg2-1 ) {
2575 inwildargs = narg1-narg2+1;
2576 if ( inwildargs == 0 ) nwildargs = 0;
2578 while ( inwildargs > 1 ) {
2580 while ( *wild ) wild++;
2585 else if ( narg1 != narg2 && ( narg2 != 0 || narg1 != 1 || *args1 != 0 ) ) {
2586 MesPrint(
"@Arguments of procedure %s are not matching",p->name);
2590 for ( i = 0; i < narg2; i++ ) {
2595 if ( *t ==
'?' && inwildargs == 0 ) {
2596 args2 = EndOfToken(args2); c = *args2; *args2 = 0;
2597 if (
PutPreVar(t,(UBYTE *)
"",0,0) < 0 )
return(-1);
2600 args2 = EndOfToken(args2); c = *args2; *args2 = 0;
2603 if ( *t1 ==
'\\' ) t1++;
2604 if ( t1 != t2 ) *t2 = *t1;
2608 if (
PutPreVar(t,args1,0,0) < 0 )
return(-1);
2611 *args2 = c; SKIPBLANKS(args2)
2612 args2++; SKIPBLANKS(args2)
2614 streamoffset = AC.CurrentStream - AC.Streams;
2615 args1 = AC.CurrentStream->name;
2616 AC.CurrentStream->name = p->name;
2617 i1 = AC.CurrentStream->linenumber;
2618 i2 = AC.CurrentStream->prevline;
2619 AC.CurrentStream->prevline =
2620 AC.CurrentStream->linenumber = 2;
2621 OpenStream(u+1,PREREADSTREAM3,numpre,PRENOACTION);
2622 AC.Streams[streamoffset].name = args1;
2623 AC.Streams[streamoffset].linenumber = i1;
2624 AC.Streams[streamoffset].prevline = i2;
2625 AddToPreTypes(PRETYPEPROCEDURE);
2628 if ( i < 0 ) MesPrint("@File %s is not a proper procedure",p->name);
2629 else MesPrint("!!!Internal error with procedure names: %s",name);
2638 int DoDebug(UBYTE *s)
2641 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2642 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2643 NeedNumber(x,s,nonumber)
2644 if ( x < 0 || x >(PREPROONLY
2655 if ( ( x & PREPROONLY ) != 0 ) AP.PreDebug |= PREPROONLY;
2656 if ( ( x & DUMPTOCOMPILER ) != 0 ) AP.PreDebug |= DUMPTOCOMPILER;
2657 if ( ( x & DUMPOUTTERMS ) != 0 ) AP.PreDebug |= DUMPOUTTERMS;
2658 if ( ( x & DUMPINTERMS ) != 0 ) AP.PreDebug |= DUMPINTERMS;
2659 if ( ( x & DUMPTOSORT ) != 0 ) AP.PreDebug |= DUMPTOSORT;
2660 if ( ( x & DUMPTOPARALLEL ) != 0 ) AP.PreDebug |= DUMPTOPARALLEL;
2662 if ( ( x & THREADSDEBUG ) != 0 ) AP.PreDebug |= THREADSDEBUG;
2666 MesPrint(
"@Illegal argument for debug instruction");
2675 int DoTerminate(UBYTE *s)
2678 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2679 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2681 NeedNumber(x,s,nonumber)
2689 MesPrint(
"@Illegal argument for terminate instruction");
2707 UBYTE *t, c, *u, *uu;
2710 LONG linenum = AC.CurrentStream->linenumber;
2711 int oldNoShowInput = AC.NoShowInput, i, oldpreassignflag;
2713 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
2714 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
2715 if ( PreSkip((UBYTE *)
"do",(UBYTE *)
"enddo",1) )
return(-1);
2723 AddToPreTypes(PRETYPEDO);
2725 loop = (
DOLOOP *)FromList(&AP.LoopList);
2726 loop->firstdollar = loop->lastdollar = loop->incdollar = -1;
2727 loop->NumPreTypes = AP.NumPreTypes-1;
2728 loop->PreIfLevel = AP.PreIfLevel;
2729 loop->PreSwitchLevel = AP.PreSwitchLevel;
2731 if ( PreLoad(&(loop->
p),(UBYTE *)
"do",(UBYTE *)
"enddo",1,
"doloop") )
return(-1);
2732 AC.NoShowInput = oldNoShowInput;
2733 loop->NoShowInput = AC.NoShowInput;
2737 s = loop->
p.buffer + (s - AP.preStart);
2740 if ( chartype[*s] != 0 ) goto illname;
2742 while ( chartype[*s] <= 1 ) s++;
2744 while ( *s == ' ' || *s == '\t' ) s++;
2745 if ( *s != '=' ) goto illdo;
2747 while ( *s == ' ' || *s == '\t' ) s++;
2751 loop->type = LISTEDLOOP;
2752 s++; loop->vars = s;
2754 while ( *s != '}
' && *s != 0 ) {
2755 if ( set_in(*s,AC.separators) ) { *s = 0; loop->lastnum++; }
2756 else if ( *s == '\\
' ) s++;
2759 if ( *s == 0 ) goto illdo;
2765 else if ( *s == '-
' || *s == '+
' || chartype[*s] == 1 || *s == '$
' ) {
2766 loop->type = NUMERICALLOOP;
2768 while ( *s && *s != ',
' ) s++;
2769 if ( *s == 0 ) goto illdo;
2772 if ( GetName(AC.dollarnames,t+1,&loop->firstdollar,NOAUTO) != CDOLLAR ) {
2773 MesPrint("@%s is undefined in first parameter in %#do instruction",t);
2776 loop->firstnum = DolToLong(BHEAD loop->firstdollar);
2777 if ( AN.ErrorInDollar ) {
2778 MesPrint("@%s does not evaluate into a valid loop parameter",t);
2785 if ( PreEval(t,&loop->firstnum) == 0 ) goto illdo;
2789 while ( *s && *s != ',
' && *s != ';
' && *s != LINEFEED ) s++;
2793 if ( GetName(AC.dollarnames,t+1,&loop->lastdollar,NOAUTO) != CDOLLAR ) {
2794 MesPrint("@%s is undefined in second parameter in %#do instruction",t);
2797 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
2798 if ( AN.ErrorInDollar ) {
2799 MesPrint("@%s does not evaluate into a valid loop parameter",t);
2806 if ( PreEval(t,&loop->lastnum) == 0 ) goto illdo;
2811 while ( *s && *s != ';
' && *s != LINEFEED ) s++;
2814 if ( GetName(AC.dollarnames,t+1,&loop->incdollar,NOAUTO) != CDOLLAR ) {
2815 MesPrint("@%s is undefined in third parameter in %#do instruction",t);
2818 loop->incnum = DolToLong(BHEAD loop->incdollar);
2819 if ( AN.ErrorInDollar ) {
2820 MesPrint("@%s does not evaluate into a valid loop parameter",t);
2827 if ( PreEval(t,&loop->incnum) == 0 ) goto illdo;
2831 else loop->incnum = 1;
2834 else if ( ( chartype[*s] == 0 ) || ( *s == '[
' ) ) {
2835 int oldNumPotModdollars = NumPotModdollars;
2837 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
2838 AC.RhsExprInModuleFlag = 0;
2841 if ( ( s = SkipAName(s) ) == 0 ) goto illdo;
2843 if ( GetName(AC.exprnames,t,&expnum,NOAUTO) == CEXPRESSION ) {
2844 loop->type = ONEEXPRESSION;
2846 We should remember the expression by name for when it gets
2847 renumbered!!! If it gets deleted there will be a crash or at
2848 least the loop terminates.
2853 if ( c == ',
' || c == '\t
' || c == ';
' ) { s++; }
2854 else if ( c != 0 && c != '\n
' ) goto illdo;
2855 while ( *s == ',
' || *s == '\t
' || *s == ';
' ) s++;
2856 if ( *s != 0 && *s != '\n
' ) goto illdo;
2862 Next determine size of statement and allocate space
2867 while ( *t ) { t++; i++; }
2869 loop->dollarname = Malloc1((LONG)i,"do-loop instruction");
2871 Construct the statement
2873 u = loop->dollarname;
2874 *u++ = '$
'; t = loop->name; while ( *t ) *u++ = *t++;
2875 *u++ = '_
'; uu = u; *u++ = '=
'; t = loop->vars;
2876 while ( *t ) *u++ = *t++;
2879 Compile and put in dollar variable.
2880 Note that we remember the dollar by name and that this name ends in _
2882 oldpreassignflag = AP.PreAssignFlag;
2883 AP.PreAssignFlag = 2;
2884 CompileStatement(loop->dollarname);
2885 if ( CatchDollar(0) ) {
2886 MesPrint("@Cannot load expression in do loop");
2889 AP.PreAssignFlag = oldpreassignflag;
2890 NumPotModdollars = oldNumPotModdollars;
2892 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
2896 else goto illdo; /* Syntax problems */
2897 loop->errorsinloop = 0;
2898 /* loop->startlinenumber = linenum+1; 5-oct-2000 One too much? */
2899 loop->startlinenumber = linenum;
2900 PutPreVar(loop->name,(UBYTE *)"0",0,0);
2901 loop->firstloopcall = 1;
2904 MesPrint("@Improper name for do loop variable");
2907 MesPrint("@Improper syntax in do loop instruction");
2916 jumps out of num #do-loops (if there are that many) (default is 1)
2919 int DoBreakDo(UBYTE *s)
2924 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
2925 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
2927 if ( NumDoLoops <= 0 ) {
2928 MesPrint("@%#dobreak without %#do");
2932 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO ) { MessPreNesting(4); return(-1); }
2934 while ( *s && ( *s == ',
' || *s == ' ' || *s == '\t
' ) ) s++;
2938 else if ( FG.cTable[*s] == 1 ) {
2940 while ( *s >= '0
' && *s <= '9
' ) { levels = 10*levels + *s++ - '0
'; }
2941 if ( *s != 0 ) goto improper;
2945 MesPrint("@Improper syntax of %#dobreak instruction");
2948 if ( levels > NumDoLoops ) {
2949 MesPrint("@Too many loop levels requested in %#breakdo instruction");
2952 while ( levels > 0 ) {
2953 while ( AC.CurrentStream->type != PREREADSTREAM
2954 && AC.CurrentStream->type != PREREADSTREAM2
2955 && AC.CurrentStream->type != PREREADSTREAM3 ) {
2956 AC.CurrentStream = CloseStream(AC.CurrentStream);
2958 while ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO
2959 && AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) AP.NumPreTypes--;
2960 if ( AC.CurrentStream->type == PREREADSTREAM3
2961 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
2962 MesPrint("@Trying to jump out of a procedure with a %#breakdo instruction");
2965 loop = &(DoLoops[NumDoLoops-1]);
2966 AP.NumPreTypes = loop->NumPreTypes;
2967 AP.PreIfLevel = loop->PreIfLevel;
2968 AP.PreSwitchLevel = loop->PreSwitchLevel;
2973 DoUndefine(loop->name);
2974 M_free(loop->p.buffer,"loop->p.buffer");
2975 loop->firstloopcall = 0;
2977 AC.CurrentStream = CloseStream(AC.CurrentStream);
2988 int DoElse(UBYTE *s)
2990 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
2991 if ( AP.PreIfLevel <= 0 ) MesPrint("@%#else without corresponding %#if");
2992 else MessPreNesting(1);
2995 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
2996 while ( *s == ' ' ) s++;
2997 if ( tolower(*s) == 'i
' && tolower(s[1]) == 'f
' && s[2]
2998 && FG.cTable[s[2]] > 1 && s[2] != '_
' ) {
3000 while ( *s == ' ' ) s++;
3001 return(DoElseif(s));
3003 if ( AP.PreIfLevel <= 0 ) {
3004 MesPrint("@%#else without corresponding %#if");
3007 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3009 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3011 case LOOKINGFORELSE:
3012 AP.PreIfStack[AP.PreIfLevel] = EXECUTINGIF;
3014 case LOOKINGFORENDIF:
3025 int DoElseif(UBYTE *s)
3028 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3029 if ( AP.PreIfLevel <= 0 ) MesPrint("@%#elseif without corresponding %#if");
3030 else MessPreNesting(2);
3033 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3034 if ( AP.PreIfLevel <= 0 ) {
3035 MesPrint("@%#elseif without corresponding %#if");
3038 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3040 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3042 case LOOKINGFORELSE:
3043 if ( ( condition = EvalPreIf(s) ) < 0 ) return(-1);
3044 AP.PreIfStack[AP.PreIfLevel] = condition;
3046 case LOOKINGFORENDIF:
3056 At the first call there is no stream yet.
3057 After that we have to close the stream and start a new one.
3060 int DoEnddo(UBYTE *s)
3064 UBYTE *t, *tt, *value, numstr[16];
3068 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3069 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3071 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ||
3072 AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
3073 if ( AP.PreTypes[AP.NumPreTypes] == PRETYPEDO ) AP.NumPreTypes--;
3074 else { MessPreNesting(3); return(-1); }
3078 if ( NumDoLoops <= 0 ) {
3079 MesPrint("@%#enddo without %#do");
3082 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO ) { MessPreNesting(4); return(-1); }
3083 loop = &(DoLoops[NumDoLoops-1]);
3084 if ( !loop->firstloopcall ) AC.CurrentStream = CloseStream(AC.CurrentStream);
3086 if ( loop->errorsinloop ) {
3087 MesPrint("++++Errors in Loop");
3090 if ( loop->type == LISTEDLOOP ) {
3091 if ( loop->firstnum >= loop->lastnum ) goto finish;
3093 t = value = loop->vars;
3094 while ( *value ) value++;
3099 if ( *value == '\\
' ) value++;
3103 PutPreVar(loop->name,t,0,1); /* We overwrite the definition */
3105 else if ( loop->type == NUMERICALLOOP ) {
3107 if ( !loop->firstloopcall ) {
3109 Test whether the variable was changed inside the loop into
3110 a different numerical value. If so, adjust.
3112 t = GetPreVar(loop->name,WITHOUTERROR);
3116 while ( *value && ( *value == ' '
3117 || *value == '-
' || *value == '+
' ) ) {
3118 if ( *value == '-
' ) xsign = -xsign;
3121 t = value; xval = 0;
3122 while ( *value >= '0
' && *value <= '9
' ) xval = 10*xval + *value++ - '0
';
3123 while ( *value && *value == ' ' ) value++;
3124 if ( *value == 0 ) {
3126 Now we may substitute the loopvalue.
3128 if ( xsign < 0 ) xval = -xval;
3129 if ( loop->incdollar >= 0 ) {
3130 loop->incnum = DolToLong(BHEAD loop->incdollar);
3131 if ( AN.ErrorInDollar ) {
3132 MesPrint("@%s does not evaluate into a valid third loop parameter",DOLLARNAME(Dollars,loop->incdollar));
3136 loop->firstnum = xval + loop->incnum;
3139 if ( loop->lastdollar >= 0 ) {
3140 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
3141 if ( AN.ErrorInDollar ) {
3142 MesPrint("@%s does not evaluate into a valid second loop parameter",DOLLARNAME(Dollars,loop->lastdollar));
3147 if ( ( loop->incnum > 0 && loop->firstnum > loop->lastnum )
3148 || ( loop->incnum < 0 && loop->firstnum < loop->lastnum ) ) goto finish;
3149 NumToStr(numstr,loop->firstnum);
3151 loop->firstnum += loop->incnum;
3152 PutPreVar(loop->name,t,0,1); /* We overwrite the definition */
3154 else if ( loop->type == ONEEXPRESSION ) {
3156 Find the dollar expression
3158 WORD numdollar = GetDollar(loop->dollarname+1);
3159 DOLLARS d = Dollars + numdollar;
3160 WORD *w, *dw, v, *ww;
3161 if ( (d->where) == 0 ) {
3162 d->type = DOLUNDEFINED;
3163 M_free(loop->dollarname,"do-loop instruction");
3166 w = d->where + loop->incnum;
3168 M_free(d->where,"dollar");
3170 d->type = DOLUNDEFINED;
3171 M_free(loop->dollarname,"do-loop instruction");
3176 Now the term has to be converted to text.
3178 ww = w + *w; v = *ww; *ww = 0;
3179 dw = d->where; d->where = w;
3180 t = WriteDollarToBuffer(numdollar,1);
3181 d->where = dw; *ww = v;
3182 PutPreVar(loop->name,t,0,1); /* We overwrite the definition */
3185 if ( loop->firstloopcall ) OpenStream(loop->contents,PREREADSTREAM2,0,PRENOACTION);
3186 else OpenStream(loop->contents,PREREADSTREAM,0,PRENOACTION);
3187 AC.CurrentStream->prevline =
3188 AC.CurrentStream->linenumber = loop->startlinenumber;
3189 AC.CurrentStream->eqnum = 0;
3190 loop->firstloopcall = 0;
3194 retval = DoUndefine(loop->name);
3195 M_free(loop->p.buffer,"loop->p.buffer");
3196 loop->firstloopcall = 0;
3206 int DoEndif(UBYTE *s)
3209 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3210 if ( AP.PreIfLevel <= 0 ) MesPrint("@%#endif without corresponding %#if");
3211 else MessPreNesting(5);
3215 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3216 if ( AP.PreIfLevel <= 0 ) {
3217 MesPrint("@%#endif without corresponding %#if");
3228 Action is simple: close the current stream if it is still
3229 the stream from which the statement came.
3230 Then pop the current procedure and all its local derivatives.
3231 if loadmode > 1 the procedure was defined locally.
3234 int DoEndprocedure(UBYTE *s)
3237 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) {
3242 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3243 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3244 AC.CurrentStream = CloseStream(AC.CurrentStream);
3247 if ( Procedures[NumProcedures].loadmode == 0 ) {
3248 M_free(Procedures[NumProcedures].p.buffer,"procedures buffer");
3249 M_free(Procedures[NumProcedures].name,"procedures name");
3251 } while ( Procedures[NumProcedures].loadmode > 1 );
3263 AddToPreTypes(PRETYPEIF);
3264 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3265 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3266 condition = EvalPreIf(s);
3267 if ( condition < 0 ) return(-1);
3269 else condition = LOOKINGFORENDIF;
3270 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3271 int **ppp = &AP.PreIfStack; /* To avoid a compiler warning */
3272 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,sizeof(int),
3273 "PreIfLevels") ) return(-1);
3275 AP.PreIfStack[++AP.PreIfLevel] = condition;
3284 int DoIfdef(UBYTE *s, int par)
3287 AddToPreTypes(PRETYPEIF);
3288 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3289 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3290 while ( *s == ' ' || *s == '\t
' ) s++;
3291 if ( ( *s == 0 ) == ( par == 1 ) ) condition = LOOKINGFORELSE;
3292 else condition = EXECUTINGIF;
3294 else condition = LOOKINGFORENDIF;
3295 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3296 int **ppp = &AP.PreIfStack; /* to avoid a compiler warning */
3297 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,sizeof(int),
3298 "PreIfLevels") ) return(-1);
3300 AP.PreIfStack[++AP.PreIfLevel] = condition;
3309 int DoIfydef(UBYTE *s)
3311 return DoIfdef(s,1);
3319 int DoIfndef(UBYTE *s)
3321 return DoIfdef(s,2);
3328 #inside $var1,...,$varn
3329 statements without .sort
3332 executes the statements on the contents of the $ variables as if they
3333 are a module. The results are put back in the dollar variables.
3334 To do this right we need a struct with
3336 list of numbers of dollars
3338 length of the array containing the list
3339 Because we need to compose statements, the statement buffer must be
3340 empty. This means that we have to test for that. Same at the end. We
3341 must have a completed statement.
3344 int DoInside(UBYTE *s)
3347 int numdol, error = 0;
3348 WORD *nb, newsize, i;
3350 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3351 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3352 if ( AP.PreInsideLevel != 0 ) {
3353 MesPrint("@Illegal nesting of %#inside/%#endinside instructions");
3357 if ( AP.PreContinuation ) {
3359 MesPrint("@%#inside cannot be inside a regular statement");
3364 Now the dollars to do
3366 AP.inside.numdollars = 0;
3368 while ( *s == ',
' || *s == ' ' || *s == '\t
' ) s++;
3369 if ( *s == 0 ) break;
3371 MesPrint("@%#inside instruction can have only $ variables for parameters");
3376 while (chartype[*s] <= 1 ) s++;
3378 if ( ( numdol = GetDollar(name) ) < 0 ) {
3379 MesPrint("@%#inside: $%s has not (yet) been defined",name);
3385 if ( AP.inside.numdollars >= AP.inside.size ) {
3386 if ( AP.inside.buffer == 0 ) newsize = 20;
3387 else newsize = 2*AP.inside.size;
3388 nb = (WORD *)Malloc1(newsize*sizeof(WORD),"insidebuffer");
3389 if ( AP.inside.buffer ) {
3390 for ( i = 0; i < AP.inside.size; i++ ) nb[i] = AP.inside.buffer[i];
3391 M_free(AP.inside.buffer,"insidebuffer");
3393 AP.inside.buffer = nb;
3394 AP.inside.size = newsize;
3396 AP.inside.buffer[AP.inside.numdollars++] = numdol;
3400 We have to store the configuration of the compiler buffer, so that
3401 we know where to start executing and how to reset the buffer.
3403 AP.inside.oldcompiletype = AC.compiletype;
3404 AP.inside.oldparallelflag = AC.mparallelflag;
3405 AP.inside.oldnumpotmoddollars = NumPotModdollars;
3406 AP.inside.oldcbuf = AC.cbufnum;
3407 AP.inside.oldrbuf = AM.rbufnum;
3408 AP.inside.oldcnumlhs = AR.Cnumlhs,
3409 AddToPreTypes(PRETYPEINSIDE);
3410 AP.PreInsideLevel = 1;
3411 AC.cbufnum = AP.inside.inscbuf;
3412 AM.rbufnum = AP.inside.inscbuf;
3413 clearcbuf(AC.cbufnum);
3415 AC.mparallelflag = PARALLELFLAG;
3418 * We use AC.RhsExprInModuleFlag, PotModdollars, and AC.pfirstnum
3419 * in order to check (1) whether there are expression names in RHS,
3420 * (2) which dollar variables can be modified, and (3) which
3421 * preprocessor variables can be redefined, in #inside.
3422 * We store the current values of them, and then reset them.
3424 PF_StoreInsideInfo();
3425 AC.RhsExprInModuleFlag = 0;
3426 NumPotModdollars = 0;
3427 AC.numpfirstnum = 0;
3437 int DoEndInside(UBYTE *s)
3440 WORD numdol, *oldworkpointer = AT.WorkPointer, *term, *t, j, i;
3442 WORD oldbracketon = AR.BracketOn;
3443 WORD *oldcompresspointer = AR.CompressPointer;
3444 int oldmultithreaded = AS.MultiThreaded;
3445 /* int oldmparallelflag = AC.mparallelflag; */
3451 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3452 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3453 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEINSIDE ) {
3454 if ( AP.PreInsideLevel != 1 ) MesPrint("@%#endinside without corresponding %#inside");
3455 else MessPreNesting(11);
3459 if ( AP.PreInsideLevel != 1 ) {
3460 MesPrint("@%#endinside without corresponding %#inside");
3463 if ( AP.PreContinuation ) {
3464 MesPrint("@%#endinside: previous statement not terminated.");
3467 AC.compiletype = AP.inside.oldcompiletype;
3468 AR.Cnumlhs = cbuf[AM.rbufnum].numlhs;
3471 * If the #inside...#endinside contains expressions in RHS, only the master executes it
3472 * and then broadcasts the result to the all slaves. If not, the all processes execute
3473 * it and in this case no MPI interactions are needed.
3475 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
3478 AS.MultiThreaded = 0;
3479 /* AC.mparallelflag = PARALLELFLAG; */
3480 if ( AR.CompressPointer == 0 ) AR.CompressPointer = AR.CompressBuffer;
3481 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3483 Now we have to execute the statements on the proper dollars.
3485 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3486 numdol = AP.inside.buffer[i];
3487 nd = d = Dollars + numdol;
3488 if ( d->type != DOLZERO ) {
3489 if ( d->type != DOLTERMS ) nd = DolToTerms(BHEAD numdol);
3493 AR.MaxDum = AM.IndDum;
3495 t = oldworkpointer; j = *term;
3498 AN.IndDum = AM.IndDum;
3499 AR.CurDum = ReNumber(BHEAD term);
3500 if ( Generator(BHEAD oldworkpointer,0) ) {
3501 MesPrint("@Called from %#endinside");
3502 MesPrint("@Evaluating variable $%s",DOLLARNAME(Dollars,numdol));
3506 AT.WorkPointer = oldworkpointer;
3507 CleanDollarFactors(d);
3508 if ( d->where ) { M_free(d->where,"dollar contents"); d->where = 0; }
3509 EndSort(BHEAD (WORD *)((VOID *)(&(d->where))),2);
3511 term = d->where; while ( *term ) term += *term;
3512 d->size = term - d->where;
3513 if ( nd != d ) M_free(nd,"Copy of dollar variable");
3514 if ( d->where[0] == 0 ) {
3515 M_free(d->where,"dollar contents"); d->where = 0;
3522 if ( AC.RhsExprInModuleFlag ) {
3524 * The only master executed the statements in #inside.
3525 * We need to broadcast the result to the all slaves.
3527 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3529 * Mark $-variables specified in the #inside instruction as modified
3530 * such that they will be broadcast.
3532 AddPotModdollar(AP.inside.buffer[i]);
3534 /* Now actual broadcast of modified variables. */
3535 if ( NumPotModdollars > 0 ) {
3536 error = PF_BroadcastModifiedDollars();
3537 if ( error ) goto cleanup;
3539 if ( AC.numpfirstnum > 0 ) {
3540 error = PF_BroadcastRedefinedPreVars();
3541 if ( error ) goto cleanup;
3546 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3547 AC.cbufnum = AP.inside.oldcbuf;
3548 AM.rbufnum = AP.inside.oldrbuf;
3549 AR.Cnumlhs = AP.inside.oldcnumlhs;
3550 AR.BracketOn = oldbracketon;
3551 AP.PreInsideLevel = 0;
3552 AR.CompressPointer = oldcompresspointer;
3553 AS.MultiThreaded = oldmultithreaded;
3554 AC.mparallelflag = AP.inside.oldparallelflag;
3555 NumPotModdollars = AP.inside.oldnumpotmoddollars;
3558 PF_RestoreInsideInfo();
3559 if ( error ) return error;
3569 int DoMessage(UBYTE *s)
3571 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3572 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3573 while ( *s == ' ' || *s == '\t
' ) s++;
3574 MesPrint("~~~%s",s);
3583 int DoPipe(UBYTE *s)
3588 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3589 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3592 while ( *s == ' ' || *s == '\t
' ) s++;
3593 if ( OpenStream(s,PIPESTREAM,0,PRENOACTION) == 0 ) return(-1);
3596 Error0("Pipes not implemented on this computer/system");
3606 int DoPrcExtension(UBYTE *s)
3609 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3610 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3611 while ( *s == ' ' || *s == '\t
' ) s++;
3612 if ( *s == 0 || *s == '\n
' ) {
3613 MesPrint("@No valid procedure extension specified");
3616 if ( FG.cTable[*s] != 0 ) {
3617 MesPrint("@Procedure extension should be a string starting with an alphabetic character. No whitespace.");
3621 while ( *s && *s != '\n
' && *s != ' ' && *s != '\t
' ) s++;
3623 while ( *s == ' ' || *s == '\t
' ) s++;
3624 if ( *s != 0 && *s != '\n
' ) {
3625 MesPrint("@Too many parameters in ProcedureExtension instruction");
3629 if ( AP.procedureExtension ) M_free(AP.procedureExtension,"ProcedureExtension");
3630 AP.procedureExtension = strDup1(t,"ProcedureExtension");
3640 int DoPreOut(UBYTE *s)
3642 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3643 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3644 if ( tolower(*s) == 'o
' ) {
3645 if ( tolower(s[1]) == 'n
' && s[2] == 0 ) {
3649 if ( tolower(s[1]) == 'f
' && tolower(s[2]) == 'f
' && s[3] == 0 ) {
3654 MesPrint("@Illegal option in PreOut instruction");
3660 #[ DoPrePrintTimes :
3663 int DoPrePrintTimes(UBYTE *s)
3666 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3667 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3673 #] DoPrePrintTimes :
3680 int DoPreAppend(UBYTE *s)
3684 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3685 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3686 if ( AP.preError ) return(0);
3687 while ( *s == ' ' || *s == '\t
' ) s++;
3689 Determine where to write
3694 while ( *s && *s != '>
' ) {
3695 if ( *s == '\\
' ) s++;
3699 MesPrint("@Improper termination of filename");
3704 if ( *name ) { GetAppendChannel((char *)name); }
3709 MesPrint("@Proper syntax is: %#append <filename>");
3723 int DoPreCreate(UBYTE *s)
3727 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3728 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3729 if ( AP.preError ) return(0);
3730 while ( *s == ' ' || *s == '\t
' ) s++;
3732 Determine where to write
3737 while ( *s && *s != '>
' ) {
3738 if ( *s == '\\
' ) s++;
3742 MesPrint("@Improper termination of filename");
3747 if ( *name ) { GetChannel((char *)name,0); }
3752 MesPrint("@Proper syntax is: %#create <filename>");
3763 int DoPreRemove(UBYTE *s)
3766 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3767 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3768 if ( AP.preError ) return(0);
3769 while ( *s == ' ' || *s == '\t
' ) s++;
3770 if ( *s == '<
' ) { s++; }
3772 MesPrint("@Proper syntax is: %#remove <filename>");
3776 while ( *s && *s != '>
' ) {
3777 if ( *s == '\\
' ) s++;
3781 MesPrint("@Improper filename");
3786 CloseChannel((char *)name);
3787 remove((char *)name);
3796 int DoPreClose(UBYTE *s)
3799 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3800 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3801 if ( AP.preError ) return(0);
3802 while ( *s == ' ' || *s == '\t
' ) s++;
3803 if ( *s == '<
' ) { s++; }
3805 MesPrint("@Proper syntax is: %#close <filename>");
3809 while ( *s && *s != '>
' ) {
3810 if ( *s == '\\
' ) s++;
3814 MesPrint("@Improper filename");
3819 return(CloseChannel((char *)name));
3827 #write [<filename>] "formatstring" [,objects]
3828 The format string can contain the following special objects/codes
3831 \! if last entry in string: no linefeed at end
3833 %$ $-variable (to be found among the objects)
3834 %e expression (name to be found among the objects)
3835 %E expression without ; (name to be found among the objects)
3836 %s string (to be found among the objects) (with or without "")
3837 %S subterms (see PrintSubtermList)
3840 int DoPreWrite(UBYTE *s)
3844 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
3845 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3846 if ( AP.preError ) return(0);
3849 if ( PF.me != MASTER ) return 0;
3852 h.oldsilent = AM.silent;
3853 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
3854 h.newhandle = h.oldhandle = AC.LogHandle;
3855 h.oldprinttype = AO.PrintType;
3857 while ( *s == ' ' || *s == '\t
' ) s++;
3859 Determine where to write
3861 if( (s=defineChannel(s,&h))==0 ) return(-1);
3863 return(writeToChannel(WRITEOUT,s,&h));
3870 We have to read this procedure into a buffer.
3871 The only complications are:
3872 1: we have to seek through the file to do this efficiently
3873 the file operations under VMS cannot do this properly
3874 (unless we use the proper ANSI structs?)
3875 This is the reason why we read whole input files under VMS.
3876 2: what to do when the same name is used twice.
3877 Note that we have to do the reading without substitution of
3878 preprocessor variables.
3881 int DoProcedure(UBYTE *s)
3886 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
3887 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
3888 if ( PreSkip((UBYTE *)"procedure",(UBYTE *)"endprocedure",1) ) return(-1);
3891 p = (PROCEDURE *)FromList(&AP.ProcList);
3892 if ( PreLoad(&(p->p),(UBYTE *)"procedure",(UBYTE *)"endprocedure"
3893 ,1,(char *)"procedure") ) return(-1);
3896 s = p->p.buffer + 10;
3897 while ( *s == ' ' || *s == LINEFEED ) s++;
3898 if ( chartype[*s] ) {
3899 MesPrint("@Illegal name for procedure");
3903 while ( chartype[*s] == 0 || chartype[*s] == 1 ) s++;
3905 p->name = strDup1(p->name,"procedure");
3908 Check for double names
3910 for ( i = NumProcedures-2; i >= 0; i-- ) {
3911 if ( StrCmp(Procedures[i].name,p->name) == 0 ) {
3912 Error1("Multiple occurrence of procedure name ",p->name);
3923 int DoPreBreak(UBYTE *s)
3926 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3927 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3928 if ( AP.PreSwitchLevel <= 0 )
3929 MesPrint("@Break without corresponding Switch");
3930 else MessPreNesting(7);
3933 if ( AP.PreSwitchLevel <= 0 ) {
3934 MesPrint("@Break without corresponding Switch");
3937 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH )
3938 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
3947 int DoPreCase(UBYTE *s)
3950 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3951 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3952 if ( AP.PreSwitchLevel <= 0 )
3953 MesPrint("@Case without corresponding Switch");
3954 else MessPreNesting(8);
3957 if ( AP.PreSwitchLevel <= 0 ) {
3958 MesPrint("@Case without corresponding Switch");
3961 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE ) return(0);
3965 while ( *s ) { if ( *s == '\\
' ) s++; s++; }
3966 while ( s > t && ( s[-1] == ' ' || s[-1] == '\t
' ) && s[-2] != '\\
' ) {
3967 if ( s[-2] == '\\
' ) s--;
3970 if ( *t == '"' && s > t+1 && s[-1] == '"' && s[-2] != '\\
' ) {
3974 s = AP.PreSwitchStrings[AP.PreSwitchLevel];
3975 while ( *t == *s && *t ) { s++; t++; }
3976 if ( *t || *s ) return(0); /* case did not match */
3977 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
3986 int DoPreDefault(UBYTE *s)
3989 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
3990 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3991 if ( AP.PreSwitchLevel <= 0 )
3992 MesPrint("@Default without corresponding Switch");
3993 else MessPreNesting(9);
3996 if ( AP.PreSwitchLevel <= 0 ) {
3997 MesPrint("@Default without corresponding Switch");
4000 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE ) return(0);
4001 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
4010 int DoPreEndSwitch(UBYTE *s)
4013 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
4014 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4015 if ( AP.PreSwitchLevel <= 0 )
4016 MesPrint("@EndSwitch without corresponding Switch");
4017 else MessPreNesting(10);
4021 if ( AP.PreSwitchLevel <= 0 ) {
4022 MesPrint("@EndSwitch without corresponding Switch");
4025 M_free(AP.PreSwitchStrings[AP.PreSwitchLevel--],"pre switch string");
4033 There should be a string after this.
4034 We have to store it somewhere.
4037 int DoPreSwitch(UBYTE *s)
4039 UBYTE *t, *switchstring, **newstrings;
4040 int newnum, i, *newmodes;
4041 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
4044 while ( *s ) { if ( *s == '\\
' ) s++; s++; }
4045 while ( s > t && ( s[-1] == ' ' || s[-1] == '\t
' ) && s[-2] != '\\
' ) {
4046 if ( s[-2] == '\\
' ) s--;
4049 if ( *t == '"' && s > t+1 && s[-1] == '"' && s[-2] != '\\
' ) {
4053 switchstring = (UBYTE *)Malloc1((s-t)+1,"case string");
4056 if ( *t == '\\
' ) t++;
4060 if ( AP.PreSwitchLevel >= AP.NumPreSwitchStrings ) {
4061 newnum = 2*AP.NumPreSwitchStrings;
4062 newstrings = (UBYTE **)Malloc1(sizeof(UBYTE *)*(newnum+1),"case strings");
4063 newmodes = (int *)Malloc1(sizeof(int)*(newnum+1),"case strings");
4064 for ( i = 0; i < AP.NumPreSwitchStrings; i++ )
4065 newstrings[i] = AP.PreSwitchStrings[i];
4066 M_free(AP.PreSwitchStrings,"AP.PreSwitchStrings");
4067 for ( i = 0; i <= AP.NumPreSwitchStrings; i++ )
4068 newmodes[i] = AP.PreSwitchModes[i];
4069 M_free(AP.PreSwitchModes,"AP.PreSwitchModes");
4070 AP.PreSwitchStrings = newstrings;
4071 AP.PreSwitchModes = newmodes;
4072 AP.NumPreSwitchStrings = newnum;
4074 AP.PreSwitchStrings[++AP.PreSwitchLevel] = switchstring;
4075 if ( ( AP.PreSwitchLevel > 1 )
4076 && ( AP.PreSwitchModes[AP.PreSwitchLevel-1] != EXECUTINGPRESWITCH ) )
4077 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4079 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPRECASE;
4080 AddToPreTypes(PRETYPESWITCH);
4088 Print the contents of the preprocessor variables
4091 int DoPreShow(UBYTE *s)
4095 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) return(0);
4096 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) return(0);
4097 while ( *s == ' ' || *s == '\t
' ) s++;
4099 MesPrint("%#The preprocessor variables:");
4100 for ( i = 0; i < NumPre; i++ ) {
4101 MesPrint("%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4106 name = s; while ( *s && *s != ' ' && *s != '\t
' && *s != ',
' ) s++;
4108 for ( i = 0; i < NumPre; i++ ) {
4109 if ( StrCmp(PreVar[i].name,name) == 0 )
4110 MesPrint("%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4113 while ( *s == ' ' || *s == '\t
' ) s++;
4125 * A macro for translating the contents of `x' into a
string after expanding.
4127 #define STRINGIFY(x) STRINGIFY__(x)
4128 #define STRINGIFY__(x) #x
4130 int DoSystem(UBYTE *s)
4132 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4133 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4134 if ( AP.preError )
return(0);
4137 while ( *s ==
' ' || *s ==
'\t' ) s++;
4138 if ( *s ==
'-' && s[1] ==
'e' ) {
4143 MesPrint(
"@Syntax error in #system command.");
4146 while ( *s ==
' ' || *s ==
'\t' ) s++;
4147 err = system((
char *)s);
4149 PutPreVar((UBYTE *)
"SYSTEMERROR_",str,0,1);
4151 else if ( system((
char *)s) ) {
4152 MesPrint(
"@System call returned with error condition");
4157 Error0(
"External programs not implemented on this computer/system");
4170 int PreLoad(
PRELOAD *p, UBYTE *start, UBYTE *stop,
int mode,
char *message)
4172 UBYTE *s, *t, *top, *newbuffer, c;
4173 LONG i, ppsize, linenum = AC.CurrentStream->linenumber;
4174 int size1, size2, level, com=0, last=1, strng = 0;
4176 p->buffer = (UBYTE *)Malloc1(p->size+1,message);
4177 top = p->buffer + p->size - 2;
4178 t = p->buffer; *t++ =
'#';
4179 s = start; size1 = size2 = 0;
4180 while ( *s ) { s++; size1++; }
4181 s = stop;
while ( *s ) { s++; size2++; }
4182 s = AP.preStart;
while ( *s ) *t++ = *s++; *t++ = LINEFEED;
4187 if ( c == ENDOFINPUT ) {
4188 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4191 if ( c == AP.ComChar && last == 1 ) com = 1;
4192 if ( c == LINEFEED ) { last = 1; com = 0; }
4195 if ( ( c ==
'"' ) && ( com == 0 ) ) { strng ^= 1; }
4197 if ( ( c ==
'#' ) && ( com == 0 ) ) i = 0;
4201 ppsize = t - p->buffer;
4203 newbuffer = (UBYTE *)Malloc1(p->size,message);
4204 t = newbuffer; s = p->buffer;
4205 while ( --ppsize >= 0 ) *t++ = *s++;
4206 M_free(p->buffer,
"loading do loop");
4207 p->buffer = newbuffer;
4208 top = p->buffer + p->size - 2;
4212 if ( ( i == size2 ) && ( com == 0 ) ) {
4214 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4215 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4217 if ( level <= 0 )
break;
4218 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4219 *t++ = LINEFEED; *t = 0; last = 1;
4222 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4224 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4232 if ( i == 1 && t[-2] == LINEFEED ) {
4233 if ( c ==
'-' ) AC.NoShowInput = 1;
4234 else if ( c ==
'+' ) AC.NoShowInput = 0;
4251 #define SKIPBUFSIZE 20
4253 int PreSkip(UBYTE *start, UBYTE *stop,
int mode)
4255 UBYTE *s, *t, buffer[SKIPBUFSIZE+2], c;
4256 LONG i, linenum = AC.CurrentStream->linenumber;
4257 int size1, size2, level, com=0, last=1;
4259 t = buffer; *t++ =
'#';
4260 s = start; size1 = size2 = 0;
4261 while ( *s ) { s++; size1++; }
4262 s = stop;
while ( *s ) { s++; size2++; }
4267 if ( c == ENDOFINPUT ) {
4268 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4271 if ( c == AP.ComChar && last == 1 ) com = 1;
4272 if ( c == LINEFEED ) { last = 1; com = 0; i = 0; t = buffer; }
4274 if ( ( c ==
'#' ) && ( com == 0 ) ) { i = 0; t = buffer; }
4277 if ( i < SKIPBUFSIZE ) *t++ = c;
4278 if ( ( i == size2 ) && ( com == 0 ) ) {
4280 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4281 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4284 pushbackchar = LINEFEED;
4287 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4291 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4293 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4294 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4311 AP.MaxPreIfLevel = 2;
4312 ppp = &AP.PreIfStack;
4313 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
4314 "PreIfLevels") ) Terminate(-1);
4315 AP.PreIfLevel = 0; AP.PreIfStack[0] = EXECUTINGIF;
4317 AP.NumPreSwitchStrings = 10;
4318 AP.PreSwitchStrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*
4319 (AP.NumPreSwitchStrings+1),
"case strings");
4320 AP.PreSwitchModes = (
int *)Malloc1(
sizeof(
int)*
4321 (AP.NumPreSwitchStrings+1),
"case strings");
4322 AP.PreSwitchModes[0] = EXECUTINGPRESWITCH;
4323 AP.PreSwitchLevel = 0;
4336 int EvalPreIf(UBYTE *s)
4344 if ( ( u = PreIfEval(s,&val) ) == 0 )
return(-1);
4346 MesPrint(
"@Unmatched parentheses in condition");
4349 if ( val )
return(EXECUTINGIF);
4350 else return(LOOKINGFORELSE);
4371 UBYTE *PreIfEval(UBYTE *s,
int *value)
4373 int orlevel = 0, andlevel = 0, eqlevel = 0, cmplevel = 0;
4376 int ortype, orval, cmptype, cmpval, eqtype, eqval, andtype, andval;
4377 UBYTE *t, *eqt, *cmpt, c;
4379 ortype = orval = cmptype = cmpval = eqtype = eqval = andtype = andval = 0;
4383 while ( *s !=
')' ) {
4384 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4386 s = pParseObject(s,&type,&val2);
4387 if ( s == 0 )
return(0);
4391 while ( c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' ) {
4394 if ( *t ==
'"' ) t++;
4397 if ( *s !=
'|' )
goto illoper;
4402 if ( type == 0 || cmptype == 0 )
goto illobject;
4403 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4408 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4413 if ( andtype != 0 || type != 0 )
goto illobject;
4418 if ( ortype != 0 || type != 0 )
goto illobject;
4430 if ( *s !=
'&' )
goto illoper;
4433 if ( type == 0 || cmptype == 0 )
goto illobject;
4434 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4439 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4444 if ( andtype != 0 || type != 0 )
goto illobject;
4453 if ( eqlevel )
goto illorder;
4455 if ( type == 0 || cmptype == 0 )
goto illobject;
4456 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4460 if ( c ==
'!' && *s !=
'=' )
goto illoper;
4461 if ( *s ==
'=' ) s++;
4462 if ( c ==
'!' ) eqop = 1;
4464 eqlevel = 1; eqt = t; eqval = val; eqtype = type;
4468 if ( cmplevel )
goto illorder;
4469 if ( c ==
'<' ) cmpop = -1;
4471 cmplevel = 1; cmpt = t; cmpval = val; cmptype = type;
4474 if ( *s ==
'~' ) { s++; cmpop *= 4; }
4477 else if ( *s ==
'~' ) { s++; cmpop *= 3; }
4485 MesPrint(
"@illegal order of operators");
4488 MesPrint(
"@illegal object for this operator");
4491 MesPrint(
"@illegal operator");
4500 int PreCmp(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int cmpop)
4502 if ( type == 2 || type2 == 2 || cmpop < -2 || cmpop > 2 ) {
4503 if ( cmpop < 0 && cmpop > -3 ) cmpop -= 2;
4504 if ( cmpop > 0 && cmpop < 3 ) cmpop += 2;
4505 if ( cmpop == 3 ) val = StrCmp(t2,t) > 0;
4506 else if ( cmpop == 4 ) val = StrCmp(t2,t) >= 0;
4507 else if ( cmpop == -3 ) val = StrCmp(t2,t) < 0;
4508 else if ( cmpop == -4 ) val = StrCmp(t2,t) <= 0;
4511 if ( cmpop == 1 ) val = ( val2 > val );
4512 else if ( cmpop == 2 ) val = ( val2 >= val );
4513 else if ( cmpop == -1 ) val = ( val2 < val );
4514 else if ( cmpop == -2 ) val = ( val2 <= val );
4524 int PreEq(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int eqop)
4527 if ( type == 2 || type2 == 2 ) {
4528 if ( type != 2 ) { NumToStr(str,val ); t = str; }
4529 if ( type2 != 2 ) { NumToStr(str,val2); t2 = str; }
4530 if ( eqop == 1 ) val = StrCmp(t,t2) != 0;
4531 else val = StrCmp(t,t2) == 0;
4534 if ( eqop ) val = val != val2;
4535 else val = val == val2;
4553 UBYTE *pParseObject(UBYTE *s,
int *type, LONG *val2)
4558 while ( *s ==
' ' || *s ==
'\t' ) s++;
4561 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4562 s = PreIfEval(s,&val);
4567 else if ( *s ==
'$' && s[1] ==
'(' ) {
4569 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4570 s = PreIfDollarEval(s,&val);
4571 *type = 0; *val2 = val;
4576 MesPrint(
"@illegal end of condition");
4581 while ( *s && *s !=
'"' ) {
4582 if ( *s ==
'\\' ) s++;
4585 if ( *s == 0 )
goto illend;
4590 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4594 t = s; sign = 1; x = 0;
4595 if ( chartype[*t] == 0 ) {
4596 do { t++; }
while ( chartype[*t] <= 1 );
4600 if ( StrICmp(s,(UBYTE *)
"termsin") == 0 ) {
4602 WORD numdol, numexp;
4606 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4608 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4610 if ( ( numdol = GetDollar(t) ) > 0 ) {
4613 x = SizeOfDollar(numdol);
4616 x = TermsInDollar(numdol);
4620 MesPrint(
"@$%s has not (yet) been defined",t);
4628 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4629 MesPrint(
"@%s has not (yet) been defined",t);
4636 x = SizeOfExpression(numexp);
4639 x = TermsInExpression(numexp);
4643 while ( *tt ==
' ' || *tt ==
'\t'
4644 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4646 MesPrint(
"@Improper use of terms($var) or terms(expr)");
4654 else if ( StrICmp(s,(UBYTE *)
"sizeof") == 0 ) {
4658 else if ( StrICmp(s,(UBYTE *)
"exists") == 0 ) {
4660 WORD numdol, numexp;
4662 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4664 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4666 if ( ( numdol = GetDollar(t) ) >= 0 ) { x = 1; }
4673 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) { x = 0; }
4677 while ( *tt ==
' ' || *tt ==
'\t'
4678 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4680 MesPrint(
"@Improper use of exists($var) or exists(expr)");
4688 else if ( StrICmp(s,(UBYTE *)
"isnumerical") == 0 ) {
4691 WORD numdol, numexp;
4693 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4695 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4697 if ( ( numdol = GetDollar(t) ) < 0 ) {
4698 MesPrint(
"@$ variable in isnumerical(%s) does not exist",t);
4701 x = DolToLong(BHEAD numdol);
4702 if ( AN.ErrorInDollar ) {
4705 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
4706 if ( d->where[0] == 0 ) x = 1;
4707 else if ( d->where[d->where[0]] == 0 ) {
4708 if ( ABS(d->where[d->where[0]-1]) == d->where[0]-1 )
4719 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4720 MesPrint(
"@expression in isnumerical(%s) does not exist",t);
4723 x = TermsInExpression(numexp);
4724 if ( x != 1 ) x = 0;
4726 WORD *term = AT.WorkPointer;
4727 if ( GetFirstTerm(term,numexp) < 0 ) {
4728 MesPrint(
"@error reading expression in isnumerical(%s)",t);
4731 if ( *term == ABS(term[*term-1])+1 ) x = 1;
4736 while ( *tt ==
' ' || *tt ==
'\t'
4737 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4739 MesPrint(
"@Improper use of isnumerical($var) or numerical(expr)");
4747 else if ( StrICmp(s,(UBYTE *)(
"maxpowerof")) == 0 ) {
4752 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4755 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4756 MesPrint(
"@%s has not (yet) been defined",t);
4760 else if ( stype != CSYMBOL ) {
4761 MesPrint(
"@%s should be a symbol",t);
4767 x = symbols[numsym].maxpower;
4769 while ( *tt ==
' ' || *tt ==
'\t'
4770 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4772 MesPrint(
"@Improper use of maxpowerof(symbol)");
4780 else if ( StrICmp(s,(UBYTE *)(
"minpowerof")) == 0 ) {
4785 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4788 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4789 MesPrint(
"@%s has not (yet) been defined",t);
4793 else if ( stype != CSYMBOL ) {
4794 MesPrint(
"@%s should be a symbol",t);
4800 x = symbols[numsym].minpower;
4802 while ( *tt ==
' ' || *tt ==
'\t'
4803 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4805 MesPrint(
"@Improper use of minpowerof(symbol)");
4813 else if ( StrICmp(s,(UBYTE *)
"isfactorized") == 0 ) {
4815 WORD numdol, numexp;
4817 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4819 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4821 if ( ( numdol = GetDollar(t) ) > 0 ) {
4822 if ( Dollars[numdol].factors != 0 ) x = 1;
4826 MesPrint(
"@ %s should be the name of an expression or a $ variable",t-1);
4834 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4835 MesPrint(
"@ %s should be the name of an expression or a $ variable",t);
4839 if ( ( Expressions[numexp].vflags & ISFACTORIZED ) != 0 ) x = 1;
4844 while ( *tt ==
' ' || *tt ==
'\t'
4845 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4847 MesPrint(
"@Improper use of isfactorized($var) or isfactorized(expr)");
4855 else if ( StrICmp(s,(UBYTE *)
"isdefined") == 0 ) {
4858 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4864 while ( *tt ==
' ' || *tt ==
'\t'
4865 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4867 MesPrint(
"@Improper use of isdefined(var)");
4877 else if ( *t ==
'=' || *t ==
'<' || *t ==
'>' || *t ==
'!'
4878 || *t ==
')' || *t ==
' ' || *t ==
'\t' || *t == 0 || *t ==
'\n' ) {
4884 MesPrint(
"@Illegal use of string in preprocessor condition: %s",s);
4888 while ( *t ==
'-' || *t ==
'+' || *t ==
' ' || *t ==
'\t' ) {
4889 if ( *t ==
'-' ) sign = -sign;
4892 while ( chartype[*t] == 1 ) { x = 10*x + *t++ -
'0'; }
4893 while ( *t ==
' ' || *t ==
'\t' ) t++;
4894 if ( chartype[*t] == 8 || *t ==
')' || *t ==
'=' || *t == 0 ) {
4895 *val2 = sign > 0 ? x: -x;
4899 while ( chartype[*t] != 8 && *t !=
')' && *t !=
'=' && *t ) t++;
4900 while ( ( t > s ) && ( t[-1] ==
' ' || t[-1] ==
'\t' ) ) t--;
4921 UBYTE *buff, *s = 0, *t, *newb, c;
4922 int size, i, n, parlevel = 0, bralevel = 0;
4929 if ( size == 0 ) size = 72;
4931 if ( ( newb = (UBYTE *)Malloc1(size+2,
"{}") ) == 0 )
return(0);
4937 M_free(buff,
"pre calc buffer");
4945 Error0(
"Unmatched {}");
4946 M_free(buff,
"precalc buffer");
4949 else if ( c ==
'{' ) { bralevel++; }
4950 else if ( c ==
'}' ) {
4951 if ( --bralevel < 0 ) { *s++ = c; *s = 0;
break; }
4953 else if ( c ==
'(' ) { parlevel++; }
4954 else if ( c ==
')' ) {
4955 if ( --parlevel < 0 ) { *s++ = c; *s = 0;
goto setstring; }
4957 else if ( chartype[c] != 1 && chartype[c] != 5
4958 && chartype[c] != 6 && c !=
'!' && c !=
'&'
4959 && c !=
'|' && c !=
'\\' ) { *s++ = c; *s = 0;
goto setstring; }
4961 if ( parlevel > 0 )
goto setstring;
4967 if ( PreEval(buff+1,&answer) == 0 )
goto setstring;
4970 if ( answer < 0 ) { *s++ =
'-'; }
4971 uanswer = LongAbs(answer);
4974 *--t = ( uanswer % 10 ) +
'0';
4977 }
while ( uanswer > 0 );
4985 if ( OpenStream(buff,PRECALCSTREAM,0,PRENOACTION) == 0 )
return(0);
4997 UBYTE *PreEval(UBYTE *s, LONG *x)
5000 int tobemultiplied, tobeadded = 1, expsign, i;
5003 while ( *s ==
' ' || *s ==
'\t' ) s++;
5005 if ( *s ==
'+' || *s ==
'-' ) {
5006 if ( *s ==
'-' ) tobeadded = -1;
5009 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5010 if ( *s ==
'-' ) tobeadded = -tobeadded;
5016 while ( *s ==
' ' || *s ==
'\t' ) s++;
5017 if ( *s <= '9' && *s >=
'0' ) {
5022 else if ( *s == '(' || *s == '{
' ) {
5023 if ( ( t = PreEval(s+1,&y) ) == 0 ) return(0);
5027 while ( *s == ' ' || *s == '\t
' ) s++;
5029 while ( *s == '^
' || *s == '!
' ) {
5031 if ( s[-1] == '!
' ) { /* factorial of course */
5032 while ( *s == ' ' || *s == '\t
' ) s++;
5034 MesPrint("@Negative value in preprocessor factorial: %l",y);
5037 else if ( y == 0 ) y = 1;
5040 while ( z > 0 ) { y = y*z; z--; }
5044 else if ( *s == '%
' ) { /* ^% is postfix 2log */
5046 while ( *s == ' ' || *s == '\t
' ) s++;
5049 MesPrint("@Illegal value in preprocessor logarithm: %l",z);
5053 while ( z ) { y++; z >>= 1; }
5056 else if ( *s == '/
' ) { /* ^/ is postfix sqrt */
5059 while ( *s == ' ' || *s == '\t
' ) s++;
5062 MesPrint("@Illegal value in preprocessor square root: %l",z);
5065 if ( z > 8 ) { /* Very crude integer square root */
5068 while ( zz ) { yy++; zz >>= 1; }
5069 zz = z >> (yy/2); i = 10; y = 0;
5071 yy = zz/2 + z/(2*zz); i--;
5072 if ( y == yy ) break;
5074 } while ( y != yy && i > 0 );
5075 while ( y*y < z ) y++;
5076 while ( y*y > z ) y--;
5078 else if ( z >= 4 ) y = 2;
5079 else if ( z == 0 ) y = 0;
5083 while ( *s == ' ' || *s == '\t
' ) s++;
5084 while ( *s == '-
' || *s == '+
' || *s == ' ' || *s == '\t
' ) {
5085 if ( *s == '-
' ) expsign = -expsign;
5087 if ( *s <= '9
' && *s >= '0
' ) {
5090 else if ( *s == '(
' || *s == '{
' ) {
5091 if ( ( t = PreEval(s+1,&z) ) == 0 ) return(0);
5095 while ( *s == ' ' || *s == '\t
' ) s++;
5098 if ( tobemultiplied == 0 ) {
5099 if ( expsign < 0 ) a = 1/y;
5103 if ( tobemultiplied > 2 && expsign != 1 ) {
5104 MesPrint("&Incorrect use of ^ with & or |. Use brackets!");
5107 tobemultiplied *= expsign;
5108 if ( tobemultiplied == 1 ) a *= y;
5109 else if ( tobemultiplied == 3 ) a &= y;
5110 else if ( tobemultiplied == 4 ) a |= y;
5112 if ( y == 0 || tobemultiplied == -2 ) {
5113 MesPrint("@Division by zero in preprocessor calculator");
5116 if ( tobemultiplied == 2 ) a %= y;
5120 if ( *s == '%
' ) tobemultiplied = 2;
5121 else if ( *s == '*
' ) tobemultiplied = 1;
5122 else if ( *s == '/
' ) tobemultiplied = -1;
5123 else if ( *s == '&
' ) tobemultiplied = 3;
5124 else if ( *s == '|
' ) tobemultiplied = 4;
5129 if ( tobeadded >= 0 ) ux += ua;
5131 *x = ULongToLong(ux);
5132 if ( *s == ')
' || *s == '}
' ) return(s+1);
5133 else if ( *s == '-
' || *s == '+
' ) { tobeadded = 1; break; }
5147 void AddToPreTypes(int type)
5149 if ( AP.NumPreTypes >= AP.MaxPreTypes ) {
5150 int i, *newlist = (int *)Malloc1(sizeof(int)*(2*AP.MaxPreTypes+1)
5151 ,"preprocessor type lists");
5152 for ( i = 0; i <= AP.MaxPreTypes; i++ ) newlist[i] = AP.PreTypes[i];
5153 M_free(AP.PreTypes,"preprocessor type lists");
5154 AP.PreTypes = newlist;
5155 AP.MaxPreTypes = 2*AP.MaxPreTypes;
5157 AP.PreTypes[++AP.NumPreTypes] = type;
5165 void MessPreNesting(int par)
5167 MesPrint("@(%d)Illegal nesting of %#if, %#do, %#procedure and/or %#switch",par);
5172 #[ DoPreAddSeparator :
5174 Preprocessor directives "addseparator" and "rmseparator" add/remove
5175 separator characters used to separate function arguments.
5180 *Comma must be quoted!:
5185 Characters ' ', '\t' and '"' are ignored!
5188 int DoPreAddSeparator(UBYTE *s)
5190 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5191 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5192 for(;*s !=
'\0';s++){
5193 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5200 set_set(*s,AC.separators);
5213 int DoPreRmSeparator(UBYTE *s)
5215 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5216 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5217 for(;*s !=
'\0';s++){
5218 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5219 set_del(*s,AC.separators);
5230 int DoExternal(UBYTE *s)
5232 #ifdef WITHEXTERNALCHANNEL
5238 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5239 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5240 if ( AP.preError )
return(0);
5242 #ifdef WITHEXTERNALCHANNEL
5243 while ( *s ==
' ' || *s ==
'\t' ) s++;
5247 if ( chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5249 MesPrint(
"@Can't finde closing \"");
5252 case 0:
case 1:
continue;
5257 MesPrint(
"@Illegal name of preprocessor variable to store external channel");
5261 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5265 MesPrint(
"@Illegal external command");
5271 externalD=openExternalChannel(
5279 Error1(
"Can't start external program",s);
5286 NumToStr(buf,externalD);
5287 if (
PutPreVar(prevar,buf,0,1) < 0 )
return(-1);
5290 AX.currentExternalChannel=externalD;
5292 if(AX.currentPrompt!=0){
5293 if(setTerminatorForExternalChannel( (
char *)AX.currentPrompt)){
5294 MesPrint(
"@Prompt is too long");
5298 setKillModeForExternalChannel(AX.killSignal,AX.killWholeGroup);
5302 Error0(
"External channel: not implemented on this computer/system");
5313 int DoPrompt(UBYTE *s)
5315 #ifndef WITHEXTERNALCHANNEL
5318 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5319 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5321 #ifdef WITHEXTERNALCHANNEL
5322 while ( *s ==
' ' || *s ==
'\t' ) s++;
5323 if ( AX.currentPrompt )
5324 M_free(AX.currentPrompt,
"external channel prompt");
5326 AX.currentPrompt = (UBYTE *)strDup1((UBYTE *)
"",
"external channel prompt");
5328 AX.currentPrompt = strDup1(s,
"external channel prompt");
5329 if( setTerminatorForExternalChannel( (
char *)AX.currentPrompt) > 0 ){
5330 MesPrint(
"@Prompt is too long");
5336 Error0(
"External channel: not implemented on this computer/system");
5346 int DoSetExternal(UBYTE *s)
5348 #ifdef WITHEXTERNALCHANNEL
5353 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5354 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5355 if ( AP.preError )
return(0);
5357 #ifdef WITHEXTERNALCHANNEL
5358 while ( *s ==
' ' || *s ==
'\t' ) s++;
5359 while ( chartype[*s] == 1 ) { n = 10*n + *s++ -
'0'; }
5360 while ( *s ==
' ' || *s ==
'\t' ) s++;
5362 MesPrint(
"@setexternal: number expected");
5365 if(selectExternalChannel(n)<0){
5366 MesPrint(
"@setexternal: invalid number");
5369 AX.currentExternalChannel=n;
5372 Error0(
"External channel: not implemented on this computer/system");
5381 static FORM_INLINE UBYTE *pickupword(UBYTE *s)
5384 for(;*s>
' ';s++)
switch(*s){
5395 static inline int strINCmp(UBYTE *a, UBYTE *b,
int n)
5397 for(;n>0;n--)
if(tolower(*a++)!=tolower(*b++))
5403 #define KILLALL "killall"
5404 #define DAEMON "daemon"
5405 #define SHELL "shell"
5406 #define STDERR "stderr"
5408 #define TRUE_EXPR "true"
5409 #define FALSE_EXPR "false"
5410 #define NOSHELL "noshell"
5411 #define TERMINAL "terminal"
5416 int DoSetExternalAttr(UBYTE *s)
5418 #ifdef WITHEXTERNALCHANNEL
5424 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5425 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5426 if ( AP.preError )
return(0);
5428 #ifdef WITHEXTERNALCHANNEL
5431 while ( *s ==
' ' || *s ==
'\t' ) s++;
5432 s=pickupword(nam=s);
5434 while ( *s ==
' ' || *s ==
'\t' ) s++;
5436 MesPrint(
"@External channel:'=' expected instead of %s",s-1);
5440 while ( *s ==
' ' || *s ==
'\t' ) s++;
5447 while ( *s ==
' ' || *s ==
'\t' ) s++;
5448 if( (*s ==
',')||(*s ==
'\n')||(*s ==
';')||(*s ==
'\0') ){
5455 while ( *s ==
' ' || *s ==
'\t' ) s++;
5457 if(strINCmp((UBYTE *)SHELL,nam,lnam)==0){
5458 if(AX.shellname!=NULL)
5459 M_free(AX.shellname,
"external channel shellname");
5460 if(strINCmp((UBYTE *)NOSHELL,val,lval)==0)
5464 b=ch=AX.shellname=Malloc1(lval+1,
"external channel shellname");
5469 }
else if(strINCmp((UBYTE *)DAEMON,nam,lnam)==0){
5470 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5472 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5475 MesPrint(
"@External channel:true or false expected for %s",DAEMON);
5478 }
else if(strINCmp((UBYTE *)KILLALL,nam,lnam)==0){
5479 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5480 AX.killWholeGroup = 1;
5481 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5482 AX.killWholeGroup = 0;
5484 MesPrint(
"@External channel: true or false expected for %s",KILLALL);
5487 }
else if(strINCmp((UBYTE *)KILL,nam,lnam)==0){
5490 if( *val>=
'0' && *val<=
'9' )
5491 n = 10*n + *val++ -
'0';
5493 MesPrint(
"@External channel: number expected for %s",KILL);
5497 }
else if(strINCmp((UBYTE *)STDERR,nam,lnam)==0){
5498 if( AX.stderrname != NULL ) {
5499 M_free(AX.stderrname,
"external channel stderrname");
5501 if(strINCmp((UBYTE *)TERMINAL,val,lval)==0)
5502 AX.stderrname = NULL;
5505 b=ch=AX.stderrname=Malloc1(lval+1,
"external channel stderrname");
5512 MesPrint(
"@External channel: unrecognized attribute",nam);
5515 }
while(*s++ ==
',');
5516 if( (*(s-1)>
' ')&&(*(s-1)!=
';') ){
5517 MesPrint(
"@External channel: syntax error: %s",s-1);
5522 Error0(
"External channel: not implemented on this computer/system");
5532 int DoRmExternal(UBYTE *s)
5534 #ifdef WITHEXTERNALCHANNEL
5539 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5540 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5541 if ( AP.preError )
return(0);
5543 #ifdef WITHEXTERNALCHANNEL
5544 while ( *s ==
' ' || *s ==
'\t' ) s++;
5545 if( chartype[*s] == 1 ){
5546 for(n=0; chartype[*s] == 1 ; s++) { n = 10*n + *s -
'0'; }
5547 while ( *s ==
' ' || *s ==
'\t' ) s++;
5550 MesPrint(
"@rmexternal: invalid number");
5555 closeAllExternalChannels();
5556 AX.currentExternalChannel=0;
5560 n=AX.currentExternalChannel;
5563 closeExternalChannel(n);
5565 if (n == AX.currentExternalChannel)
5566 AX.currentExternalChannel=0;
5569 Error0(
"External channel: not implemented on this computer/system");
5597 int DoFromExternal(UBYTE *s)
5599 #ifdef WITHEXTERNALCHANNEL
5602 int withNoList=AC.NoShowInput;
5603 int oldpreassignflag;
5607 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5608 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5609 if ( AP.preError )
return(0);
5610 #ifdef WITHEXTERNALCHANNEL
5614 while ( *s ==
' ' || *s ==
'\t' ) s++;
5616 if ( *s ==
'-' || *s ==
'+' ) {
5622 while ( *s ==
' ' || *s ==
'\t' ) s++;
5629 if ( *s==
'$' || chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5631 MesPrint(
"@Can't finde closing \"");
5634 case 0:
case 1:
continue;
5639 MesPrint(
"@Illegal name to store output of external channel");
5643 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5647 if( chartype[*s] == 1 ){
5648 for(lbuf=0; chartype[*s] == 1 ; s++) { lbuf = 10*lbuf + *s -
'0'; }
5649 while ( *s ==
' ' || *s ==
'\t' ) s++;
5651 if( (*s!=
'\0')||(lbuf<0) ){
5652 MesPrint(
"@Illegal buffer length in fromexternal");
5657 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5660 if(selectExternalChannel(AX.currentExternalChannel)){
5661 MesPrint(
"@No current external channel");
5672 buf=Malloc1( (lbuf=255)+1,
"Fromexternal");
5678 for(i=0;(cc=getcFromExtChannel())>0;i++){
5682 UBYTE *tmp=Malloc1( (lbuf*=2)+1,
"Fromexternal");
5683 for(j=0;j<i;j++)tmp[j]=buf[j];
5684 M_free(buf,
"Fromexternal");
5691 MesPrint(
"@No current external channel");
5699 buf=Malloc1(lbuf+1,
"Fromexternal");
5700 for(i=0; i<lbuf;i++){
5706 if( (cc=getcFromExtChannel())<1 )
5719 while(getcFromExtChannel()>0);
5721 MesPrint(
"@No current external channel");
5728 int oldNumPotModdollars = NumPotModdollars;
5730 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
5731 AC.RhsExprInModuleFlag = 0;
5735 UBYTE *pbuf=Malloc1(StrLen(prevar)+1+lbuf+1,
"Fromexternal to dollar");
5738 while(*b!=
'\0'){*c++ = *b++;}
5741 while( (*c++=*b++)!=
'\0' );
5742 oldpreassignflag = AP.PreAssignFlag;
5743 AP.PreAssignFlag = 1;
5744 if ( ( cc = CompileStatement(pbuf) ) || ( cc = CatchDollar(0) ) ) {
5745 Error1(
"External channel: can't asign output to dollar variable ",prevar);
5747 AP.PreAssignFlag = oldpreassignflag;
5748 NumPotModdollars = oldNumPotModdollars;
5750 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
5752 M_free(pbuf,
"Fromexternal to dollar");
5757 M_free(buf,
"Fromexternal");
5758 if ( cc )
return(-1);
5762 if ( OpenStream(s,EXTERNALCHANNELSTREAM,0,PRENOACTION) == 0 )
return(-1);
5764 AC.NoShowInput = withNoList;
5768 Error0(
"External channel: not implemented on this computer/system");
5779 #ifdef WITHEXTERNALCHANNEL
5782 LONG WriteToExternalChannel(
int handle, UBYTE *buffer, LONG size)
5787 if(writeBufToExtChannel((
char*)buffer,size))
5793 int DoToExternal(UBYTE *s)
5795 #ifdef WITHEXTERNALCHANNEL
5797 LONG (*OldWrite)(
int handle, UBYTE *buffer, LONG size) = WriteFile;
5802 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5803 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5804 if ( AP.preError )
return(0);
5805 #ifdef WITHEXTERNALCHANNEL
5807 h.oldsilent=AM.silent;
5808 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
5809 h.newhandle = h.oldhandle = AC.LogHandle;
5810 h.oldprinttype = AO.PrintType;
5812 WriteFile=&WriteToExternalChannel;
5814 while ( *s ==
' ' || *s ==
'\t' ) s++;
5816 if(AX.currentExternalChannel==0){
5817 MesPrint(
"@No current external channel");
5818 goto DoToExternalReady;
5821 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5822 selectExternalChannel(AX.currentExternalChannel);
5824 ret=writeToChannel(EXTERNALCHANNELOUT,s,&h);
5829 Error0(
"External channel: not implemented on this computer/system");
5840 UBYTE *defineChannel(UBYTE *s,
HANDLERS *h)
5849 while ( *s && *s !=
'>' ) {
5850 if ( *s ==
'\\' ) s++;
5854 MesPrint(
"@Improper termination of filename");
5860 h->newhandle = GetChannel((
char *)name,0);
5863 else if ( AC.LogHandle >= 0 ) {
5864 h->newhandle = AC.LogHandle;
5875 int writeToChannel(
int wtype, UBYTE *s,
HANDLERS *h)
5877 UBYTE *to, *fstring, *ss, *sss, *s1, c, c1;
5878 WORD num, number, nfac;
5879 WORD oldOptimizationLevel;
5880 UBYTE Out[MAXLINELENGTH+14], *stopper;
5887 while ( *s ==
',' || *s ==
' ' ) s++;
5889 MesPrint(
"@No format string present");
5892 s++; fstring = to = s;
5898 if ( *s ==
'\\' ) *to++ = *s++;
5900 else if ( *s ==
'"' ) *to++ = *s++;
5901 else { *to++ =
'\\'; *to++ = *s++; }
5903 else if ( *s ==
'"' )
break;
5907 MesPrint(
"@No closing \" in format string");
5911 if ( AC.LineLength > 20 && AC.LineLength <= MAXLINELENGTH ) stopper = Out + AC.LineLength;
5912 else stopper = Out + MAXLINELENGTH;
5919 AC.LogHandle = h->newhandle;
5920 AM.FileOnlyFlag = h->newlogonly;
5921 if ( h->newhandle >= 0 ) {
5922 AO.PrintType |= PRINTLFILE;
5924 while ( *fstring ) {
5925 if ( to >= stopper ) {
5926 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
5930 WriteString(wtype,Out,num);
5932 if ( AC.OutputMode == FORTRANMODE
5933 || AC.OutputMode == PFORTRANMODE ) {
5935 for ( i = 0; i < number; i++ ) *to++ =
' ';
5939 if ( *fstring ==
'\\' ) {
5941 if ( *fstring ==
'n' ) {
5943 WriteString(wtype,Out,num);
5947 else if ( *fstring ==
't' ) { *to++ =
'\t'; fstring++; }
5948 else if ( *fstring ==
'b' ) { *to++ =
'\\'; fstring++; }
5949 else *to++ = *fstring++;
5951 else if ( *fstring ==
'%' ) {
5955 if ( *fstring ==
'd' ) {
5959 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
5961 while ( *s ==
'+' || *s ==
'-' ) {
5962 if ( *s ==
'-' ) sign = -sign;
5965 dig = 0; ss = s;
if ( sign < 0 ) { ss--; *ss =
'-'; dig++; }
5966 while ( *s >=
'0' && *s <=
'9' ) { s++; dig++; }
5969 if ( to >= stopper ) {
5971 WriteString(wtype,Out,num);
5974 if ( *ss ==
'\\' ) ss++;
5979 if ( number < dig ) { dig = number; ss = s - dig; }
5980 while ( number > dig ) {
5981 if ( to >= stopper ) {
5983 WriteString(wtype,Out,num);
5986 *to++ =
' '; number--;
5989 if ( to >= stopper ) {
5991 WriteString(wtype,Out,num);
5994 if ( *ss ==
'\\' ) ss++;
6000 else if ( *fstring ==
'$' ) {
6002 number = AO.OutSkip;
6004 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6005 if ( AC.OutputMode == FORTRANMODE
6006 || AC.OutputMode == PFORTRANMODE ) {
6010 nodollar: MesPrint(
"@$-variable expected in #write instruction");
6011 AM.FileOnlyFlag = h->oldlogonly;
6012 AC.LogHandle = h->oldhandle;
6013 AO.PrintType = h->oldprinttype;
6014 AM.silent = h->oldsilent;
6018 while ( chartype[*s] <= 1 ) s++;
6019 if ( s == ss )
goto nodollar;
6021 num = GetDollar(ss);
6023 MesPrint(
"@#write instruction: $%s has not been defined",ss);
6024 AM.FileOnlyFlag = h->oldlogonly;
6025 AC.LogHandle = h->oldhandle;
6026 AO.PrintType = h->oldprinttype;
6027 AM.silent = h->oldsilent;
6032 if ( Dollars[num].nfactors <= 0 ) {
6034 MesPrint(
"@#write instruction: $%s has not been factorized",ss);
6035 AM.FileOnlyFlag = h->oldlogonly;
6036 AC.LogHandle = h->oldhandle;
6037 AO.PrintType = h->oldprinttype;
6038 AM.silent = h->oldsilent;
6044 nfac = GetDollarNumber(&s,Dollars+num);
6046 if ( Dollars[num].nfactors == 1 && nfac == 1 )
goto writewhole;
6048 if ( ( dolalloc = WriteDollarFactorToBuffer(num,nfac,0) ) == 0 ) {
6049 AM.FileOnlyFlag = h->oldlogonly;
6050 AC.LogHandle = h->oldhandle;
6051 AO.PrintType = h->oldprinttype;
6052 AM.silent = h->oldsilent;
6057 else if ( *s && *s !=
' ' && *s !=
',' && *s !=
'\t' ) {
6058 MesPrint(
"@#write instruction: illegal characters after $-variable");
6059 AM.FileOnlyFlag = h->oldlogonly;
6060 AC.LogHandle = h->oldhandle;
6061 AO.PrintType = h->oldprinttype;
6062 AM.silent = h->oldsilent;
6067 if ( ( dolalloc = WriteDollarToBuffer(num,0) ) == 0 ) {
6068 AM.FileOnlyFlag = h->oldlogonly;
6069 AC.LogHandle = h->oldhandle;
6070 AO.PrintType = h->oldprinttype;
6071 AM.silent = h->oldsilent;
6078 if ( to >= stopper ) {
6079 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6083 WriteString(wtype,Out,num);
6085 for ( i = 0; i < number; i++ ) *to++ =
' ';
6086 if ( AC.OutputMode == FORTRANMODE
6087 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6089 if ( chartype[*ss] > 3 ) { *to++ = *ss++; }
6091 sss = ss;
while ( chartype[*ss] <= 3 ) ss++;
6092 if ( ( to + (ss-sss) ) >= stopper ) {
6093 if ( (ss-sss) >= (stopper-Out) ) {
6094 if ( ( to - stopper ) < 10 ) {
6095 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6099 WriteString(wtype,Out,num);
6101 for ( i = 0; i < number; i++ ) *to++ =
' ';
6102 if ( AC.OutputMode == FORTRANMODE
6103 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6105 while ( (ss-sss) >= (stopper-Out) ) {
6106 while ( to < stopper-1 ) {
6109 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6116 WriteString(wtype,Out,num);
6118 if ( AC.OutputMode == FORTRANMODE
6119 || AC.OutputMode == PFORTRANMODE ) {
6120 for ( i = 0; i < number; i++ ) *to++ =
' ';
6126 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6130 WriteString(wtype,Out,num);
6132 for ( i = 0; i < number; i++ ) *to++ =
' ';
6133 if ( AC.OutputMode == FORTRANMODE
6134 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6137 while ( sss < ss ) *to++ = *sss++;
6141 M_free(dolalloc,
"written dollar");
6145 else if ( *fstring ==
's' ) {
6147 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6151 if ( *s ==
'\\' ) s++;
6152 else if ( *s ==
'"' )
break;
6156 MesPrint(
"@#write instruction: Missing \" in string");
6157 AM.FileOnlyFlag = h->oldlogonly;
6158 AC.LogHandle = h->oldhandle;
6159 AO.PrintType = h->oldprinttype;
6160 AM.silent = h->oldsilent;
6164 if ( to >= stopper ) {
6166 WriteString(wtype,Out,num);
6169 if ( *ss ==
'\\' ) ss++;
6176 while ( *s && *s !=
',' ) {
6177 if ( *s ==
'\\' ) { s++; sss = s+1; }
6180 while ( s > sss+1 && ( s[-1] ==
' ' || s[-1] ==
'\t' ) ) s--;
6182 if ( to >= stopper ) {
6184 WriteString(wtype,Out,num);
6187 if ( *ss ==
'\\' ) ss++;
6192 else if ( *fstring ==
'X' ) {
6194 if ( cbuf[AM.sbufnum].numrhs > 0 ) {
6198 UBYTE *s = GetPreVar(AM.oldnumextrasymbols,0);
6200 while ( *s >=
'0' && *s <=
'9' ) x = 10*x + *s++ -
'0';
6202 PrintSubtermList(1,x);
6204 PrintSubtermList(1,cbuf[AM.sbufnum].numrhs);
6207 else if ( *fstring ==
'O' ) {
6208 number = AO.OutSkip;
6214 if ( AO.OptimizeResult.code == NULL && AO.OptimizationLevel != 0 ) {
6215 MesPrint(
"@In #write instruction: no optimization results available!");
6219 WriteString(wtype,Out,num);
6221 if ( AO.OptimizationLevel != 0 ) {
6222 WORD oldoutskip = AO.OutSkip;
6223 AO.OutSkip = number;
6224 optimize_print_code(0);
6225 AO.OutSkip = oldoutskip;
6228 else if ( *fstring ==
'e' || *fstring ==
'E' ) {
6229 if ( *fstring ==
'E'
6230 || AC.OutputMode == FORTRANMODE
6231 || AC.OutputMode == PFORTRANMODE ) nosemi = 1;
6234 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6235 if ( chartype[*s] != 0 && *s !=
'[' ) {
6236 noexpr: MesPrint(
"@expression name expected in #write instruction");
6237 AM.FileOnlyFlag = h->oldlogonly;
6238 AC.LogHandle = h->oldhandle;
6239 AO.PrintType = h->oldprinttype;
6240 AM.silent = h->oldsilent;
6244 if ( ( s = SkipAName(ss) ) == 0 || s[-1] ==
'_' )
goto noexpr;
6245 s1 = s; c = c1 = *s1;
6249 AO.CurBufWrt = s1+1;
6253 MesPrint(
"@Illegal () specifier in expression name in #write");
6254 AM.FileOnlyFlag = h->oldlogonly;
6255 AC.LogHandle = h->oldhandle;
6256 AO.PrintType = h->oldprinttype;
6257 AM.silent = h->oldsilent;
6261 else AO.CurBufWrt = (UBYTE *)underscore;
6264 if ( num > 0 ) WriteUnfinString(wtype,Out,num);
6266 oldOptimizationLevel = AO.OptimizationLevel;
6267 AO.OptimizationLevel = 0;
6268 if ( WriteOne(ss,(
int)num,nosemi,plus) < 0 ) {
6269 AM.FileOnlyFlag = h->oldlogonly;
6270 AC.LogHandle = h->oldhandle;
6271 AO.PrintType = h->oldprinttype;
6272 AM.silent = h->oldsilent;
6275 AO.OptimizationLevel = oldOptimizationLevel;
6277 if ( s > s1 ) *s++ = c;
6282 else if ( ( *fstring ==
'f' ) || ( *fstring ==
'F' ) ) {
6284 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6286 while ( *s && *s !=
',' ) {
6287 if ( *s ==
'\\' ) s++;
6291 s1 = LoadInputFile(ss,HEADERFILE);
6298 ss = s1;
while ( *ss ) ss++;
6300 WriteString(wtype,s1,n);
6301 M_free(s1,
"copy file");
6303 else if ( *fstring ==
'F' ) {
6305 MesPrint(
"@Error in #write: could not open file %s",ss);
6307 goto ReturnWithError;
6311 else if ( *fstring ==
'%' ) {
6314 else if ( FG.cTable[*fstring] == 1 ) {
6316 while ( FG.cTable[*fstring] == 1 ) {
6317 number = 10*number + *fstring++ -
'0';
6319 if ( *fstring ==
'O' )
goto dooptim;
6320 else if ( *fstring ==
'd' )
goto donumber;
6321 else if ( *fstring ==
'$' )
goto dodollar;
6322 else if ( *fstring ==
'X' || *fstring ==
'x' ) {
6323 if ( number > 0 && number <= cbuf[AM.sbufnum].numrhs ) {
6324 UBYTE buffer[80], *out, *old1, *old2, *old3;
6326 if ( *fstring ==
'X' ) {
6327 out = StrCopy((UBYTE *)AC.extrasym,buffer);
6328 if ( AC.extrasymbols == 0 ) {
6329 out = NumCopy(number,out);
6330 out = StrCopy((UBYTE *)
"_",out);
6332 else if ( AC.extrasymbols == 1 ) {
6333 if ( AC.OutputMode == CMODE ) {
6334 out = StrCopy((UBYTE *)
"[",out);
6335 out = NumCopy(number,out);
6336 out = StrCopy((UBYTE *)
"]",out);
6339 out = StrCopy((UBYTE *)
"(",out);
6340 out = NumCopy(number,out);
6341 out = StrCopy((UBYTE *)
")",out);
6344 out = StrCopy((UBYTE *)
"=",out);
6346 while ( ss < out ) {
6347 if ( to >= stopper ) {
6349 WriteString(wtype,Out,num);
6355 term = cbuf[AM.sbufnum].rhs[number];
6362 old2 = AO.OutputLine;
6365 AO.OutputLine = Out;
6366 AO.OutStop = Out + AC.LineLength;
6368 if ( WriteInnerTerm(term,first) ) Terminate(-1);
6372 to = Out + (AO.OutFill-AO.OutputLine);
6374 AO.OutputLine = old2;
6381 goto IllegControlSequence;
6384 else if ( *fstring ==
'+' ) {
6385 plus = 1;
goto retry;
6387 else if ( *fstring == 0 ) {
6391 IllegControlSequence:
6392 MesPrint(
"@Illegal control sequence in format string in #write instruction");
6394 AM.FileOnlyFlag = h->oldlogonly;
6395 AC.LogHandle = h->oldhandle;
6396 AO.PrintType = h->oldprinttype;
6397 AM.silent = h->oldsilent;
6410 if(wtype==EXTERNALCHANNELOUT){
6412 WriteUnfinString(wtype,Out,num);
6415 WriteString(wtype,Out,num);
6419 AM.FileOnlyFlag = h->oldlogonly;
6420 AC.LogHandle = h->oldhandle;
6421 AO.PrintType = h->oldprinttype;
6422 AM.silent = h->oldsilent;
6434 int DoFactDollar(UBYTE *s)
6437 WORD numdollar, *oldworkpointer;
6439 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6440 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6441 while ( *s ==
' ' || *s ==
'\t' ) s++;
6443 if ( GetName(AC.dollarnames,s+1,&numdollar,NOAUTO) != CDOLLAR ) {
6444 MesPrint(
"@%s is undefined",s);
6449 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6453 oldworkpointer = AT.WorkPointer;
6454 if ( DollarFactorize(BHEAD numdollar) )
return(-1);
6455 AT.WorkPointer = oldworkpointer;
6459 else if ( ParenthesesTest(s) )
return(-1);
6461 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6471 WORD GetDollarNumber(UBYTE **inp,
DOLLARS d)
6473 UBYTE *s = *inp, c, *name;
6474 WORD number, nfac, *w;
6479 while ( FG.cTable[*s] < 2 ) s++;
6481 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6482 MesPrint(
"@dollar in #write should have been defined previously");
6486 dd = Dollars + number;
6489 nfac = GetDollarNumber(inp,dd);
6492 MesPrint(
"@Illegal factor for dollar variable");
6497 if ( dd->nfactors > d->nfactors ) {
6499 MesPrint(
"@Factor number for dollar variable too large");
6502 return(dd->nfactors);
6504 w = dd->factors[nfac-1].where;
6506 if ( dd->factors[nfac-1].value > d->nfactors ||
6507 dd->factors[nfac-1].value < 0 )
goto TooBig;
6508 return(dd->factors[nfac-1].value);
6510 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6511 && w[1] <= d->nfactors )
return(w[1]);
6512 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6514 MesPrint(
"@Illegal factor number for dollar variable");
6518 if ( dd->type == DOLZERO ) {
6521 else if ( dd->type == DOLTERMS || dd->type == DOLNUMBER ) {
6523 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6524 && w[1] <= d->nfactors )
return(w[1]);
6525 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6531 else if ( FG.cTable[*s] == 1 ) {
6532 WORD x = *s++ -
'0';
6533 while ( FG.cTable[*s] == 1 ) {
6534 x = 10*x + *s++ -
'0';
6535 if ( x > d->nfactors ) {
6536 MesPrint(
"@Factor number %d for dollar variable too large",x);
6541 MesPrint(
"@Illegal factor number for dollar variable");
6548 MesPrint(
"@Illegal factor indicator for dollar variable");
6561 int DoSetRandom(UBYTE *s)
6564 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6565 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6566 while ( *s ==
' ' || *s ==
'\t' ) s++;
6568 while ( FG.cTable[*s] == 1 ) {
6569 x = 10*x + (*s++-
'0');
6571 while ( *s ==
' ' || *s ==
'\t' ) s++;
6575 int id, totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
6577 int id, totnum = AM.totalnumberofthreads;
6579 for (
id = 0;
id < totnum;
id++ ) {
6580 AB[id]->R.wranfseed = x;
6581 if ( AB[
id]->R.wranfia ) M_free(AB[
id]->R.wranfia,
"wranf");
6582 AB[id]->R.wranfia = 0;
6586 if ( AR.wranfia ) M_free(AR.wranfia,
"wranf");
6592 MesPrint(
"@proper syntax is #SetRandom number");
6604 int DoOptimize(UBYTE *s)
6610 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6611 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6613 exprname = s; s = SkipAName(s);
6614 if ( *s != 0 && *s != ';' ) {
6615 MesPrint(
"@proper syntax is #Optimize,expression");
6619 if ( GetName(AC.exprnames,exprname,&numexpr,NOAUTO) != CEXPRESSION ) {
6620 MesPrint(
"@%s is not an expression",exprname);
6623 else if ( AP.preError == 0 ) {
6627 WORD *term = AT.WorkPointer;
6629 if ( AO.OptimizationLevel == 0 )
return(0);
6630 switch ( e->status ) {
6631 case LOCALEXPRESSION:
6632 case GLOBALEXPRESSION:
6635 MesPrint(
"@Expression %s is not an active unhidden local or global expression.",exprname);
6640 if ( PF.me == MASTER )
6643 for ( i = NumExpressions-1; i >= 0; i-- ) {
6644 AS.OldOnFile[i] = Expressions[i].onfile;
6645 AS.OldNumFactors[i] = Expressions[i].numfactors;
6646 AS.Oldvflags[i] = Expressions[i].vflags;
6647 Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
6649 for ( i = 0; i < NumExpressions; i++ ) {
6650 if ( i == numexpr ) {
6652 GetPreVar((UBYTE *)
"EXTRASYMBOLS_",0),0,1);
6653 Optimize(numexpr, 0);
6654 AO.OptimizeResult.nameofexpr = strDup1(exprname,
"optimize expression name");
6658 if ( PF.me == MASTER ) {
6660 e = Expressions + i;
6661 switch ( e->status ) {
6662 case LOCALEXPRESSION:
6663 case SKIPLEXPRESSION:
6664 case DROPLEXPRESSION:
6665 case DROPPEDEXPRESSION:
6666 case GLOBALEXPRESSION:
6667 case SKIPGEXPRESSION:
6668 case DROPGEXPRESSION:
6669 case HIDELEXPRESSION:
6670 case HIDEGEXPRESSION:
6671 case DROPHLEXPRESSION:
6672 case DROPHGEXPRESSION:
6673 case INTOHIDELEXPRESSION:
6674 case INTOHIDEGEXPRESSION:
6680 SetScratch(AR.infile,&(e->onfile));
6681 if ( GetTerm(BHEAD term) <= 0 ) {
6682 MesPrint(
"@Expression %d has problems reading from scratchfile",i);
6687 SeekScratch(AR.outfile,&position);
6688 e->onfile = position;
6689 *AM.S0->sBuffer = 0; firstterm = -1;
6691 WORD *oldipointer = AR.CompressPointer;
6692 WORD *comprtop = AR.ComprTop;
6693 AR.ComprTop = AM.S0->sTop;
6694 AR.CompressPointer = AM.S0->sBuffer;
6695 if ( firstterm > 0 ) {
6696 if (
PutOut(BHEAD term,&position,AR.outfile,1) < 0 )
goto DoSerr;
6698 else if ( firstterm < 0 ) {
6699 if (
PutOut(BHEAD term,&position,AR.outfile,0) < 0 )
goto DoSerr;
6703 if (
PutOut(BHEAD term,&position,AR.outfile,-1) < 0 )
goto DoSerr;
6706 AR.CompressPointer = oldipointer;
6707 AR.ComprTop = comprtop;
6708 }
while ( GetTerm(BHEAD term) );
6709 if (
FlushOut(&position,AR.outfile,1) ) {
6711 MesPrint(
"@Expression %d has problems writing to scratchfile",i);
6737 int DoClearOptimize(UBYTE *s)
6739 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6740 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6742 return(ClearOptimize());
6757 int DoSkipExtraSymbols(UBYTE *s)
6759 CBUF *C = cbuf + AM.sbufnum;
6760 WORD tt = 0, j = 0, oldval = AO.OptimizeResult.minvar;
6761 if ( AO.OptimizeResult.code == NULL )
return(0);
6762 if ( AO.OptimizationLevel == 0 )
return(0);
6763 while ( *s ==
',' ) s++;
6765 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
6768 while ( *s <= '9' && *s >=
'0' ) j = 10*j + *s++ -
'0';
6770 MesPrint(
"@Illegal use of #SkipExtraSymbols instruction");
6773 AO.OptimizeResult.minvar += j;
6774 if ( AO.OptimizeResult.minvar > AO.OptimizeResult.maxvar )
6775 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
6777 j = AO.OptimizeResult.minvar - oldval;
6782 InsTree(AM.sbufnum,C->numrhs);
6796 int DoPreReset(UBYTE *s)
6799 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6800 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6801 while ( *s ==
' ' || *s ==
'\t' ) s++;
6803 MesPrint(
"@proper syntax is #Reset variable");
6807 while ( FG.cTable[*s] == 0 ) s++;
6809 if ( ( StrICmp(ss,(UBYTE *)
"timer") == 0 )
6810 || ( StrICmp(ss,(UBYTE *)
"stopwatch") == 0 ) ) {
6812 AP.StopWatchZero = GetRunningTime();
6817 MesPrint(
"@proper syntax is #Reset variable");
6827 static int DoAddPath(UBYTE *s,
int bPrepend)
6831 UBYTE *path, *path_end, *current_dir, *current_dir_end, *NewPath, *t;
6834 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6835 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6838 while ( *s ==
' ' || *s ==
'\t' ) s++;
6841 while ( *s && *s !=
'"' ) {
6842 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
6843 if ( !s[1] )
goto ImproperPath;
6848 if ( *s !=
'"' )
goto ImproperPath;
6853 while ( *s && *s !=
' ' && *s !=
'\t' ) {
6854 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
6855 if ( !s[1] )
goto ImproperPath;
6862 if ( path == path_end )
goto ImproperPath;
6863 while ( *s ==
' ' || *s ==
'\t' ) s++;
6864 if ( *s )
goto ImproperPath;
6868 if ( path[0] == SEPARATOR ) {
6872 else if ( chartype[path[0]] == 0 && path[1] ==
':' ) {
6879 if ( !AC.CurrentStream )
goto FileNameUnavailable;
6880 if ( AC.CurrentStream->type != FILESTREAM && AC.CurrentStream->type != REVERSEFILESTREAM )
goto FileNameUnavailable;
6881 if ( !AC.CurrentStream->name )
goto FileNameUnavailable;
6882 s = current_dir = current_dir_end = AC.CurrentStream->name;
6884 if ( SEPARATOR !=
'\\' && *s ==
'\\' && s[1] ) {
6888 if ( *s == SEPARATOR ) {
6889 current_dir_end = s;
6895 current_dir = current_dir_end = NULL;
6899 n = path_end - path;
6900 if ( AM.Path ) n += StrLen(AM.Path) + 1;
6901 if ( current_dir != current_dir_end ) n+= current_dir_end - current_dir + 1;
6902 s = NewPath = (UBYTE *)Malloc1(n + 1,
"add path");
6906 if ( current_dir != current_dir_end ) {
6908 while ( t != current_dir_end ) *s++ = *t++;
6912 while ( t != path_end ) *s++ = *t++;
6913 if ( AM.Path ) *s++ = PATHSEPARATOR;
6917 while ( *t ) *s++ = *t++;
6920 if ( AM.Path ) *s++ = PATHSEPARATOR;
6921 if ( current_dir != current_dir_end ) {
6923 while ( t != current_dir_end ) *s++ = *t++;
6927 while ( t != path_end ) *s++ = *t++;
6932 if ( AM.Path ) M_free(AM.Path,
"add path");
6938 MesPrint(
"@Improper syntax for %#%sPath", bPrepend ?
"Prepend" :
"Append");
6941 FileNameUnavailable:
6943 MesPrint(
"@Sorry, %#%sPath can't resolve the current file name from here", bPrepend ?
"Prepend" :
"Append");
6956 return DoAddPath(s, 0);
6973 return DoAddPath(s, 1);
6983 int DoTimeOutAfter(UBYTE *s)
6986 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6987 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6988 while ( *s ==
' ' || *s ==
'\t' ) s++;
6990 while ( FG.cTable[*s] == 1 ) {
6991 x = 10*x + (*s++-
'0');
6993 while ( *s ==
' ' || *s ==
'\t' ) s++;
6999 MesPrint(
"@proper syntax is #TimeoutAfter number");
int PutPreVar(UBYTE *, UBYTE *, UBYTE *, int)
#define VectorReserve(X, newcapacity)
int DoRecovery(int *moduletype)
int DoPrePrependPath(UBYTE *)
int DoPreAppendPath(UBYTE *)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
int TheDefine(UBYTE *, int)
WORD FlushOut(POSITION *, FILEHANDLE *, int)
void DoCheckpoint(int moduletype)