40static UBYTE pushbackchar = 0;
41static int oldmode = 0;
42static int stopdelay = 0;
43static STREAM *oldstream = 0;
44static UBYTE underscore[2] = {
'_',0};
45static PREVAR *ThePreVar = 0;
47static int ExitDoLoops(
int,
const char *);
50 {
"add" , DoPreAdd , 0, 0}
51 ,{
"addseparator" , DoPreAddSeparator,0,0}
52 ,{
"append" , DoPreAppend , 0, 0}
54 ,{
"assign" , DoPreAssign , 0, 0}
55 ,{
"break" , DoPreBreak , 0, 0}
56 ,{
"breakdo" , DoBreakDo , 0, 0}
57 ,{
"call" , DoCall , 0, 0}
58 ,{
"case" , DoPreCase , 0, 0}
59 ,{
"clearflag" , DoClearUserFlag, 0, 0}
60 ,{
"clearoptimize", DoClearOptimize, 0, 0}
61 ,{
"close" , DoPreClose , 0, 0}
62 ,{
"closedictionary", DoPreCloseDictionary,0,0}
63 ,{
"commentchar" , DoCommentChar , 0, 0}
65 ,{
"create" , DoPreCreate , 0, 0}
66 ,{
"debug" , DoDebug , 0, 0}
67 ,{
"default" , DoPreDefault , 0, 0}
68 ,{
"define" , DoDefine , 0, 0}
70 ,{
"else" , DoElse , 0, 0}
71 ,{
"elseif" , DoElseif , 0, 0}
72 ,{
"enddo" , DoEnddo , 0, 0}
74 ,{
"endfloat" , DoEndFloat , 0, 0}
76 ,{
"endif" , DoEndif , 0, 0}
77 ,{
"endinside" , DoEndInside , 0, 0}
78 ,{
"endnamespace" , DoEndNamespace , 0, 0}
79 ,{
"endprocedure" , DoEndprocedure , 0, 0}
80 ,{
"endswitch" , DoPreEndSwitch , 0, 0}
81 ,{
"exchange" , DoPreExchange , 0, 0}
82 ,{
"external" , DoExternal , 0, 0}
83 ,{
"factdollar" , DoFactDollar , 0, 0}
84 ,{
"fromexternal" , DoFromExternal , 0, 0}
86 ,{
"ifdef" , DoIfydef , 0, 0}
87 ,{
"ifndef" , DoIfndef , 0, 0}
88 ,{
"include" , DoInclude , 0, 0}
89 ,{
"inside" , DoInside , 0, 0}
90 ,{
"message" , DoMessage , 0, 0}
91 ,{
"namespace" , DoNamespace , 0, 0}
92 ,{
"opendictionary", DoPreOpenDictionary,0,0}
93 ,{
"optimize" , DoOptimize , 0, 0}
94 ,{
"pipe" , DoPipe , 0, 0}
95 ,{
"preout" , DoPreOut , 0, 0}
97 ,{
"printtimes" , DoPrePrintTimes, 0, 0}
98 ,{
"procedure" , DoProcedure , 0, 0}
99 ,{
"procedureextension" , DoPrcExtension , 0, 0}
100 ,{
"prompt" , DoPrompt , 0, 0}
101 ,{
"redefine" , DoRedefine , 0, 0}
102 ,{
"remove" , DoPreRemove , 0, 0}
103 ,{
"reset" , DoPreReset , 0, 0}
104 ,{
"reverseinclude" , DoReverseInclude , 0, 0}
105 ,{
"rmexternal" , DoRmExternal , 0, 0}
106 ,{
"rmseparator" , DoPreRmSeparator,0, 0}
107 ,{
"setexternal" , DoSetExternal , 0, 0}
108 ,{
"setexternalattr" , DoSetExternalAttr , 0, 0}
109 ,{
"setflag" , DoSetUserFlag , 0, 0}
110 ,{
"setrandom" , DoSetRandom , 0, 0}
111 ,{
"show" , DoPreShow , 0, 0}
112 ,{
"skipextrasymbols" , DoSkipExtraSymbols , 0, 0}
113 ,{
"sortreallocate", DoPreSortReallocate , 0, 0}
115 ,{
"startfloat" , DoStartFloat , 0, 0}
117 ,{
"switch" , DoPreSwitch , 0, 0}
118 ,{
"system" , DoSystem , 0, 0}
119 ,{
"terminate" , DoTerminate , 0, 0}
120 ,{
"timeoutafter" , DoTimeOutAfter , 0, 0}
121 ,{
"toexternal" , DoToExternal , 0, 0}
122 ,{
"undefine" , DoUndefine , 0, 0}
123 ,{
"use" , DoUse , 0, 0}
124 ,{
"usedictionary", DoPreUseDictionary,0,0}
125 ,{
"write" , DoPreWrite , 0, 0}
141 while ( AC.CurrentStream ) {
142 c = GetFromStream(AC.CurrentStream);
143 if ( c != ENDOFSTREAM ) {
146 && AC.NoShowInput <= 0
147 && AC.CurrentStream->type != PREVARSTREAM )
149 if ( AC.NoShowInput <= 0 && AC.CurrentStream->type != PREVARSTREAM )
154 AC.CurrentStream = CloseStream(AC.CurrentStream);
155 if ( stopdelay && AC.CurrentStream == oldstream ) {
156 stopdelay = 0; AP.AllowDelay = 1;
167void ClearPushback(
void)
185UBYTE GetChar(
int level)
187 UBYTE namebuf[MAXPRENAMESIZE+2], c, *s, *t;
188 static UBYTE lastchar, charinbuf = 0;
189 int i, j, raiselow, olddelay;
195 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0;
return(c); }
196 if ( charinbuf ) { c = charinbuf; charinbuf = 0;
return(c); }
200 charinbuf = GetInput();
201 if ( charinbuf != LINEFEED ) {
202 pushbackchar = charinbuf;
207 while ( ( c = GetInput() ) ==
' ' || c ==
'\t' ) {}
209 else if ( c ==
'\'' || c ==
'`' ) {
210 if ( AP.DelayPrevar == 1 && c ==
'\'' ) {
217 if ( c ==
'!' && lastchar ==
'`' ) {
218 if ( stopdelay == 0 ) oldstream = AC.CurrentStream;
223 if ( c ==
'~' && lastchar ==
'`' ) {
224 if ( AP.AllowDelay ) {
234 olddelay = AP.DelayPrevar;
238 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0; }
239 else { c = GetInput(); }
240 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
241 && lastchar !=
'\\' ) ) {
245 if ( PreCalc() == 0 ) Terminate(-1);
248 MesPrint(
"@Illegal set inside preprocessor variable name");
252 if ( c ==
'`' && lastchar !=
'\\' ) {
254 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
255 && lastchar !=
'\\' ) ) {
259 if ( lastchar ==
'\\' ) { i--; lastchar = 0; }
262 if ( i > MAXPRENAMESIZE ) {
264 Error1(
"Preprocessor variable name too long: ",namebuf);
269 Error1(
"Unmatched quotes for preprocessor variable",namebuf);
271 AP.DelayPrevar = olddelay;
272 if ( namebuf[0] ==
'$' ) {
273 raiselow = PRENOACTION;
274 if ( AP.PreproFlag && *AP.preStart) {
277 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
278 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
279 && GetDollar(namebuf+1) < 0 ) {
287 if ( *s ==
'[' ) {
while ( *s ) s++; }
289 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
290 raiselow = PRELOWERAFTER;
291 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
292 raiselow = PRERAISEAFTER;
294 if ( OpenStream(namebuf+1,DOLLARSTREAM,0,raiselow) == 0 ) {
296 MesPrint(
"@Undefined variable %s used as preprocessor variable",
303 raiselow = PRENOACTION;
304 if ( AP.PreproFlag && *AP.preStart) {
307 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
308 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
316 if ( *s ==
'_' ) s++;
317 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
318 raiselow = PRELOWERAFTER;
319 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
320 raiselow = PRERAISEAFTER;
321 else if ( *s ==
'(' && namebuf[i-2] ==
')' ) {
333 *s++ = 0; namebuf[i-2] = 0;
334 if ( StrICmp(namebuf,(UBYTE *)
"random_") == 0 ) {
336 ranvalue = PreRandom(s);
338 M_free(ranvalue,
"PreRandom");
341 else if ( StrICmp(namebuf,(UBYTE *)
"tolower_") == 0 ) {
343 while ( *ss ) { *ss = (UBYTE)(tolower(*ss)); ss++; }
347 else if ( StrICmp(namebuf,(UBYTE *)
"toupper_") == 0 ) {
349 while ( *ss ) { *ss = (UBYTE)(toupper(*ss)); ss++; }
353 else if ( StrICmp(namebuf,(UBYTE *)
"takeleft_") == 0 ) {
356 while ( *ss !=
',' && *ss ) ss++;
360 while ( FG.cTable[*ss] == 1 ) x = 10*x + (*ss++ -
'0');
361 if ( x > nsize ) x = nsize;
367 else if ( StrICmp(namebuf,(UBYTE *)
"takeright_") == 0 ) {
370 while ( *ss !=
',' && *ss ) ss++;
374 while ( FG.cTable[*ss] == 1 ) x = 10*x + (*ss++ -
'0');
375 if ( x > nsize ) x = nsize;
383 else if ( StrICmp(namebuf,(UBYTE *)
"keepleft_") == 0 ) {
386 while ( *ss !=
',' && *ss ) ss++;
390 while ( FG.cTable[*ss] == 1 ) x = 10*x + (*ss++ -
'0');
391 if ( x > nsize ) x = nsize;
398 else if ( StrICmp(namebuf,(UBYTE *)
"keepright_") == 0 ) {
401 while ( *ss !=
',' && *ss ) ss++;
405 while ( FG.cTable[*ss] == 1 ) x = 10*x + (*ss++ -
'0');
406 if ( x > nsize ) x = nsize;
414 if ( *s ==
'\\' ) s++;
415 if ( *s ==
',' ) { *s = 0; nargs++; }
418 GetPreVar(namebuf,WITHERROR);
421 MesPrint(
"@Illegal use of arguments in preprocessor variable %s",namebuf);
424 if ( p->nargs <= 0 || ( p->wildarg == 0 && nargs != p->nargs )
425 || ( p->wildarg > 0 && nargs < p->nargs-1 ) ) {
426 MesPrint(
"@Arguments of macro %s do not match",namebuf);
429 if ( p->wildarg > 0 ) {
434 for ( j = 0; j < p->wildarg; j++ ) {
438 for ( j = 0; j < nargs-p->nargs; j++ ) {
450 p_offset = p - PreVar;
451 for ( j = 0; j < p->nargs; j++ ) {
452 if ( ( nargs == p->nargs-1 ) && ( *t ==
'?' ) ) {
460 p = PreVar + p_offset;
466 if ( ( stream = OpenStream(namebuf,PREVARSTREAM,0,raiselow) ) == 0 ) {
471 else if ( stream->inbuffer == 0 ) {
473 if ( level > 0 && c ==
'\'' )
return(c);
479 else if ( c ==
'{' ) {
480 if ( PreCalc() == 0 ) Terminate(-1);
497 if ( c == LINEFEED ) {
498 AM.OutBuffer[AP.InOutBuf++] = c;
499 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
503 if ( AP.InOutBuf >= AM.OutBufSize || c == LINEFEED ) {
504 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
507 AM.OutBuffer[AP.InOutBuf++] = c;
516void UnsetAllowDelay(
void)
518 if ( ThePreVar != 0 ) {
519 if ( ThePreVar->
nargs > 0 ) AP.AllowDelay = 0;
536static UBYTE *yes = (UBYTE *)
"1";
537static UBYTE *no = (UBYTE *)
"0";
538static UBYTE numintopolynomial[12];
540static Vector(UBYTE, exprstr);
542UBYTE *GetPreVar(UBYTE *name,
int flag)
547 UBYTE *t, c = 0, *tt = 0;
548 t = name;
while ( *t ) t++;
549 if ( t[-1] ==
'-' && t[-2] ==
'-' && t-2 > name && t[-3] !=
'_' ) {
550 t -= 2; c = *t; *t = 0; tt = t;
552 else if ( t[-1] ==
'+' && t[-2] ==
'+' && t-2 > name && t[-3] !=
'_' ) {
553 t -= 2; c = *t; *t = 0; tt = t;
555 else if ( StrICmp(name,(UBYTE *)
"time_") == 0 ) {
557 LONG millitime, timepart;
558 int timepart1, timepart2;
559 static char timestring[40];
561 millitime = GetRunningTime();
562 timepart = millitime%1000;
565 timepart1 = timepart / 10;
566 timepart2 = timepart % 10;
567 NumToStr(millibuf,millitime);
568 snprintf(timestring,40,
"%s.%1d%1d",millibuf,timepart1,timepart2);
569 return((UBYTE *)timestring);
571 else if ( ( StrICmp(name,(UBYTE *)
"timer_") == 0 )
572 || ( StrICmp(name,(UBYTE *)
"stopwatch_") == 0 ) ) {
573 static char timestring[40];
574 snprintf(timestring,40,
"%ld",(
long int)(GetRunningTime() - AP.StopWatchZero));
575 return((UBYTE *)timestring);
577 else if ( StrICmp(name, (UBYTE *)
"numactiveexprs_") == 0 ) {
580 for ( i = 0; i < NumExpressions; i++ ) {
582 switch ( e->status ) {
583 case LOCALEXPRESSION:
584 case GLOBALEXPRESSION:
585 case UNHIDELEXPRESSION:
586 case UNHIDEGEXPRESSION:
587 case INTOHIDELEXPRESSION:
588 case INTOHIDEGEXPRESSION:
597 else if ( StrICmp(name, (UBYTE *)
"activeexprnames_") == 0 ) {
601 for ( i = 0; i < NumExpressions; i++ ) {
605 switch ( e->status ) {
606 case LOCALEXPRESSION:
607 case GLOBALEXPRESSION:
608 case UNHIDELEXPRESSION:
609 case UNHIDEGEXPRESSION:
610 case INTOHIDELEXPRESSION:
611 case INTOHIDEGEXPRESSION:
612 s = AC.exprnames->namebuffer + e->name;
617 if ( j > 0 ) p[j++] =
',';
618 for ( k = 0; k < len; k++ ) {
619 if ( s[k] ==
',' || s[k] ==
'|' ) p[j++] =
'\\';
628 else if ( StrICmp(name, (UBYTE *)
"path_") == 0 ) {
638 while ( *t && *t !=
'_' ) t++;
639 for ( i = NumPre-1; i >= 0; i-- ) {
640 if ( *t ==
'_' && ( StrICmp(name,PreVar[i].name) == 0 ) ) {
642 ThePreVar = PreVar+i;
643 return(PreVar[i].value);
645 else if ( StrCmp(name,PreVar[i].name) == 0 ) {
647 ThePreVar = PreVar+i;
648 return(PreVar[i].value);
652 if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS_") == 0 )
goto extrashort;
654 if ( StrICmp(name,(UBYTE *)
"UNCHANGED") == 0 ) mode = 1;
655 else if ( StrICmp(name,(UBYTE *)
"ZERO") == 0 ) mode = 0;
656 else if ( StrICmp(name,(UBYTE *)
"SHOWINPUT") == 0 ) {
659 if ( AC.NoShowInput > 0 )
return(no);
662 else if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS") == 0 ) {
665 number = cbuf[AM.sbufnum].numrhs;
666 t = numintopolynomial;
668 return(numintopolynomial);
675 if ( GetName(AC.exprnames,t,&number,NOAUTO) == CEXPRESSION ) {
677 if ( ( Expressions[number].vflags & ( 1 << mode ) ) != 0 )
688 if ( ( AR.expflags & ( 1 << mode ) ) == 0 )
return(yes);
693 if ( ( t = (UBYTE *)(getenv((
char *)(name))) ) != 0 ) {
699 if ( flag == WITHERROR ) {
700 Error1(
"Undefined preprocessor variable",name);
724int PutPreVar(UBYTE *name, UBYTE *value, UBYTE *args,
int mode)
726 int i, ii, num = 2, nnum = 2, numargs = 0;
727 UBYTE *s, *t, *u = 0;
729 if ( value == 0 && name[0] !=
'?' ) {
730 MesPrint(
"@Illegal empty value for preprocessor variable %s",name);
736 if ( *s !=
' ' && *s !=
'\t' ) num++;
743 if ( StrCmp(name,PreVar[i].name) == 0 ) {
750 if ( i < 0 ) { p = (
PREVAR *)FromList(&AP.PreVarList); ii = p - PreVar; }
751 else { p = &(PreVar[i]); ii = i; }
753 s = value;
while ( *s ) { s++; num++; }
759 while ( *s ) { s++; nnum++; }
766 if ( value && p->value ) {
769 while ( *s ) *t++ = *s++;
776 s = name;
while ( *s ) { s++; num++; }
777 t = (UBYTE *)Malloc1(num,
"PreVariable");
779 s = name;
while ( *s ) *t++ = *s++; *t++ = 0;
782 s = value;
while ( *s ) *t++ = *s++; *t = 0;
783 if ( AM.atstartup && t[-1] ==
'\n' ) t[-1] = 0;
789 t++; p->argnames = t;
792 if ( *s ==
' ' || *s ==
'\t' ) { s++;
continue; }
794 s++; *t++ = 0; numargs++;
795 while ( *s ==
' ' || *s ==
'\t' ) s++;
797 if ( p->wildarg > 0 ) {
798 Error0(
"More than one ?var in #define");
800 p->wildarg = numargs;
803 else if ( *s ==
'?' && first ) {
804 p->wildarg = 1; *t++ = *s++;
806 else { *t++ = *s++; }
817 if ( u ) M_free(u,
"replace PreVar value");
826void PopPreVars(
int tonumber)
828 PREVAR *p = &(PreVar[NumPre]);
829 while ( NumPre > tonumber ) {
831 M_free(p->name,
"popping PreVar");
832 p->name = p->value = 0;
841void IniModule(
int type)
845 CBUF *C = cbuf+AC.cbufnum;
859 AR.StoreData.dirtyflag = 0;
860 AC.bracketindexflag = 0;
861 AT.bracketindexflag = 0;
866 AC.RhsExprInModuleFlag = 0;
869 PF.slavebuf.PObuffer=NULL;
870 for(i=0; i<NumExpressions; i++)
871 Expressions[i].vflags &= ~ISINRHS;
883 w = C->
rhs; i = C->maxrhs;
884 do { *w++ = 0; }
while ( --i > 0 );
887 w = C->
lhs; i = C->maxlhs;
888 do { *w++ = 0; }
while ( --i > 0 );
891 C->numlhs = C->numrhs = 0;
892 ClearTree(AC.cbufnum);
893 while ( AC.NumLabels > 0 ) {
895 if ( AC.LabelNames[AC.NumLabels] ) M_free(AC.LabelNames[AC.NumLabels],
"LabelName");
900 AC.Commercial[0] = 0;
902 AC.IfStack = AC.IfHeap;
910 AC.MustTestTable = 0;
915 AC.SymChangeFlag = 0;
916 AP.lhdollarerror = 0;
917 AR.PolyFun = AC.lPolyFun;
918 AR.PolyFunInv = AC.lPolyFunInv;
919 AR.PolyFunType = AC.lPolyFunType;
920 AR.PolyFunExp = AC.lPolyFunExp;
921 AR.PolyFunVar = AC.lPolyFunVar;
922 AR.PolyFunPow = AC.lPolyFunPow;
923 AC.mparallelflag = AC.parallelflag | AM.hparallelflag;
924 AC.inparallelflag = 0;
925 AC.mProcessBucketSize = AC.ProcessBucketSize;
926 NumPotModdollars = 0;
927 AC.topolynomialflag = 0;
929 if ( AM.totalnumberofthreads > 1 ) AS.MultiThreaded = 1;
930 else AS.MultiThreaded = 0;
931 for ( i = 1; i < AM.totalnumberofthreads; i++ ) {
932 AB[i]->T.S0->PolyWise = 0;
943void IniSpecialModule(
int type)
953void PreProcessor(
void)
955 int moduletype = FIRSTMODULE;
957 int error1 = 0, error2 = 0, retcode, retval;
959 AP.StopWatchZero = GetRunningTime();
961 AP.PreContinuation = 0;
962 AP.PreAssignLevel = 0;
964 AC.iPointer = AC.iBuffer;
967 if ( AC.CheckpointFlag == -1 )
DoRecovery(&moduletype);
968 AC.CheckpointStamp = Timer(0);
973 IniModule(moduletype);
979 NumToStr(buf,AC.CModule);
983 if ( specialtype ) IniSpecialModule(specialtype);
987 if ( c == AP.ComChar ) {
989 if ( AC.CurrentStream->FoldName ) {
991 if ( *t && t[1] && t[2] ==
'#' && t[3] ==
']' ) {
993 while ( *t ==
' ' || *t ==
'\t' ) t++;
994 s = AC.CurrentStream->FoldName;
995 while ( *s == *t ) { s++; t++; }
996 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t'
998 while ( *t ==
' ' || *t ==
'\t' ) t++;
1000 AC.CurrentStream = CloseStream(AC.CurrentStream);
1008 while ( c ==
' ' || c ==
'\t' ) c = GetChar(0);
1009 if ( c == LINEFEED )
continue;
1010 if ( c == ENDOFINPUT ) {
1012 Warning(
".end instruction generated");
1013 moduletype = ENDMODULE; specialtype = 0;
1017 if ( PreProInstruction() ) { error1++; error2++; AP.preError++; }
1020 else if ( c ==
'.' ) {
1021 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
1022 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
1026 if ( ModuleInstruction(&moduletype,&specialtype) ) { error2++; AP.preError++; }
1027 if ( specialtype ) SetSpecialMode(moduletype,specialtype);
1028 if ( AP.PreInsideLevel != 0 ) {
1029 MesPrint(
"@end of module instructions may not be used inside");
1030 MesPrint(
"@the scope of a %#inside %#endinside construction.");
1033 if ( AC.RepLevel > 0 ) {
1034 MesPrint(
"&EndRepeat statement(s) missing");
1035 error2++; AP.preError++;
1037 if ( AC.tablecheck == 0 ) {
1039 if ( TestTables() ) { error2++; AP.preError++; }
1041 if ( AP.PreContinuation ) {
1043 MesPrint(
"&Unfinished statement. Missing ;?");
1045 if ( moduletype == GLOBALMODULE ) MakeGlobal();
1047endmodule:
if ( error2 == 0 && AM.qError == 0 ) {
1048 retcode = ExecModule(moduletype);
1050 if(PF.slavebuf.PObuffer!=NULL){
1051 M_free(PF.slavebuf.PObuffer,
"PF inbuf");
1052 PF.slavebuf.PObuffer=NULL;
1056 if ( retcode < 0 ) error1++;
1057 if ( retcode ) { error2++; AP.preError++; }
1062 for ( j = 0, e = Expressions; j < NumExpressions; j++, e++ ) {
1063 if ( e->replace == NEWLYDEFINEDEXPRESSION ) e->replace = REGULAREXPRESSION;
1066 switch ( moduletype ) {
1068 if ( ExecStore() ) error1++;
1072 error1 = error2 = AP.preError = 0;
1074 PutPreVar((UBYTE *)
"DATE_",(UBYTE *)MakeDate(),0,1);
1076 if ( AM.resetTimeOnClear ) {
1083 AP.StopWatchZero = GetRunningTime();
1086 Terminate( -( error1 | error2 ) );
1091 if ( AC.exprfillwarning > 0 ) {
1092 AC.exprfillwarning = 0;
1094 if ( AC.CheckpointFlag && error1 == 0 && error2 == 0 )
DoCheckpoint(moduletype);
1098 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
1099 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
1105 if ( AP.PreContinuation ) {
1106 retval = LoadStatement(OLDSTATEMENT);
1109 AC.CurrentStream->prevline = AC.CurrentStream->linenumber;
1110 retval = LoadStatement(NEWSTATEMENT);
1114 if ( retval == -1 ) AP.PreContinuation = 0;
1115 else AP.PreContinuation = 1;
1118 else if ( retval > 0 ) AP.PreContinuation = 0;
1119 else AP.PreContinuation = 1;
1120 if ( error1 == 0 && !AP.PreContinuation ) {
1121 if ( ( AP.PreDebug & PREPROONLY ) == 0 ) {
1122 int onpmd = NumPotModdollars;
1124 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
1125 if ( AP.PreAssignFlag ) AC.RhsExprInModuleFlag = 0;
1127 if ( AP.PreOut || ( AP.PreDebug & DUMPTOCOMPILER )
1129 MesPrint(
" %s",AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1130 retcode = CompileStatement(AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1131 if ( retcode < 0 ) error1++;
1132 if ( retcode ) { error2++; AP.preError++; }
1133 if ( AP.PreAssignFlag ) {
1134 if ( retcode == 0 ) {
1135 if ( ( retcode = CatchDollar(0) ) < 0 ) error1++;
1136 else if ( retcode > 0 ) { error2++; AP.preError++; }
1138 else CatchDollar(-1);
1140 if ( AP.PreAssignLevel <=0 )
1141 AP.PreAssignFlag = 0;
1142 NumPotModdollars = onpmd;
1144 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
1149 MesPrint(
" %s",AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1152 else if ( !AP.PreContinuation ) {
1153 if ( AP.PreAssignLevel > 0 ) {
1155 if ( AP.PreAssignLevel <=0 )
1156 AP.PreAssignFlag = 0;
1172int PreProInstruction(
void)
1182 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
1184 if ( ( StrICmp(AP.preStart,(UBYTE *)
"case") == 0
1185 || StrICmp(AP.preStart,(UBYTE *)
"default") == 0 )
1186 && AP.PreSwitchModes[AP.PreSwitchLevel] == SEARCHINGPRECASE ) {
1189 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
1190 else { LoadInstruction(1); }
1192 else if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
1194 if ( ( StrICmp(AP.preStart,(UBYTE *)
"else") == 0
1195 || StrICmp(AP.preStart,(UBYTE *)
"elseif") == 0 )
1196 && AP.PreIfStack[AP.PreIfLevel] == LOOKINGFORELSE ) {
1199 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
1210 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1211 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1214 else if ( *t ==
'+' ) {
1215 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1216 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1219 else if ( *t ==
':' ) {}
1222 key = FindKeyWord(t,precommands,
sizeof(precommands)/
sizeof(
KEYWORD));
1230 MesPrint(
"@Unrecognized preprocessor instruction: %s",t);
1234 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
1237 while ( ( t[-1] ==
';' ) && ( t[-2] !=
'\\' ) ) {
1240 return((key->func)(s));
1260int LoadInstruction(
int mode)
1262 UBYTE *s, *sstart, *t, c, cp;
1263 LONG position, fillpos = 0;
1264 int bralevel = 0, parlevel = 0, first = 1;
1269 if ( s[1] != LINEFEED && s[1] != ENDOFINPUT ) {
1272 else { oldmode = mode;
return(0); }
1274 else { s = AP.preStart; }
1277 if ( ( mode & 1 ) == 1 ) {
1278 if ( pushbackchar && ( mode == 3 || mode == 5 ) ) {
1279 c = pushbackchar; pushbackchar = 0;
1281 else c = GetInput();
1287 if ( mode == 2 && c ==
';' )
break;
1288 if ( ( mode == 1 || mode == 5 ) && c == LINEFEED )
break;
1289 if ( mode == 3 && FG.cTable[c] != 0 ) {
1292 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1293 *s++ =
'g'; *s++ =
'n'; *s++ =
' '; *s = 0;
1295 if ( c ==
'\'' || c ==
'`' ) {
1299 AP.preFill = s; *s++ = 0; *s = c;
1304 if ( mode == 0 && first ) {
1306dodollar: s = sstart;
1307 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1308 *s++ =
'g'; *s++ =
'n'; *s = 0;
1313 if ( c ==
' ' || c ==
'\t' || c ==
',' ) {}
1316 else if ( mode == 1 && first && c ==
'$' && oldmode == 3 )
goto dodollar;
1317 if ( c == ENDOFINPUT || ( c == LINEFEED
1319 && quotelevel == 0 ) ) {
1320 if ( mode == 2 && c == ENDOFINPUT ) {
1321 MesPrint(
"@Unexpected end of instruction");
1332 if ( mode != 2 )
break;
1336 if ( ( mode == 1 ) || ( mode == 5 ) ) c = GetInput();
1340 if ( c == ENDOFINPUT ) {
1341 MesPrint(
"@Unmatched \"");
1342 if ( mode == 2 && c == ENDOFINPUT ) {
1343 MesPrint(
"@Unexpected end of instruction");
1353 else if ( c == LINEFEED ) {}
1354 else if ( c ==
'"' ) { *s++ =
'\\'; }
1359 else if ( c ==
'"' ) {
1364 else if ( c ==
'\\' ) {
1365 if ( ( mode == 1 ) || ( mode == 5 ) ) cp = GetInput();
1369 if ( cp == LINEFEED )
continue;
1370 if ( mode != 2 || cp !=
';' ) *s++ = c;
1373 else if ( c ==
'"' ) {
1379 while ( FG.cTable[*t] <= 1 ) t++;
1381 if ( ( StrICmp(AP.preStart,(UBYTE *)
"define") == 0 )
1382 || ( StrICmp(AP.preStart,(UBYTE *)
"redefine") == 0 ) ) {
1384 oldstream = AC.CurrentStream;
1389 else if ( quotelevel == 0 && bralevel == 0 && c ==
'(' ) {
1391 while ( FG.cTable[*t] <= 1 ) t++;
1393 if ( ( parlevel == 0 )
1394 && ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 ) ) {
1396 oldstream = AC.CurrentStream;
1401 else if ( quotelevel == 0 && bralevel == 0 && c ==
')' ) {
1404 else if ( quotelevel == 0 && parlevel == 0 && c ==
'{' ) {
1406 while ( FG.cTable[*t] <= 1 ) t++;
1408 if ( ( bralevel == 0 )
1409 && ( ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 )
1410 || ( StrICmp(AP.preStart,(UBYTE *)
"do") == 0 ) ) ) {
1412 oldstream = AC.CurrentStream;
1417 else if ( quotelevel == 0 && parlevel == 0 && c ==
'}' ) {
1419 if ( bralevel < 0 ) {
1421 MesPrint(
"@Unmatched brackets");
1428 if ( s >= (AP.preStop-1) ) {
1430 position = s - AP.preStart;
1431 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1432 ppp = &(AP.preStart);
1433 if ( DoubleLList((
void ***)ppp,&AP.pSize,
sizeof(UBYTE),
1434 "instruction buffer") ) { *s = 0; oldmode = mode;
return(-1); }
1435 AP.preStop = AP.preStart + AP.pSize-3;
1436 s = AP.preStart + position;
1437 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1444 if ( ExpandTripleDots(1) < 0 )
return(-1);
1463int LoadStatement(
int type)
1466 int retval = 0, stringlevel = 0, newstatement = 0;
1467 if ( type == NEWSTATEMENT ) { AP.eat = 1; newstatement = 1;
1468 s = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; }
1469 else { s = AC.iPointer; *s = 0; c =
' ';
goto blank; }
1473 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1474 if ( stringlevel == 0 ) {
1475 if ( c == LINEFEED ) {
1476 if ( AP.eat < 0 ) { s--; AP.eat = 0; }
1480 if ( AP.eat < 0 ) { s--; AP.eat = 0; }
1481 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1482 if ( c != LINEFEED ) UngetChar(c);
1489 if ( cp == LINEFEED )
continue;
1494 if ( stringlevel == 0 ) stringlevel = 1;
1495 else stringlevel = 0;
1498 else if ( stringlevel == 0 ) {
1499 if ( c ==
'\t' ) c =
' ';
1501blank:
if ( newstatement < 0 ) newstatement = 0;
1502 if ( AP.eat && ( newstatement == 0 ) )
continue;
1505 if ( newstatement > 0 ) newstatement = -1;
1507 else if ( chartype[c] <= 3 ) {
1509 if ( newstatement < 0 ) newstatement = 0;
1511 else if ( c ==
',' ) {
1512 if ( newstatement > 0 ) {
1517 else if ( AP.eat == -2 ) { AP.eat = 1;
continue; }
1518 else {
goto doall; }
1521doall:;
if ( AP.eat < 0 ) {
1522 if ( newstatement == 0 ) s--;
1523 else { newstatement = 0; }
1525 else if ( newstatement == 1 ) newstatement = 0;
1527 if ( c ==
'*' && s > AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] && s[-1] ==
'*' ) {
1533 if ( s >= AC.iStop ) {
1534 if ( !AP.iBufError ) {
1535 LONG position = s - AC.iBuffer;
1536 LONG position2 = AC.iPointer - AC.iBuffer;
1537 UBYTE **ppp = &(AC.iBuffer);
1538 if ( DoubleLList((
void ***)ppp,&AC.iBufferSize
1539 ,
sizeof(UBYTE),
"statement buffer") ) {
1540 *s = 0; retval = -1; AP.iBufError = 1;
1542 AC.iPointer = AC.iBuffer + position2;
1543 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1544 s = AC.iBuffer + position;
1546 if ( AP.iBufError ) {
1549 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1551 if ( stringlevel > 0 ) stringlevel = 0;
1552 else stringlevel = 1;
1554 else if ( c == LINEFEED && !stringlevel ) { retval = -2;
break; }
1555 else if ( c ==
';' && !stringlevel ) {
1556 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1557 if ( c != LINEFEED ) UngetChar(c);
1561 else if ( c ==
'\\' ) c = GetChar(0);
1570 if ( stringlevel > 0 ) {
1571 MesPrint(
"@Unbalanced \". Runaway string");
1574 if ( retval == 1 ) {
1575 if ( ExpandTripleDots(0) < 0 ) retval = -1;
1585static inline int IsSignChar(UBYTE c)
1587 return c ==
'+' || c ==
'-';
1590static inline int IsAlphanumericChar(UBYTE c)
1592 return FG.cTable[c] == 0 || FG.cTable[c] == 1;
1595static inline int CanParseSignedNumber(
const UBYTE *s)
1597 while ( IsSignChar(*s) ) s++;
1598 return FG.cTable[*s] == 1;
1601int ExpandTripleDots(
int par)
1603 UBYTE *s, *s1, *s2, *n1, *n2, *t1, *t2, *startp, operator1, operator2, c, cc;
1604 UBYTE *nBuffer, *strngs, *Buffer, *Stop;
1605 LONG withquestion, x1, x2, y1, y2, number, inc, newsize, pow, fullsize;
1606 int i, error = 0, i1 ,i2, ii, *nums = 0;
1609 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1612 Buffer = AP.preStart; Stop = AP.preStop;
1614 s = Buffer;
while ( *s ) s++;
1615 fullsize = s - Buffer;
1616 if ( fullsize < 7 )
return(error);
1620 if ( *s !=
'.' || ( s[-1] !=
',' && FG.cTable[s[-1]] != 5 ) )
1622 if ( s[-1] ==
'%' || s[-1] ==
'^' || s[1] !=
'.' || s[2] !=
'.' )
1626 if ( *s != s[-4] && ( *s !=
'+' || s[-4] !=
'-' )
1627 && ( *s !=
'-' || s[-4] !=
'+' ) ) {
1628 MesPrint(
"&Improper operators for ...");
1633 if ( operator1 ==
':' ) operator1 =
'.';
1634 if ( operator2 ==
':' ) operator2 =
'.';
1644 if ( *s2 !=
'<' || *s1 !=
'>' ) {
1646 withquestion = ( *s1 ==
'?' ); s1--;
1647 while ( FG.cTable[*s1] == 1 && s1 >= Buffer ) s1--;
1649 if ( FG.cTable[*n1] != 1 ) {
1650 MesPrint(
"&No first number in ... operator");
1653 while ( FG.cTable[*s1] <= 1 && s1 >= Buffer ) s1--;
1659 while ( t1 < n1 && *t1 == *t2 ) { t1++; t2++; }
1661 if ( FG.cTable[*t2] != 1 ) {
1662 MesPrint(
"&No second number in ... operator");
1666 while ( FG.cTable[*t2] == 1 ) x2 = 10*x2 + *t2++ -
'0';
1668 while ( FG.cTable[*t1] == 1 ) x1 = 10*x1 + *t1++ -
'0';
1669 if ( withquestion != ( *t2 ==
'?' ) ) {
1670 MesPrint(
"&Improper use of ? in ... operator");
1671 if ( *t2 ==
'?' ) t2++;
1674 else if ( withquestion ) t2++;
1675 if ( FG.cTable[*t2] <= 2 ) {
1676 MesPrint(
"&Illegal object after ... construction");
1679 c = *n1; *n1 = 0; s = t2;
1680 if ( error )
continue;
1689 if ( x2 < x1 ) { number = x1-x2; inc = -1; y1 = x2; y2 = x1; }
1690 else { number = x2-x1; inc = 1; y1 = x1; y2 = x2; }
1691 newsize = (number+1)*(n1-s1)
1693 +(number+1)*(withquestion?1:0)
1696 for ( i = 1; i < 10; i++, pow *= 10 ) {
1697 if ( y1 >= pow ) newsize += number+1;
1698 else if ( y2 >= pow ) newsize += y2-pow+1;
1701 while ( Buffer+(fullsize+newsize-(s-s1)) >= Stop ) {
1702 LONG strpos = s1-Buffer;
1703 LONG endstr = n1-Buffer;
1704 LONG startq = startp - Buffer;
1705 LONG position = s - Buffer;
1708 LONG position2 = AC.iPointer - AC.iBuffer;
1709 ppp = &(AC.iBuffer);
1710 if ( DoubleLList((
void ***)ppp,&AC.iBufferSize
1711 ,
sizeof(UBYTE),
"statement buffer") ) {
1714 AC.iPointer = AC.iBuffer + position2;
1715 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1716 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1720 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1721 ppp = &(AP.preStart);
1722 if ( DoubleLList((
void ***)ppp,&AP.pSize,
sizeof(UBYTE),
1723 "instruction buffer") ) {
1726 AP.preStop = AP.preStart + AP.pSize-3;
1727 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1728 Buffer = AP.preStart; Stop = AP.preStop;
1730 s = Buffer + position;
1731 n1 = Buffer + endstr;
1732 s1 = Buffer + strpos;
1733 startp = Buffer + startq;
1741 if ( newsize > (s-s1) ) {
1742 t2 = Buffer + fullsize;
1743 t1 = t2 + (newsize - (s-s1));
1745 while ( t2 > s ) { *--t1 = *--t2; }
1747 else if ( newsize < (s-s1) ) {
1748 t1 = s1 + newsize; t2 = s; s = t1;
1749 while ( *t2 ) *t1++ = *t2++;
1752 for ( x1 += inc, t1 = startp; number > 0; number--, x1 += inc ) {
1754 cc = operator1; operator1 = operator2; operator2 = cc;
1755 t2 = s1;
while ( *t2 ) *t1++ = *t2++;
1758 *t1++ =
'0' + x2 % 10;
1762 while ( s2 > n2 ) { cc = *s2; *s2 = *n2; *n2++ = cc; s2--; }
1763 if ( withquestion ) *t1++ =
'?';
1765 fullsize += newsize - ( s - s1 );
1770 while ( s1 > Buffer ) {
1771 if ( *s1 ==
'<' )
break;
1776 if ( *t2 ==
'>' )
break;
1779 if ( *s1 !=
'<' || *t2 !=
'>' ) {
1780 MesPrint(
"&Illegal attempt to use ... operator");
1784 nums = (
int *)Malloc1((t1-s1)*2*(
sizeof(int)+
sizeof(UBYTE))
1786 strngs = (UBYTE *)(nums + 2*(t1-s1));
1787 n1 = s1; n2 = s2; ii = -1; i = 0;
1789 while ( n1 < t1 || n2 < t2 ) {
1791 if ( CanParseSignedNumber(n1) && CanParseSignedNumber(n2) ) {
1800 int sign1 = IsSignChar(*n1);
1801 int sign2 = IsSignChar(*n2);
1802 int inword1 = s1 < n1 && IsAlphanumericChar(n1[-1]);
1803 int inword2 = s2 < n2 && IsAlphanumericChar(n2[-1]);
1804 if ( ( sign1 ^ sign2 ) && ( inword1 || inword2 ) )
break;
1805 if ( sign1 || sign2 ) {
1810 if ( *n1 == *n2 ) { *s++ = *n1++; n2++;
continue; }
1813 ParseSignedNumber(x1,n1)
1814 ParseSignedNumber(x2,n2)
1816 if ( s != strngs && ( s[-1] ==
'+' || s[-1] ==
'-' ) ) {
1826 nums[2*i] = x1; nums[2*i+1] = x2;
1830 if ( n1 < t1 || n2 < t2 ) {
1831 MesPrint(
"&Improper use of ... operator.");
1832theend: M_free(nums,
"Expand ...");
1836 if ( i == 0 ) ii = 0;
1838 ii = nums[0] - nums[1];
1839 if ( ii < 0 ) ii = -ii;
1840 for ( x1 = 1; x1 < i; x1++ ) {
1841 x2 = nums[2*x1]-nums[2*x1+1];
1842 if ( x2 < 0 ) x2 = -x2;
1844 MesPrint(
"&Improper synchronization of numbers in ... operator");
1859 x2 = s - strngs - i;
1860 for ( i1 = 0; i1 < i; i1++ ) {
1863 if ( i2 < 0 ) i2 = -i2;
1864 if ( x1 < 0 ) x1 = -x1;
1865 if ( x1 > i2 ) i2 = x1;
1867 while ( i2 > 0 ) { i2 /= 10; x1++; }
1873 x2 +=
sizeof(UBYTE *);
1874 x2 = x2 - (x2 & (
sizeof(UBYTE *)-1));
1876 nBuffer = (UBYTE *)Malloc1(x2,
"input buffer");
1877 n1 = nBuffer; s = Buffer; s1--;
1878 while ( s < s1 ) *n1++ = *s++;
1886 if ( ( ( n1 > nBuffer ) && ( ( FG.cTable[n1[-1]] <= 1 )
1887 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1888 ( ( FG.cTable[strngs[0]] <= 1 ) || ( strngs[0] ==
'[' )
1889 || ( strngs[0] ==
'_' ) ) ) *n1++ =
',';
1891 for ( i1 = 0; i1 < ii; i1++ ) {
1892 s = strngs;
while ( *s ) *n1++ = *s++;
1893 for ( i2 = 0; i2 < i; i2++ ) {
1894 if ( n1 > nBuffer && IsSignChar(n1[-1]) ) {
1897 if ( nums[2*i2] >= 0 ) {
1901 n1 = NumCopy((WORD)(nums[2*i2]),n1);
1902 if ( nums[2*i2] > nums[2*i2+1] ) nums[2*i2]--;
1904 s++;
while ( *s ) *n1++ = *s++;
1906 if ( ( i1 & 1 ) == 0 ) *n1++ = operator1;
1907 else *n1++ = operator2;
1910 s = t2 + 1; n2 = n1;
1914 if ( ( ( ( FG.cTable[n1[-1]] <= 1 )
1915 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1916 ( ( FG.cTable[s[0]] <= 1 ) || ( s[0] ==
'[' )
1917 || ( s[0] ==
'_' ) ) ) *n1++ =
',';
1919 while ( *s ) *n1++ = *s++;
1922 LONG nnn1 = n1-nBuffer;
1923 LONG nnn2 = n2-nBuffer;
1925 while ( AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] + x2 >= AC.iStop ) {
1926 LONG position = s-Buffer;
1927 LONG position2 = AC.iPointer - AC.iBuffer;
1929 ppp = &(AC.iBuffer);
1930 if ( DoubleLList((
void ***)ppp,&AC.iBufferSize
1931 ,
sizeof(UBYTE),
"statement buffer") ) {
1934 AC.iPointer = AC.iBuffer + position2;
1935 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1936 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1937 s = Buffer + position;
1942 for ( nnn3 = 0; nnn3 < nnn1; nnn3++ ) Buffer[nnn3] = nBuffer[nnn3];
1946 M_free(nBuffer,
"input buffer");
1947 M_free(nums,
"Expand ...");
1950 AP.preStop = nBuffer + x2 - 2;
1952 M_free(AP.preStart,
"input buffer");
1953 M_free(nums,
"Expand ...");
1954 AP.preStart = nBuffer;
1955 Buffer = AP.preStart; Stop = AP.preStop;
1957 fullsize = n1 - Buffer;
1975 while ( hi >= low ) {
1977 s1 = (UBYTE *)(table[med].name);
1979 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1985 FG.cTable[*s2] != 0 && FG.cTable[*s2] != 1
1989 if ( tolower(*s2) > tolower(*s1) ) low = med+1;
2004 for ( i = 0; i < size; i++ ) {
2005 s1 = (UBYTE *)(table[i].name);
2007 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
2008 if ( *s2 == 0 || *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' )
2032 UBYTE *name, *value, *valpoin, *args = 0, c;
2033 if ( ( mode & 2 ) == 0 ) {
2034 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2035 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2037 else { mode &= ~2; }
2039 if ( chartype[*s] != 0 )
goto illname;
2041 while ( chartype[*s] <= 1 ) s++;
2043 while ( *s ==
' ' || *s ==
'\t' ) s++;
2046 if (
PutPreVar(name,(UBYTE *)
"1",0,mode) < 0 )
return(-1);
2052 if ( chartype[*s] != 0 )
goto illarg;
2054 while ( chartype[*s] <= 1 ) s++;
2055 while ( *s ==
' ' || *s ==
'\t' ) s++;
2056 if ( *s ==
')' )
break;
2057 if ( *s !=
',' )
goto illargs;
2059 while ( *s ==
' ' || *s ==
'\t' ) s++;
2062 while ( *s ==
' ' || *s ==
'\t' ) s++;
2066 s++; valpoin = value = s;
2067 while ( *s !=
'"' ) {
2069 if ( s[1] ==
'n' ) { *valpoin++ = LINEFEED; s += 2; }
2070 else if ( s[1] ==
'"' ) { *valpoin++ =
'"'; s += 2; }
2071 else if ( s[1] == 0 )
goto illval;
2072 else { *valpoin++ = *s++; *valpoin++ = *s++; }
2074 else *valpoin++ = *s++;
2077 if (
PutPreVar(name,value,args,mode) < 0 )
return(-1);
2080 MesPrint(
"@Illegal string for preprocessor variable %s. Forgotten double quotes (\") ?",name);
2085 MesPrint(
"@Illegally formed name of preprocessor variable");
2088 MesPrint(
"@Illegally formed name of argument of preprocessor definition");
2091 MesPrint(
"@Illegally formed arguments of preprocessor definition");
2094 MesPrint(
"@Illegal valpoin for preprocessor variable %s",name);
2103int DoCommentChar(UBYTE *s)
2106 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2107 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2108 while ( *s ==
' ' || *s ==
'\t' ) s++;
2109 if ( *s == 0 || *s ==
'\n' ) {
2110 MesPrint(
"@No valid comment character specified");
2114 while ( *s ==
' ' || *s ==
'\t' ) s++;
2115 if ( *s != 0 && *s !=
'\n' ) {
2116 MesPrint(
"@Comment character should be a single valid character");
2134int DoPreAssign(UBYTE *s)
2137 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
2140 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
2144 MesPrint(
"@Illegal characters in %#assign instruction");
2148 AP.PreAssignFlag = 1;
2165int DoDefine(UBYTE *s)
2175int DoRedefine(UBYTE *s)
2187int ClearMacro(UBYTE *name)
2192 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2193 if ( StrCmp(name,p->name) == 0 )
break;
2195 if ( i < 0 )
return(-1);
2196 if ( p->nargs <= 0 )
return(0);
2198 for ( i = 0; i < p->nargs; i++ ) {
2215int TheUndefine(UBYTE *name)
2217 int i, inum, error = 0;
2219 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2220 if ( StrCmp(name,p->name) == 0 ) {
2221 M_free(p->name,
"undefining PreVar");
2224 while ( i < NumPre ) {
2225 p->name = p[1].name;
2226 p->value = p[1].value;
2229 p->name = 0; p->value = 0;
2231 CBUF *CC = cbuf + AC.cbufnum;
2233 for ( j = 1; j <= CC->numlhs; j++ ) {
2234 if ( CC->
lhs[j][0] == TYPEREDEFPRE ) {
2235 if ( CC->
lhs[j][2] > inum ) CC->
lhs[j][2]--;
2236 else if ( CC->
lhs[j][2] == inum ) {
2237 for ( k = inum - 1; k >= 0; k-- )
2238 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2239 if ( k >= 0 ) CC->
lhs[j][2] = k;
2241 MesPrint(
"@Conflict between undefining a preprocessor variable and a redefine statement");
2248 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2249 if ( AC.pfirstnum[j] > inum ) AC.pfirstnum[j]--;
2250 else if ( AC.pfirstnum[j] == inum ) {
2251 for ( k = inum - 1; k >= 0; k-- )
2252 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2253 if ( k >= 0 ) AC.pfirstnum[j] = k;
2269int DoUndefine(UBYTE *s)
2272 int error = 0, retval;
2277 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2278 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2280 if ( chartype[*s] != 0 )
goto illname;
2282 while ( chartype[*s] <= 1 ) s++;
2284 if ( *s && *s !=
' ' && *s !=
'\t' )
goto illname;
2285 while ( *s ==
' ' || *s ==
'\t' ) s++;
2287 MesPrint(
"@Undefine should just have a variable name");
2291 if ( ( retval = TheUndefine(name) ) != 0 ) {
2292 if ( error == 0 )
return(retval);
2293 if ( error > 0 ) error = retval;
2312 MesPrint(
"@Illegally formed name of preprocessor variable");
2321int DoInclude(UBYTE *s) {
return(Include(s,FILESTREAM)); }
2328int DoReverseInclude(UBYTE *s) {
return(Include(s,REVERSEFILESTREAM)); }
2335int Include(UBYTE *s,
int type)
2337 UBYTE *name = s, *fold, *t, c, c1 = 0, c2 = 0, c3 = 0;
2338 int str1offset, withnolist = AC.NoShowInput;
2339 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2340 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2341 if ( *s ==
'-' || *s ==
'+' ) {
2342 if ( *s ==
'-' ) withnolist = 1;
2343 else withnolist = 0;
2345 while ( *s ==
' ' || *s ==
'\t' ) s++;
2349 while ( *s && *s !=
'"' ) {
2350 if ( *s ==
'\\' ) s++;
2356 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2357 if ( *s ==
'\\' ) s++;
2362 while ( *s ==
' ' || *s ==
'\t' ) s++;
2366 while ( *s ==
' ' || *s ==
'\t' ) s++;
2369 MesPrint(
"@Empty fold name");
2373 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2374 if ( *s ==
'\\' ) s++;
2378 while ( *s ==
' ' || *s ==
'\t' ) s++;
2386 else if ( *s == 0 ) {
2390 MesPrint(
"@Improper syntax for file name");
2395 fold = strDup1(fold,
"foldname");
2400 if ( OpenStream(name,type,0,PRENOACTION) == 0 ) {
2401 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2407 LONG linenum = 0, prevline = 0;
2408 name = strDup1(name,
"name of include file");
2409 AC.CurrentStream->FoldName = strDup1(fold,
"name of fold");
2412 c = GetFromStream(AC.CurrentStream);
2413 if ( c == ENDOFSTREAM ) {
2414 AC.CurrentStream = CloseStream(AC.CurrentStream);
2417 if ( c == AP.ComChar ) {
2418 str1offset = AC.CurrentStream-AC.Streams;
2420 if ( AC.CurrentStream != str1offset+AC.Streams ) {
2425 if ( t[2] ==
'#' && ( ( t[3] ==
'[' && !foldopen )
2426 || ( t[3] ==
']' && foldopen ) ) ) {
2428 while ( *t ==
' ' || *t ==
'\t' ) t++;
2429 s = AC.CurrentStream->FoldName;
2430 while ( *s == *t ) { s++; t++; }
2431 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t'
2433 while ( *t ==
' ' || *t ==
'\t' ) t++;
2435 if ( foldopen == 0 ) {
2437 position = GetStreamPosition(AC.CurrentStream);
2438 linenum = AC.CurrentStream->linenumber;
2439 prevline = AC.CurrentStream->prevline;
2440 c3 = AC.CurrentStream->isnextchar;
2441 c1 = AC.CurrentStream->nextchar[0];
2442 c2 = AC.CurrentStream->nextchar[1];
2446 PositionStream(AC.CurrentStream,position);
2447 AC.CurrentStream->linenumber = linenum;
2448 AC.CurrentStream->prevline = prevline;
2449 AC.CurrentStream->eqnum = 1;
2451 AC.CurrentStream->isnextchar = c3;
2452 AC.CurrentStream->nextchar[0] = c1;
2453 AC.CurrentStream->nextchar[1] = c2;
2462 while ( c != LINEFEED && c != ENDOFSTREAM ) {
2463 c = GetFromStream(AC.CurrentStream);
2464 if ( c == ENDOFSTREAM ) {
2465 AC.CurrentStream = CloseStream(AC.CurrentStream);
2470 if ( c == ENDOFSTREAM ) {
2472 MesPrint(
"@Cannot find fold %s in file %s",fold,name);
2475 M_free(name,
"name of include file");
2479 M_free(name,
"name of include file");
2481 AC.NoShowInput = withnolist;
2482 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2496int DoPreExchange(UBYTE *s)
2501 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2502 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2503 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2505 s++; s1 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2506 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2508 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2509 if ( *s !=
'$' )
goto syntax;
2510 s++; s2 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2511 if ( *s != 0 && *s !=
';' )
goto syntax;
2513 if ( ( num1 = GetDollar(s1) ) <= 0 ) {
2514 MesPrint(
"@$%s has not been defined (yet)",s1);
2517 if ( ( num2 = GetDollar(s2) ) <= 0 ) {
2518 MesPrint(
"@$%s has not been defined (yet)",s2);
2522 ExchangeDollars((
int)num1,(
int)num2);
2527 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2529 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2530 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
2532 if ( *s != 0 && *s !=
';' )
goto syntax;
2534 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
2535 MesPrint(
"@%s is not an expression",s1);
2538 if ( GetName(AC.exprnames,s2,&num2,NOAUTO) != CEXPRESSION ) {
2539 MesPrint(
"@%s is not an expression",s2);
2543 ExchangeExpressions((
int)num1,(
int)num2);
2548 MesPrint(
"@Proper syntax: %#exchange expr1,expr2 or %#exchange $var1,$var2");
2559 UBYTE *t, *u, *v, *name, c, cp, *args1, *args2, *t1, *t2, *wild = 0;
2560 int bratype = 0, wildargs = 0, inwildargs = 0, nwildargs = 0;
2563 int i, namesize, narg1, narg2, bralevel, numpre;
2565 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2566 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2572 for ( i = NumProcedures-1; i >= 0; i-- ) {
2573 if ( StrCmp(Procedures[i].name,name) == 0 )
break;
2576 p = (
PROCEDURE *)FromList(&AP.ProcList);
2580 while ( *t ) { t++; namesize++; }
2581 t = AP.procedureExtension;
2582 while ( *t ) { t++; namesize++; }
2583 t = p->name = (UBYTE *)Malloc1(namesize+2,
"procedure");
2585 while ( *u ) *t++ = *u++;
2587 v = AP.procedureExtension;
2588 while ( *v ) *t++ = *v++;
2592 p->p.buffer = LoadInputFile(p->name,PROCEDUREFILE);
2593 if ( p->p.buffer == 0 )
return(-1);
2597 p->p.buffer = Procedures[i].p.buffer;
2598 p->name = Procedures[i].name;
2604 if ( *t++ !=
'#' )
goto wrongfile;
2610 if ( StrCmp(t,name) != 0 )
goto wrongfile;
2618 bralevel = narg1 = narg2 = 0; args2 = u;
2623 while ( *u !=
')' ) {
2624 if ( *u ==
'?' ) { wildargs++; u++; nwildargs = narg2+1; }
2626 if ( *u ==
',' ) { u++; SKIPBLANKS(u) }
2627 else if ( *u !=
')' || ( wildargs > 1 ) ) {
2628 MesPrint(
"@Illegal argument field in procedure %s",p->name);
2633 while ( *u != LINEFEED ) u++;
2636 if ( *s ==
'(' ) bratype = 1;
2638 if ( *s ==
'{' && bratype == 0 ) bralevel++;
2639 else if ( *s ==
'(' && bratype == 1 ) bralevel++;
2640 else if ( *s ==
'}' && bratype == 0 ) {
2642 if ( bralevel == 0 ) {
2644 if ( wildargs && narg1 == nwildargs ) wild = s;
2647 else if ( *s ==
')' && bratype == 1 ) {
2649 if ( bralevel == 0 ) {
2651 if ( wildargs && narg1 == nwildargs ) wild = s;
2656 else if (set_in(*s,AC.separators)) {
2660 if ( wildargs && narg1 == nwildargs ) wild = s;
2662 else if ( *s ==
'\\' ) s++;
2664 }
while ( bralevel > 0 );
2665 if ( wildargs && narg1 >= narg2-1 ) {
2666 inwildargs = narg1-narg2+1;
2667 if ( inwildargs == 0 ) nwildargs = 0;
2669 while ( inwildargs > 1 ) {
2671 while ( *wild ) wild++;
2676 else if ( narg1 != narg2 && ( narg2 != 0 || narg1 != 1 || *args1 != 0 ) ) {
2677 MesPrint(
"@Arguments of procedure %s are not matching",p->name);
2681 for ( i = 0; i < narg2; i++ ) {
2686 if ( *t ==
'?' && inwildargs == 0 ) {
2687 args2 =
EndOfToken(args2); c = *args2; *args2 = 0;
2688 if (
PutPreVar(t,(UBYTE *)
"",0,0) < 0 )
return(-1);
2691 args2 =
EndOfToken(args2); c = *args2; *args2 = 0;
2694 if ( *t1 ==
'\\' ) t1++;
2695 if ( t1 != t2 ) *t2 = *t1;
2699 if (
PutPreVar(t,args1,0,0) < 0 )
return(-1);
2702 *args2 = c; SKIPBLANKS(args2)
2703 args2++; SKIPBLANKS(args2)
2705 streamoffset = AC.CurrentStream - AC.Streams;
2706 args1 = AC.CurrentStream->name;
2707 AC.CurrentStream->name = p->name;
2708 i1 = AC.CurrentStream->linenumber;
2709 i2 = AC.CurrentStream->prevline;
2710 AC.CurrentStream->prevline =
2711 AC.CurrentStream->linenumber = 2;
2712 OpenStream(u+1,PREREADSTREAM3,numpre,PRENOACTION);
2713 AC.Streams[streamoffset].name = args1;
2714 AC.Streams[streamoffset].linenumber = i1;
2715 AC.Streams[streamoffset].prevline = i2;
2716 AddToPreTypes(PRETYPEPROCEDURE);
2719 if ( i < 0 ) MesPrint(
"@File %s is not a proper procedure",p->name);
2720 else MesPrint(
"!!!Internal error with procedure names: %s",name);
2729int DoDebug(UBYTE *s)
2732 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2733 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2734 NeedNumber(x,s,nonumber)
2735 if ( x < 0 || x >(PREPROONLY
2746 if ( ( x & PREPROONLY ) != 0 ) AP.PreDebug |= PREPROONLY;
2747 if ( ( x & DUMPTOCOMPILER ) != 0 ) AP.PreDebug |= DUMPTOCOMPILER;
2748 if ( ( x & DUMPOUTTERMS ) != 0 ) AP.PreDebug |= DUMPOUTTERMS;
2749 if ( ( x & DUMPINTERMS ) != 0 ) AP.PreDebug |= DUMPINTERMS;
2750 if ( ( x & DUMPTOSORT ) != 0 ) AP.PreDebug |= DUMPTOSORT;
2751 if ( ( x & DUMPTOPARALLEL ) != 0 ) AP.PreDebug |= DUMPTOPARALLEL;
2753 if ( ( x & THREADSDEBUG ) != 0 ) AP.PreDebug |= THREADSDEBUG;
2757 MesPrint(
"@Illegal argument for debug instruction");
2766int DoTerminate(UBYTE *s)
2769 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2770 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2772 NeedNumber(x,s,nonumber)
2780 MesPrint(
"@Illegal argument for terminate instruction");
2806 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2807 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2809 if ( NumDoLoops <= 0 ) {
2810 MesPrint(
"@%#continuedo without %#do");
2818 else if ( FG.cTable[*s] == 1 ) {
2819 ParseNumber(levels,s);
2821 if ( *s != 0 )
goto improper;
2825 MesPrint(
"@Improper syntax of %#continuedo instruction");
2829 if ( levels > NumDoLoops ) {
2830 MesPrint(
"@Too many loop levels requested in %#continuedo instruction");
2834 result = ExitDoLoops(levels-1,
"continuedo");
2835 if ( result != 0 )
return(result);
2837 if ( levels <= 0 )
return(0);
2839 if ( AC.CurrentStream->type == PREREADSTREAM3
2840 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
2841 MesPrint(
"@Trying to jump out of a procedure with a %#continuedo instruction");
2845 loop = &(DoLoops[NumDoLoops-1]);
2846 AP.NumPreTypes = loop->NumPreTypes+1;
2847 AP.PreIfLevel = loop->PreIfLevel;
2848 AP.PreSwitchLevel = loop->PreSwitchLevel;
2867 UBYTE *t, c, *u, *uu;
2870 LONG linenum = AC.CurrentStream->linenumber;
2871 int oldNoShowInput = AC.NoShowInput, i, oldpreassignflag;
2873 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
2874 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
2875 if ( PreSkip((UBYTE *)
"do",(UBYTE *)
"enddo",1) )
return(-1);
2883 AddToPreTypes(PRETYPEDO);
2885 loop = (
DOLOOP *)FromList(&AP.LoopList);
2886 loop->firstdollar = loop->lastdollar = loop->incdollar = -1;
2887 loop->NumPreTypes = AP.NumPreTypes-1;
2888 loop->PreIfLevel = AP.PreIfLevel;
2889 loop->PreSwitchLevel = AP.PreSwitchLevel;
2891 if ( PreLoad(&(loop->
p),(UBYTE *)
"do",(UBYTE *)
"enddo",1,
"doloop") )
return(-1);
2892 AC.NoShowInput = oldNoShowInput;
2893 loop->NoShowInput = AC.NoShowInput;
2897 s = loop->
p.buffer + (s - AP.preStart);
2900 if ( chartype[*s] != 0 )
goto illname;
2902 while ( chartype[*s] <= 1 ) s++;
2904 while ( *s ==
' ' || *s ==
'\t' ) s++;
2905 if ( *s !=
'=' )
goto illdo;
2907 while ( *s ==
' ' || *s ==
'\t' ) s++;
2911 loop->type = LISTEDLOOP;
2912 s++; loop->vars = s;
2914 while ( *s !=
'}' && *s != 0 ) {
2915 if ( set_in(*s,AC.separators) ) { *s = 0; loop->lastnum++; }
2916 else if ( *s ==
'\\' ) s++;
2919 if ( *s == 0 )
goto illdo;
2925 else if ( *s ==
'-' || *s ==
'+' || chartype[*s] == 1 || *s ==
'$' ) {
2926 loop->type = NUMERICALLOOP;
2928 while ( *s && *s !=
',' ) s++;
2929 if ( *s == 0 )
goto illdo;
2932 if ( GetName(AC.dollarnames,t+1,&loop->firstdollar,NOAUTO) != CDOLLAR ) {
2933 MesPrint(
"@%s is undefined in first parameter in %#do instruction",t);
2936 loop->firstnum = DolToLong(BHEAD loop->firstdollar);
2937 if ( AN.ErrorInDollar ) {
2938 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2945 if ( PreEval(t,&loop->firstnum) == 0 )
goto illdo;
2949 while ( *s && *s !=
',' && *s !=
';' && *s != LINEFEED ) s++;
2953 if ( GetName(AC.dollarnames,t+1,&loop->lastdollar,NOAUTO) != CDOLLAR ) {
2954 MesPrint(
"@%s is undefined in second parameter in %#do instruction",t);
2957 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
2958 if ( AN.ErrorInDollar ) {
2959 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2966 if ( PreEval(t,&loop->lastnum) == 0 )
goto illdo;
2971 while ( *s && *s !=
';' && *s != LINEFEED ) s++;
2974 if ( GetName(AC.dollarnames,t+1,&loop->incdollar,NOAUTO) != CDOLLAR ) {
2975 MesPrint(
"@%s is undefined in third parameter in %#do instruction",t);
2978 loop->incnum = DolToLong(BHEAD loop->incdollar);
2979 if ( AN.ErrorInDollar ) {
2980 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2987 if ( PreEval(t,&loop->incnum) == 0 )
goto illdo;
2991 else loop->incnum = 1;
2994 else if ( ( chartype[*s] == 0 ) || ( *s ==
'[' ) ) {
2995 int oldNumPotModdollars = NumPotModdollars;
2997 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
2998 AC.RhsExprInModuleFlag = 0;
3001 if ( ( s =
SkipAName(s) ) == 0 )
goto illdo;
3003 if ( GetName(AC.exprnames,t,&expnum,NOAUTO) == CEXPRESSION ) {
3004 loop->type = ONEEXPRESSION;
3013 if ( c ==
',' || c ==
'\t' || c ==
';' ) { s++; }
3014 else if ( c != 0 && c !=
'\n' )
goto illdo;
3015 while ( *s ==
',' || *s ==
'\t' || *s ==
';' ) s++;
3016 if ( *s != 0 && *s !=
'\n' )
goto illdo;
3027 while ( *t ) { t++; i++; }
3029 loop->
dollarname = Malloc1((LONG)i,
"do-loop instruction");
3034 *u++ =
'$'; t = loop->
name;
while ( *t ) *u++ = *t++;
3035 *u++ =
'_'; uu = u; *u++ =
'='; t = loop->vars;
3036 while ( *t ) *u++ = *t++;
3042 oldpreassignflag = AP.PreAssignFlag;
3043 AP.PreAssignFlag = 2;
3045 if ( CatchDollar(0) ) {
3046 MesPrint(
"@Cannot load expression in do loop");
3049 AP.PreAssignFlag = oldpreassignflag;
3050 NumPotModdollars = oldNumPotModdollars;
3052 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
3057 loop->errorsinloop = 0;
3059 loop->startlinenumber = linenum;
3061 loop->firstloopcall = 1;
3064 MesPrint(
"@Improper name for do loop variable");
3067 MesPrint(
"@Improper syntax in do loop instruction");
3079int DoBreakDo(UBYTE *s)
3083 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3084 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3086 if ( NumDoLoops <= 0 ) {
3087 MesPrint(
"@%#breakdo without %#do");
3093 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
3097 else if ( FG.cTable[*s] == 1 ) {
3099 while ( *s >=
'0' && *s <=
'9' ) { levels = 10*levels + *s++ -
'0'; }
3100 if ( *s != 0 )
goto improper;
3104 MesPrint(
"@Improper syntax of %#breakdo instruction");
3107 if ( levels > NumDoLoops ) {
3108 MesPrint(
"@Too many loop levels requested in %#breakdo instruction");
3111 return(ExitDoLoops(levels,
"breakdo"));
3121static int ExitDoLoops(
int levels,
const char *instruction)
3124 while ( levels > 0 ) {
3125 while ( AC.CurrentStream->type != PREREADSTREAM
3126 && AC.CurrentStream->type != PREREADSTREAM2
3127 && AC.CurrentStream->type != PREREADSTREAM3 ) {
3128 AC.CurrentStream = CloseStream(AC.CurrentStream);
3130 while ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO
3131 && AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) AP.NumPreTypes--;
3132 if ( AC.CurrentStream->type == PREREADSTREAM3
3133 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
3134 MesPrint(
"@Trying to jump out of a procedure with a %#%s instruction",instruction);
3137 loop = &(DoLoops[NumDoLoops-1]);
3138 AP.NumPreTypes = loop->NumPreTypes;
3139 AP.PreIfLevel = loop->PreIfLevel;
3140 AP.PreSwitchLevel = loop->PreSwitchLevel;
3142 DoUndefine(loop->
name);
3143 M_free(loop->
p.buffer,
"loop->p.buffer");
3144 loop->firstloopcall = 0;
3146 AC.CurrentStream = CloseStream(AC.CurrentStream);
3159 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3160 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#else without corresponding %#if");
3161 else MessPreNesting(1);
3164 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3165 while ( *s ==
' ' ) s++;
3166 if ( tolower(*s) ==
'i' && tolower(s[1]) ==
'f' && s[2]
3167 && FG.cTable[s[2]] > 1 && s[2] !=
'_' ) {
3169 while ( *s ==
' ' ) s++;
3170 return(DoElseif(s));
3172 if ( AP.PreIfLevel <= 0 ) {
3173 MesPrint(
"@%#else without corresponding %#if");
3176 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3178 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3180 case LOOKINGFORELSE:
3181 AP.PreIfStack[AP.PreIfLevel] = EXECUTINGIF;
3183 case LOOKINGFORENDIF:
3194int DoElseif(UBYTE *s)
3197 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3198 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#elseif without corresponding %#if");
3199 else MessPreNesting(2);
3202 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3203 if ( AP.PreIfLevel <= 0 ) {
3204 MesPrint(
"@%#elseif without corresponding %#if");
3207 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3209 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3211 case LOOKINGFORELSE:
3212 if ( ( condition = EvalPreIf(s) ) < 0 )
return(-1);
3213 AP.PreIfStack[AP.PreIfLevel] = condition;
3215 case LOOKINGFORENDIF:
3229int DoEnddo(UBYTE *s)
3233 UBYTE *t, *tt, *value, numstr[16];
3237 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3238 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3247 if ( NumDoLoops <= 0 ) {
3248 MesPrint(
"@%#enddo without %#do");
3251 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO ) { MessPreNesting(4);
return(-1); }
3252 loop = &(DoLoops[NumDoLoops-1]);
3253 if ( !loop->firstloopcall ) AC.CurrentStream = CloseStream(AC.CurrentStream);
3255 if ( loop->errorsinloop ) {
3256 MesPrint(
"++++Errors in Loop");
3259 if ( loop->type == LISTEDLOOP ) {
3260 if ( loop->firstnum >= loop->lastnum )
goto finish;
3262 t = value = loop->vars;
3263 while ( *value ) value++;
3268 if ( *value ==
'\\' ) value++;
3274 else if ( loop->type == NUMERICALLOOP ) {
3276 if ( !loop->firstloopcall ) {
3285 while ( *value && ( *value ==
' '
3286 || *value ==
'-' || *value ==
'+' ) ) {
3287 if ( *value ==
'-' ) xsign = -xsign;
3290 t = value; xval = 0;
3291 while ( *value >=
'0' && *value <=
'9' ) xval = 10*xval + *value++ -
'0';
3292 while ( *value && *value ==
' ' ) value++;
3293 if ( *value == 0 ) {
3297 if ( xsign < 0 ) xval = -xval;
3298 if ( loop->incdollar >= 0 ) {
3299 loop->incnum = DolToLong(BHEAD loop->incdollar);
3300 if ( AN.ErrorInDollar ) {
3301 MesPrint(
"@%s does not evaluate into a valid third loop parameter",DOLLARNAME(Dollars,loop->incdollar));
3305 loop->firstnum = xval + loop->incnum;
3308 if ( loop->lastdollar >= 0 ) {
3309 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
3310 if ( AN.ErrorInDollar ) {
3311 MesPrint(
"@%s does not evaluate into a valid second loop parameter",DOLLARNAME(Dollars,loop->lastdollar));
3316 if ( ( loop->incnum > 0 && loop->firstnum > loop->lastnum )
3317 || ( loop->incnum < 0 && loop->firstnum < loop->lastnum ) )
goto finish;
3318 NumToStr(numstr,loop->firstnum);
3320 loop->firstnum += loop->incnum;
3323 else if ( loop->type == ONEEXPRESSION ) {
3327 WORD numdollar = GetDollar(loop->dollarname+1);
3328 DOLLARS d = Dollars + numdollar;
3329 WORD *w, *dw, v, *ww;
3330 if ( (d->where) == 0 ) {
3331 d->type = DOLUNDEFINED;
3332 M_free(loop->dollarname,
"do-loop instruction");
3335 w = d->where + loop->incnum;
3337 M_free(d->where,
"dollar");
3339 d->type = DOLUNDEFINED;
3340 M_free(loop->dollarname,
"do-loop instruction");
3347 ww = w + *w; v = *ww; *ww = 0;
3348 dw = d->where; d->where = w;
3349 t = WriteDollarToBuffer(numdollar,1);
3350 d->where = dw; *ww = v;
3354 if ( loop->firstloopcall ) OpenStream(loop->contents,PREREADSTREAM2,0,PRENOACTION);
3355 else OpenStream(loop->contents,PREREADSTREAM,0,PRENOACTION);
3356 AC.CurrentStream->prevline =
3357 AC.CurrentStream->linenumber = loop->startlinenumber;
3358 AC.CurrentStream->eqnum = 0;
3359 loop->firstloopcall = 0;
3363 retval = DoUndefine(loop->name);
3364 M_free(loop->p.buffer,
"loop->p.buffer");
3365 loop->firstloopcall = 0;
3375int DoEndif(UBYTE *s)
3378 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3379 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#endif without corresponding %#if");
3380 else MessPreNesting(5);
3384 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3385 if ( AP.PreIfLevel <= 0 ) {
3386 MesPrint(
"@%#endif without corresponding %#if");
3403int DoEndprocedure(UBYTE *s)
3406 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) {
3411 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3412 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3413 AC.CurrentStream = CloseStream(AC.CurrentStream);
3417 if ( Procedures[NumProcedures].mustfree == 1 ) {
3418 M_free(Procedures[NumProcedures].p.buffer,
"procedures buffer");
3419 M_free(Procedures[NumProcedures].name,
"procedures name");
3421 }
while ( Procedures[NumProcedures].loadmode > 1 );
3433 AddToPreTypes(PRETYPEIF);
3434 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3435 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3436 condition = EvalPreIf(s);
3437 if ( condition < 0 )
return(-1);
3439 else condition = LOOKINGFORENDIF;
3440 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3441 int **ppp = &AP.PreIfStack;
3442 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3443 "PreIfLevels") )
return(-1);
3445 AP.PreIfStack[++AP.PreIfLevel] = condition;
3454int DoIfdef(UBYTE *s,
int par)
3457 AddToPreTypes(PRETYPEIF);
3458 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3459 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3460 while ( *s ==
' ' || *s ==
'\t' ) s++;
3461 if ( ( *s == 0 ) == ( par == 1 ) ) condition = LOOKINGFORELSE;
3462 else condition = EXECUTINGIF;
3464 else condition = LOOKINGFORENDIF;
3465 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3466 int **ppp = &AP.PreIfStack;
3467 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3468 "PreIfLevels") )
return(-1);
3470 AP.PreIfStack[++AP.PreIfLevel] = condition;
3479int DoIfydef(UBYTE *s)
3481 return DoIfdef(s,1);
3489int DoIfndef(UBYTE *s)
3491 return DoIfdef(s,2);
3514int DoInside(UBYTE *s)
3517 int numdol, error = 0;
3518 WORD *nb, newsize, i;
3520 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3521 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3522 if ( AP.PreInsideLevel != 0 ) {
3523 MesPrint(
"@Illegal nesting of %#inside/%#endinside instructions");
3536 AP.inside.numdollars = 0;
3538 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
3539 if ( *s == 0 )
break;
3541 MesPrint(
"@%#inside instruction can have only $ variables for parameters");
3546 while (chartype[*s] <= 1 ) s++;
3548 if ( ( numdol = GetDollar(name) ) < 0 ) {
3549 MesPrint(
"@%#inside: $%s has not (yet) been defined",name);
3555 if ( AP.inside.numdollars >= AP.inside.size ) {
3556 if ( AP.inside.buffer == 0 ) newsize = 20;
3557 else newsize = 2*AP.inside.size;
3558 nb = (WORD *)Malloc1(newsize*
sizeof(WORD),
"insidebuffer");
3559 if ( AP.inside.buffer ) {
3560 for ( i = 0; i < AP.inside.size; i++ ) nb[i] = AP.inside.buffer[i];
3561 M_free(AP.inside.buffer,
"insidebuffer");
3563 AP.inside.buffer = nb;
3564 AP.inside.size = newsize;
3566 AP.inside.buffer[AP.inside.numdollars++] = numdol;
3573 AP.inside.oldcompiletype = AC.compiletype;
3574 AP.inside.oldparallelflag = AC.mparallelflag;
3575 AP.inside.oldnumpotmoddollars = NumPotModdollars;
3576 AP.inside.oldcbuf = AC.cbufnum;
3577 AP.inside.oldrbuf = AM.rbufnum;
3578 AP.inside.oldcnumlhs = AR.Cnumlhs,
3579 AddToPreTypes(PRETYPEINSIDE);
3580 AP.PreInsideLevel = 1;
3581 AC.cbufnum = AP.inside.inscbuf;
3582 AM.rbufnum = AP.inside.inscbuf;
3585 AC.mparallelflag = PARALLELFLAG;
3594 PF_StoreInsideInfo();
3595 AC.RhsExprInModuleFlag = 0;
3596 NumPotModdollars = 0;
3597 AC.numpfirstnum = 0;
3607int DoEndInside(UBYTE *s)
3610 WORD numdol, *oldworkpointer = AT.WorkPointer, *term, *t, j, i;
3612 WORD oldbracketon = AR.BracketOn;
3613 WORD *oldcompresspointer = AR.CompressPointer;
3614 int oldmultithreaded = AS.MultiThreaded;
3621 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3622 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3623 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEINSIDE ) {
3624 if ( AP.PreInsideLevel != 1 ) MesPrint(
"@%#endinside without corresponding %#inside");
3625 else MessPreNesting(11);
3629 if ( AP.PreInsideLevel != 1 ) {
3630 MesPrint(
"@%#endinside without corresponding %#inside");
3633 if ( AP.PreContinuation ) {
3634 MesPrint(
"@%#endinside: previous statement not terminated.");
3637 AC.compiletype = AP.inside.oldcompiletype;
3638 AR.Cnumlhs = cbuf[AM.rbufnum].numlhs;
3645 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
3648 AS.MultiThreaded = 0;
3650 if ( AR.CompressPointer == 0 ) AR.CompressPointer = AR.CompressBuffer;
3651 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3655 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3656 numdol = AP.inside.buffer[i];
3657 nd = d = Dollars + numdol;
3658 if ( d->type != DOLZERO ) {
3659 if ( d->type != DOLTERMS ) nd = DolToTerms(BHEAD numdol);
3663 AR.MaxDum = AM.IndDum;
3665 t = oldworkpointer; j = *term;
3668 AN.IndDum = AM.IndDum;
3669 AR.CurDum = ReNumber(BHEAD term);
3670 if (
Generator(BHEAD oldworkpointer,0) ) {
3671 MesPrint(
"@Called from %#endinside");
3672 MesPrint(
"@Evaluating variable $%s",DOLLARNAME(Dollars,numdol));
3676 AT.WorkPointer = oldworkpointer;
3677 CleanDollarFactors(d);
3678 if ( d->where ) { M_free(d->where,
"dollar contents"); d->where = 0; }
3679 EndSort(BHEAD (WORD *)((
void *)(&(d->where))),2);
3681 term = d->where;
while ( *term ) term += *term;
3682 d->size = term - d->where;
3683 if ( nd != d ) M_free(nd,
"Copy of dollar variable");
3684 if ( d->where[0] == 0 ) {
3685 M_free(d->where,
"dollar contents"); d->where = 0;
3692 if ( AC.RhsExprInModuleFlag ) {
3697 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3705 if ( NumPotModdollars > 0 ) {
3707 if ( error )
goto cleanup;
3709 if ( AC.numpfirstnum > 0 ) {
3711 if ( error )
goto cleanup;
3716 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3717 AC.cbufnum = AP.inside.oldcbuf;
3718 AM.rbufnum = AP.inside.oldrbuf;
3719 AR.Cnumlhs = AP.inside.oldcnumlhs;
3720 AR.BracketOn = oldbracketon;
3721 AP.PreInsideLevel = 0;
3722 AR.CompressPointer = oldcompresspointer;
3723 AS.MultiThreaded = oldmultithreaded;
3724 AC.mparallelflag = AP.inside.oldparallelflag;
3725 NumPotModdollars = AP.inside.oldnumpotmoddollars;
3728 PF_RestoreInsideInfo();
3729 if ( error )
return error;
3739int DoMessage(UBYTE *s)
3741 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3742 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3743 while ( *s ==
' ' || *s ==
'\t' ) s++;
3744 MesPrint(
"~~~%s",s);
3758 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3759 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3762 while ( *s ==
' ' || *s ==
'\t' ) s++;
3763 if ( OpenStream(s,PIPESTREAM,0,PRENOACTION) == 0 )
return(-1);
3766 Error0(
"Pipes not implemented on this computer/system");
3776int DoPrcExtension(UBYTE *s)
3779 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3780 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3781 while ( *s ==
' ' || *s ==
'\t' ) s++;
3782 if ( *s == 0 || *s ==
'\n' ) {
3783 MesPrint(
"@No valid procedure extension specified");
3786 if ( FG.cTable[*s] != 0 ) {
3787 MesPrint(
"@Procedure extension should be a string starting with an alphabetic character. No whitespace.");
3791 while ( *s && *s !=
'\n' && *s !=
' ' && *s !=
'\t' ) s++;
3793 while ( *s ==
' ' || *s ==
'\t' ) s++;
3794 if ( *s != 0 && *s !=
'\n' ) {
3795 MesPrint(
"@Too many parameters in ProcedureExtension instruction");
3799 if ( AP.procedureExtension ) M_free(AP.procedureExtension,
"ProcedureExtension");
3800 AP.procedureExtension = strDup1(t,
"ProcedureExtension");
3810int DoPreOut(UBYTE *s)
3812 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3813 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3814 if ( tolower(*s) ==
'o' ) {
3815 if ( tolower(s[1]) ==
'n' && s[2] == 0 ) {
3819 if ( tolower(s[1]) ==
'f' && tolower(s[2]) ==
'f' && s[3] == 0 ) {
3824 MesPrint(
"@Illegal option in PreOut instruction");
3833int DoPrePrintTimes(UBYTE *s)
3836 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3837 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3847int DoPreSortReallocate(UBYTE *s)
3850 if ( AC.SortReallocateFlag == 0 ) {
3853 AC.SortReallocateFlag = 2;
3867int DoPreAppend(UBYTE *s)
3871 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3872 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3873 if ( AP.preError )
return(0);
3874 while ( *s ==
' ' || *s ==
'\t' ) s++;
3881 while ( *s && *s !=
'>' ) {
3882 if ( *s ==
'\\' ) s++;
3886 MesPrint(
"@Improper termination of filename");
3891 if ( *name ) { GetAppendChannel((
char *)name); }
3896 MesPrint(
"@Proper syntax is: %#append <filename>");
3910int DoPreCreate(UBYTE *s)
3914 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3915 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3916 if ( AP.preError )
return(0);
3917 while ( *s ==
' ' || *s ==
'\t' ) s++;
3924 while ( *s && *s !=
'>' ) {
3925 if ( *s ==
'\\' ) s++;
3929 MesPrint(
"@Improper termination of filename");
3934 if ( *name ) { GetChannel((
char *)name,0); }
3939 MesPrint(
"@Proper syntax is: %#create <filename>");
3950int DoPreRemove(UBYTE *s)
3953 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3954 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3955 if ( AP.preError )
return(0);
3956 while ( *s ==
' ' || *s ==
'\t' ) s++;
3957 if ( *s ==
'<' ) { s++; }
3959 MesPrint(
"@Proper syntax is: %#remove <filename>");
3963 while ( *s && *s !=
'>' ) {
3964 if ( *s ==
'\\' ) s++;
3968 MesPrint(
"@Improper filename");
3973 CloseChannel((
char *)name);
3974 remove((
char *)name);
3983int DoPreClose(UBYTE *s)
3986 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3987 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3988 if ( AP.preError )
return(0);
3989 while ( *s ==
' ' || *s ==
'\t' ) s++;
3990 if ( *s ==
'<' ) { s++; }
3992 MesPrint(
"@Proper syntax is: %#close <filename>");
3996 while ( *s && *s !=
'>' ) {
3997 if ( *s ==
'\\' ) s++;
4001 MesPrint(
"@Improper filename");
4006 return(CloseChannel((
char *)name));
4027int DoPreWrite(UBYTE *s)
4031 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4032 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4033 if ( AP.preError )
return(0);
4036 if ( PF.me != MASTER )
return 0;
4039 h.oldsilent = AM.silent;
4040 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
4041 h.newhandle = h.oldhandle = AC.LogHandle;
4042 h.oldprinttype = AO.PrintType;
4044 while ( *s ==
' ' || *s ==
'\t' ) s++;
4048 if( (s=defineChannel(s,&h))==0 )
return(-1);
4050 return(writeToChannel(WRITEOUT,s,&h));
4068int DoProcedure(UBYTE *s)
4073 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
4074 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
4075 if ( PreSkip((UBYTE *)
"procedure",(UBYTE *)
"endprocedure",1) )
return(-1);
4079 p = (
PROCEDURE *)FromList(&AP.ProcList);
4080 if ( PreLoad(&(p->p),(UBYTE *)
"procedure",(UBYTE *)
"endprocedure"
4081 ,1,(
char *)
"procedure") )
return(-1);
4087 if ( NumProcedures >= 2 &&
4088 ( Procedures[NumProcedures-2].loadmode != 2 || Procedures[NumProcedures-2].mustfree ) ) {
4098 s = p->p.buffer + 10;
4099 while ( *s ==
' ' || *s == LINEFEED ) s++;
4100 if ( chartype[*s] ) {
4101 MesPrint(
"@Illegal name for procedure");
4105 while ( chartype[*s] == 0 || chartype[*s] == 1 ) s++;
4107 p->name = strDup1(p->name,
"procedure");
4112 for ( i = NumProcedures-2; i >= 0; i-- ) {
4113 if ( StrCmp(Procedures[i].name,p->name) == 0 ) {
4114 Error1(
"Multiple occurrence of procedure name ",p->name);
4125int DoPreBreak(UBYTE *s)
4128 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4129 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4130 if ( AP.PreSwitchLevel <= 0 )
4131 MesPrint(
"@Break without corresponding Switch");
4132 else MessPreNesting(7);
4135 if ( AP.PreSwitchLevel <= 0 ) {
4136 MesPrint(
"@Break without corresponding Switch");
4139 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH )
4140 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4149int DoPreCase(UBYTE *s)
4152 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4153 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4154 if ( AP.PreSwitchLevel <= 0 )
4155 MesPrint(
"@Case without corresponding Switch");
4156 else MessPreNesting(8);
4159 if ( AP.PreSwitchLevel <= 0 ) {
4160 MesPrint(
"@Case without corresponding Switch");
4163 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
4167 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
4168 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
4169 if ( s[-2] ==
'\\' ) s--;
4172 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
4176 s = AP.PreSwitchStrings[AP.PreSwitchLevel];
4177 while ( *t == *s && *t ) { s++; t++; }
4178 if ( *t || *s )
return(0);
4179 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
4188int DoPreDefault(UBYTE *s)
4191 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4192 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4193 if ( AP.PreSwitchLevel <= 0 )
4194 MesPrint(
"@Default without corresponding Switch");
4195 else MessPreNesting(9);
4198 if ( AP.PreSwitchLevel <= 0 ) {
4199 MesPrint(
"@Default without corresponding Switch");
4202 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
4203 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
4212int DoPreEndSwitch(UBYTE *s)
4215 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4216 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4217 if ( AP.PreSwitchLevel <= 0 )
4218 MesPrint(
"@EndSwitch without corresponding Switch");
4219 else MessPreNesting(10);
4223 if ( AP.PreSwitchLevel <= 0 ) {
4224 MesPrint(
"@EndSwitch without corresponding Switch");
4227 M_free(AP.PreSwitchStrings[AP.PreSwitchLevel--],
"pre switch string");
4239int DoPreSwitch(UBYTE *s)
4241 UBYTE *t, *switchstring, **newstrings;
4242 int newnum, i, *newmodes;
4243 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4246 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
4247 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
4248 if ( s[-2] ==
'\\' ) s--;
4251 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
4255 switchstring = (UBYTE *)Malloc1((s-t)+1,
"case string");
4258 if ( *t ==
'\\' ) t++;
4262 if ( AP.PreSwitchLevel >= AP.NumPreSwitchStrings ) {
4263 newnum = 2*AP.NumPreSwitchStrings;
4264 newstrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*(newnum+1),
"case strings");
4265 newmodes = (
int *)Malloc1(
sizeof(
int)*(newnum+1),
"case strings");
4266 for ( i = 0; i < AP.NumPreSwitchStrings; i++ )
4267 newstrings[i] = AP.PreSwitchStrings[i];
4268 M_free(AP.PreSwitchStrings,
"AP.PreSwitchStrings");
4269 for ( i = 0; i <= AP.NumPreSwitchStrings; i++ )
4270 newmodes[i] = AP.PreSwitchModes[i];
4271 M_free(AP.PreSwitchModes,
"AP.PreSwitchModes");
4272 AP.PreSwitchStrings = newstrings;
4273 AP.PreSwitchModes = newmodes;
4274 AP.NumPreSwitchStrings = newnum;
4276 AP.PreSwitchStrings[++AP.PreSwitchLevel] = switchstring;
4277 if ( ( AP.PreSwitchLevel > 1 )
4278 && ( AP.PreSwitchModes[AP.PreSwitchLevel-1] != EXECUTINGPRESWITCH ) )
4279 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4281 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPRECASE;
4282 AddToPreTypes(PRETYPESWITCH);
4293int DoPreShow(UBYTE *s)
4297 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4298 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4299 while ( *s ==
' ' || *s ==
'\t' ) s++;
4301 MesPrint(
"%#The preprocessor variables:");
4302 for ( i = 0; i < NumPre; i++ ) {
4303 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4308 name = s;
while ( *s && *s !=
' ' && *s !=
'\t' && *s !=
',' ) s++;
4310 for ( i = 0; i < NumPre; i++ ) {
4311 if ( StrCmp(PreVar[i].name,name) == 0 )
4312 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4315 while ( *s ==
' ' || *s ==
'\t' ) s++;
4329#define STRINGIFY(x) STRINGIFY__(x)
4330#define STRINGIFY__(x) #x
4332int DoSystem(UBYTE *s)
4334 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4335 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4336 if ( AP.preError )
return(0);
4339 while ( *s ==
' ' || *s ==
'\t' ) s++;
4340 if ( *s ==
'-' && s[1] ==
'e' ) {
4345 MesPrint(
"@Syntax error in #system command.");
4348 while ( *s ==
' ' || *s ==
'\t' ) s++;
4349 err = system((
char *)s);
4351 PutPreVar((UBYTE *)
"SYSTEMERROR_",str,0,1);
4353 else if ( system((
char *)s) ) {
4354 MesPrint(
"@System call returned with error condition");
4359 Error0(
"External programs not implemented on this computer/system");
4372int PreLoad(
PRELOAD *p, UBYTE *start, UBYTE *stop,
int mode,
char *message)
4374 UBYTE *s, *t, *top, *newbuffer, c;
4375 LONG i, ppsize, linenum = AC.CurrentStream->linenumber;
4376 int size1, size2, level, com=0, last=1, strng = 0;
4378 p->buffer = (UBYTE *)Malloc1(p->size+1,message);
4379 top = p->buffer + p->size - 2;
4380 t = p->buffer; *t++ =
'#';
4381 s = start; size1 = size2 = 0;
4382 while ( *s ) { s++; size1++; }
4383 s = stop;
while ( *s ) { s++; size2++; }
4384 s = AP.preStart;
while ( *s ) *t++ = *s++; *t++ = LINEFEED;
4389 if ( c == ENDOFINPUT ) {
4390 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4393 if ( c == AP.ComChar && last == 1 ) com = 1;
4394 if ( c == LINEFEED ) { last = 1; com = 0; }
4397 if ( ( c ==
'"' ) && ( com == 0 ) ) { strng ^= 1; }
4399 if ( ( c ==
'#' ) && ( com == 0 ) ) i = 0;
4403 ppsize = t - p->buffer;
4405 newbuffer = (UBYTE *)Malloc1(p->size,message);
4406 t = newbuffer; s = p->buffer;
4407 while ( --ppsize >= 0 ) *t++ = *s++;
4408 M_free(p->buffer,
"loading do loop");
4409 p->buffer = newbuffer;
4410 top = p->buffer + p->size - 2;
4414 if ( ( i == size2 ) && ( com == 0 ) ) {
4416 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4417 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4419 if ( level <= 0 )
break;
4420 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4421 *t++ = LINEFEED; *t = 0; last = 1;
4424 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4426 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4434 if ( i == 1 && t[-2] == LINEFEED ) {
4435 if ( c ==
'-' ) AC.NoShowInput = 1;
4436 else if ( c ==
'+' ) AC.NoShowInput = 0;
4453#define SKIPBUFSIZE 20
4455int PreSkip(UBYTE *start, UBYTE *stop,
int mode)
4457 UBYTE *s, *t, buffer[SKIPBUFSIZE+2], c;
4458 LONG i, linenum = AC.CurrentStream->linenumber;
4459 int size1, size2, level, com=0, last=1;
4461 t = buffer; *t++ =
'#';
4462 s = start; size1 = size2 = 0;
4463 while ( *s ) { s++; size1++; }
4464 s = stop;
while ( *s ) { s++; size2++; }
4469 if ( c == ENDOFINPUT ) {
4470 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4473 if ( c == AP.ComChar && last == 1 ) com = 1;
4474 if ( c == LINEFEED ) { last = 1; com = 0; i = 0; t = buffer; }
4476 if ( ( c ==
'#' ) && ( com == 0 ) ) { i = 0; t = buffer; }
4479 if ( i < SKIPBUFSIZE ) *t++ = c;
4480 if ( ( i == size2 ) && ( com == 0 ) ) {
4482 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4483 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4486 pushbackchar = LINEFEED;
4489 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4493 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4495 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4496 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4510void StartPrepro(
void)
4513 AP.MaxPreIfLevel = 2;
4514 ppp = &AP.PreIfStack;
4515 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
4516 "PreIfLevels") ) Terminate(-1);
4517 AP.PreIfLevel = 0; AP.PreIfStack[0] = EXECUTINGIF;
4519 AP.NumPreSwitchStrings = 10;
4520 AP.PreSwitchStrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*
4521 (AP.NumPreSwitchStrings+1),
"case strings");
4522 AP.PreSwitchModes = (
int *)Malloc1(
sizeof(
int)*
4523 (AP.NumPreSwitchStrings+1),
"case strings");
4524 AP.PreSwitchModes[0] = EXECUTINGPRESWITCH;
4525 AP.PreSwitchLevel = 0;
4538int EvalPreIf(UBYTE *s)
4546 if ( ( u = PreIfEval(s,&val) ) == 0 )
return(-1);
4548 MesPrint(
"@Unmatched parentheses in condition");
4551 if ( val )
return(EXECUTINGIF);
4552 else return(LOOKINGFORELSE);
4573UBYTE *PreIfEval(UBYTE *s,
int *value)
4575 int orlevel = 0, andlevel = 0, eqlevel = 0, cmplevel = 0;
4578 int ortype, orval, cmptype, cmpval, eqtype, eqval, andtype, andval;
4579 UBYTE *t, *eqt, *cmpt, c;
4581 ortype = orval = cmptype = cmpval = eqtype = eqval = andtype = andval = 0;
4585 while ( *s !=
')' ) {
4586 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4588 s = pParseObject(s,&type,&val2);
4589 if ( s == 0 )
return(0);
4593 while ( c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' ) {
4596 if ( *t ==
'"' ) t++;
4599 if ( *s !=
'|' )
goto illoper;
4604 if ( type == 0 || cmptype == 0 )
goto illobject;
4605 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4610 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4615 if ( andtype != 0 || type != 0 )
goto illobject;
4620 if ( ortype != 0 || type != 0 )
goto illobject;
4632 if ( *s !=
'&' )
goto illoper;
4635 if ( type == 0 || cmptype == 0 )
goto illobject;
4636 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4641 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4646 if ( andtype != 0 || type != 0 )
goto illobject;
4655 if ( eqlevel )
goto illorder;
4657 if ( type == 0 || cmptype == 0 )
goto illobject;
4658 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4662 if ( c ==
'!' && *s !=
'=' )
goto illoper;
4663 if ( *s ==
'=' ) s++;
4664 if ( c ==
'!' ) eqop = 1;
4666 eqlevel = 1; eqt = t; eqval = val; eqtype = type;
4670 if ( cmplevel )
goto illorder;
4671 if ( c ==
'<' ) cmpop = -1;
4673 cmplevel = 1; cmpt = t; cmpval = val; cmptype = type;
4676 if ( *s ==
'~' ) { s++; cmpop *= 4; }
4679 else if ( *s ==
'~' ) { s++; cmpop *= 3; }
4687 MesPrint(
"@illegal order of operators");
4690 MesPrint(
"@illegal object for this operator");
4693 MesPrint(
"@illegal operator");
4702int PreCmp(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int cmpop)
4704 if ( type == 2 || type2 == 2 || cmpop < -2 || cmpop > 2 ) {
4705 if ( cmpop < 0 && cmpop > -3 ) cmpop -= 2;
4706 if ( cmpop > 0 && cmpop < 3 ) cmpop += 2;
4707 if ( cmpop == 3 ) val = StrCmp(t2,t) > 0;
4708 else if ( cmpop == 4 ) val = StrCmp(t2,t) >= 0;
4709 else if ( cmpop == -3 ) val = StrCmp(t2,t) < 0;
4710 else if ( cmpop == -4 ) val = StrCmp(t2,t) <= 0;
4713 if ( cmpop == 1 ) val = ( val2 > val );
4714 else if ( cmpop == 2 ) val = ( val2 >= val );
4715 else if ( cmpop == -1 ) val = ( val2 < val );
4716 else if ( cmpop == -2 ) val = ( val2 <= val );
4726int PreEq(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int eqop)
4729 if ( type == 2 || type2 == 2 ) {
4730 if ( type != 2 ) { NumToStr(str,val ); t = str; }
4731 if ( type2 != 2 ) { NumToStr(str,val2); t2 = str; }
4732 if ( eqop == 1 ) val = StrCmp(t,t2) != 0;
4733 else val = StrCmp(t,t2) == 0;
4736 if ( eqop ) val = val != val2;
4737 else val = val == val2;
4755UBYTE *pParseObject(UBYTE *s,
int *type, LONG *val2)
4760 while ( *s ==
' ' || *s ==
'\t' ) s++;
4763 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4764 s = PreIfEval(s,&val);
4769 else if ( *s ==
'$' && s[1] ==
'(' ) {
4771 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4772 s = PreIfDollarEval(s,&val);
4773 *type = 0; *val2 = val;
4778 MesPrint(
"@illegal end of condition");
4783 while ( *s && *s !=
'"' ) {
4784 if ( *s ==
'\\' ) s++;
4787 if ( *s == 0 )
goto illend;
4792 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4796 t = s; sign = 1; x = 0;
4797 if ( chartype[*t] == 0 ) {
4798 do { t++; }
while ( chartype[*t] <= 1 );
4802 if ( StrICmp(s,(UBYTE *)
"termsin") == 0 ) {
4804 WORD numdol, numexp;
4808 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4810 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4812 if ( ( numdol = GetDollar(t) ) > 0 ) {
4815 x = SizeOfDollar(numdol);
4818 x = TermsInDollar(numdol);
4822 MesPrint(
"@$%s has not (yet) been defined",t);
4830 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4831 MesPrint(
"@%s has not (yet) been defined",t);
4838 x = SizeOfExpression(numexp);
4841 x = TermsInExpression(numexp);
4845 while ( *tt ==
' ' || *tt ==
'\t'
4846 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4848 MesPrint(
"@Improper use of terms($var) or terms(expr)");
4856 else if ( StrICmp(s,(UBYTE *)
"sizeof") == 0 ) {
4860 else if ( StrICmp(s,(UBYTE *)
"exists") == 0 ) {
4862 WORD numdol, numexp;
4864 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4866 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4868 if ( ( numdol = GetDollar(t) ) >= 0 ) { x = 1; }
4872 else if ( *t ==
'"' ) {
4876 if ( *tt ==
'\\' ) tt++;
4877 else if ( *tt ==
'"' )
break;
4890 x = OpenFile((
char *)t);
4907 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) { x = 0; }
4911 while ( *tt ==
' ' || *tt ==
'\t'
4912 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4914 MesPrint(
"@Improper use of exists($var) or exists(expr)");
4922 else if ( StrICmp(s,(UBYTE *)
"isnumerical") == 0 ) {
4925 WORD numdol, numexp;
4927 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4929 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4931 if ( ( numdol = GetDollar(t) ) < 0 ) {
4932 MesPrint(
"@$ variable in isnumerical(%s) does not exist",t);
4935 x = DolToLong(BHEAD numdol);
4936 if ( AN.ErrorInDollar ) {
4939 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
4940 if ( d->where[0] == 0 ) x = 1;
4941 else if ( d->where[d->where[0]] == 0 ) {
4942 if ( ABS(d->where[d->where[0]-1]) == d->where[0]-1 )
4953 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4954 MesPrint(
"@expression in isnumerical(%s) does not exist",t);
4957 x = TermsInExpression(numexp);
4958 if ( x != 1 ) x = 0;
4960 WORD *term = AT.WorkPointer;
4962 MesPrint(
"@error reading expression in isnumerical(%s)",t);
4965 if ( *term == ABS(term[*term-1])+1 ) x = 1;
4970 while ( *tt ==
' ' || *tt ==
'\t'
4971 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4973 MesPrint(
"@Improper use of isnumerical($var) or numerical(expr)");
4981 else if ( StrICmp(s,(UBYTE *)(
"maxpowerof")) == 0 ) {
4986 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4989 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4990 MesPrint(
"@%s has not (yet) been defined",t);
4994 else if ( stype != CSYMBOL ) {
4995 MesPrint(
"@%s should be a symbol",t);
5001 x = symbols[numsym].maxpower;
5003 while ( *tt ==
' ' || *tt ==
'\t'
5004 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5006 MesPrint(
"@Improper use of maxpowerof(symbol)");
5014 else if ( StrICmp(s,(UBYTE *)(
"minpowerof")) == 0 ) {
5019 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5022 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
5023 MesPrint(
"@%s has not (yet) been defined",t);
5027 else if ( stype != CSYMBOL ) {
5028 MesPrint(
"@%s should be a symbol",t);
5034 x = symbols[numsym].minpower;
5036 while ( *tt ==
' ' || *tt ==
'\t'
5037 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5039 MesPrint(
"@Improper use of minpowerof(symbol)");
5047 else if ( StrICmp(s,(UBYTE *)
"isfactorized") == 0 ) {
5049 WORD numdol, numexp;
5051 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5053 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
5055 if ( ( numdol = GetDollar(t) ) > 0 ) {
5056 if ( Dollars[numdol].factors != 0 ) x = 1;
5060 MesPrint(
"@ %s should be the name of an expression or a $ variable",t-1);
5068 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
5069 MesPrint(
"@ %s should be the name of an expression or a $ variable",t);
5073 if ( ( Expressions[numexp].vflags & ISFACTORIZED ) != 0 ) x = 1;
5078 while ( *tt ==
' ' || *tt ==
'\t'
5079 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5081 MesPrint(
"@Improper use of isfactorized($var) or isfactorized(expr)");
5089 else if ( StrICmp(s,(UBYTE *)
"isdefined") == 0 ) {
5092 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5098 while ( *tt ==
' ' || *tt ==
'\t'
5099 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5101 MesPrint(
"@Improper use of isdefined(var)");
5109 else if ( StrICmp(s,(UBYTE *)
"flag") == 0 ) {
5114 while ( *t ==
' ' || *t ==
'\t' ) t++;
5115 if ( FG.cTable[*t] != 1 )
goto flagerror;
5116 while ( FG.cTable[*t] == 1 ) x = 10*x + (*t++ -
'0');
5117 if ( x < 1 || x > BITSINWORD ) {
5118 MesPrint(
"@Illegal number %d for flag in flag condition",x);
5121 while ( *t ==
' ' || *t ==
'\t' ) t++;
5122 if ( *t !=
',' )
goto flagerror;
5124 while ( *t ==
' ' || *t ==
'\t' ) t++;
5127 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
5128 MesPrint(
"@ %s should be the name of an expression",t);
5132 while ( *t ==
' ' || *t ==
'\t' ) t++;
5135 MesPrint(
"@Improper use of flag(num,expr)");
5139 if ( ( Expressions[numexp].uflags & ( 1 << (x-1) ) ) != 0 )
5149 else if ( *t ==
'=' || *t ==
'<' || *t ==
'>' || *t ==
'!'
5150 || *t ==
')' || *t ==
' ' || *t ==
'\t' || *t == 0 || *t ==
'\n' ) {
5156 MesPrint(
"@Illegal use of string in preprocessor condition: %s",s);
5160 while ( *t ==
'-' || *t ==
'+' || *t ==
' ' || *t ==
'\t' ) {
5161 if ( *t ==
'-' ) sign = -sign;
5164 while ( chartype[*t] == 1 ) { x = 10*x + *t++ -
'0'; }
5165 while ( *t ==
' ' || *t ==
'\t' ) t++;
5166 if ( chartype[*t] == 8 || *t ==
')' || *t ==
'=' || *t == 0 ) {
5167 *val2 = sign > 0 ? x: -x;
5171 while ( chartype[*t] != 8 && *t !=
')' && *t !=
'=' && *t ) t++;
5172 while ( ( t > s ) && ( t[-1] ==
' ' || t[-1] ==
'\t' ) ) t--;
5193 UBYTE *buff, *s = 0, *t, *newb, c;
5194 int size, i, n, parlevel = 0, bralevel = 0;
5201 if ( size == 0 ) size = 72;
5203 if ( ( newb = (UBYTE *)Malloc1(size+2,
"{}") ) == 0 )
return(0);
5209 M_free(buff,
"pre calc buffer");
5217 Error0(
"Unmatched {}");
5218 M_free(buff,
"precalc buffer");
5221 else if ( c ==
'{' ) { bralevel++; }
5222 else if ( c ==
'}' ) {
5223 if ( --bralevel < 0 ) { *s++ = c; *s = 0;
break; }
5225 else if ( c ==
'(' ) { parlevel++; }
5226 else if ( c ==
')' ) {
5227 if ( --parlevel < 0 ) { *s++ = c; *s = 0;
goto setstring; }
5229 else if ( chartype[c] != 1 && chartype[c] != 5
5230 && chartype[c] != 6 && c !=
'!' && c !=
'&'
5231 && c !=
'|' && c !=
'\\' ) { *s++ = c; *s = 0;
goto setstring; }
5233 if ( parlevel > 0 )
goto setstring;
5239 if ( PreEval(buff+1,&answer) == 0 )
goto setstring;
5242 if ( answer < 0 ) { *s++ =
'-'; }
5243 uanswer = LongAbs(answer);
5246 *--t = ( uanswer % 10 ) +
'0';
5249 }
while ( uanswer > 0 );
5257 if ( OpenStream(buff,PRECALCSTREAM,0,PRENOACTION) == 0 )
return(0);
5269UBYTE *PreEval(UBYTE *s, LONG *x)
5272 int tobemultiplied, tobeadded = 1, expsign, i;
5275 while ( *s ==
' ' || *s ==
'\t' ) s++;
5277 if ( *s ==
'+' || *s ==
'-' ) {
5278 if ( *s ==
'-' ) tobeadded = -1;
5281 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5282 if ( *s ==
'-' ) tobeadded = -tobeadded;
5288 while ( *s ==
' ' || *s ==
'\t' ) s++;
5289 if ( *s <=
'9' && *s >=
'0' ) {
5294 else if ( *s ==
'(' || *s ==
'{' ) {
5295 if ( ( t = PreEval(s+1,&y) ) == 0 )
return(0);
5299 while ( *s ==
' ' || *s ==
'\t' ) s++;
5301 while ( *s ==
'^' || *s ==
'!' ) {
5303 if ( s[-1] ==
'!' ) {
5304 while ( *s ==
' ' || *s ==
'\t' ) s++;
5306 MesPrint(
"@Negative value in preprocessor factorial: %l",y);
5309 else if ( y == 0 ) y = 1;
5312 while ( z > 0 ) { y = y*z; z--; }
5316 else if ( *s ==
'%' ) {
5318 while ( *s ==
' ' || *s ==
'\t' ) s++;
5321 MesPrint(
"@Illegal value in preprocessor logarithm: %l",z);
5325 while ( z ) { y++; z >>= 1; }
5328 else if ( *s ==
'/' ) {
5331 while ( *s ==
' ' || *s ==
'\t' ) s++;
5334 MesPrint(
"@Illegal value in preprocessor square root: %l",z);
5340 while ( zz ) { yy++; zz >>= 1; }
5341 zz = z >> (yy/2); i = 10; y = 0;
5343 yy = zz/2 + z/(2*zz); i--;
5344 if ( y == yy )
break;
5346 }
while ( y != yy && i > 0 );
5347 while ( y*y < z ) y++;
5348 while ( y*y > z ) y--;
5350 else if ( z >= 4 ) y = 2;
5351 else if ( z == 0 ) y = 0;
5355 while ( *s ==
' ' || *s ==
'\t' ) s++;
5356 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5357 if ( *s ==
'-' ) expsign = -expsign;
5359 if ( *s <=
'9' && *s >=
'0' ) {
5362 else if ( *s ==
'(' || *s ==
'{' ) {
5363 if ( ( t = PreEval(s+1,&z) ) == 0 )
return(0);
5367 while ( *s ==
' ' || *s ==
'\t' ) s++;
5370 if ( tobemultiplied == 0 ) {
5371 if ( expsign < 0 ) a = 1/y;
5375 if ( tobemultiplied > 2 && expsign != 1 ) {
5376 MesPrint(
"&Incorrect use of ^ with & or |. Use brackets!");
5379 tobemultiplied *= expsign;
5380 if ( tobemultiplied == 1 ) a *= y;
5381 else if ( tobemultiplied == 3 ) a &= y;
5382 else if ( tobemultiplied == 4 ) a |= y;
5384 if ( y == 0 || tobemultiplied == -2 ) {
5385 MesPrint(
"@Division by zero in preprocessor calculator");
5388 if ( tobemultiplied == 2 ) a %= y;
5392 if ( *s ==
'%' ) tobemultiplied = 2;
5393 else if ( *s ==
'*' ) tobemultiplied = 1;
5394 else if ( *s ==
'/' ) tobemultiplied = -1;
5395 else if ( *s ==
'&' ) tobemultiplied = 3;
5396 else if ( *s ==
'|' ) tobemultiplied = 4;
5401 if ( tobeadded >= 0 ) ux += ua;
5403 *x = ULongToLong(ux);
5404 if ( *s ==
')' || *s ==
'}' )
return(s+1);
5405 else if ( *s ==
'-' || *s ==
'+' ) { tobeadded = 1;
break; }
5419void AddToPreTypes(
int type)
5421 if ( AP.NumPreTypes >= AP.MaxPreTypes ) {
5422 int i, *newlist = (
int *)Malloc1(
sizeof(
int)*(2*AP.MaxPreTypes+1)
5423 ,
"preprocessor type lists");
5424 for ( i = 0; i <= AP.MaxPreTypes; i++ ) newlist[i] = AP.PreTypes[i];
5425 M_free(AP.PreTypes,
"preprocessor type lists");
5426 AP.PreTypes = newlist;
5427 AP.MaxPreTypes = 2*AP.MaxPreTypes;
5429 AP.PreTypes[++AP.NumPreTypes] = type;
5437void MessPreNesting(
int par)
5439 MesPrint(
"@(%d)Illegal nesting of %#if, %#do, %#procedure and/or %#switch",par);
5460int DoPreAddSeparator(UBYTE *s)
5462 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5463 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5464 for(;*s !=
'\0';s++){
5465 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5472 set_set(*s,AC.separators);
5485int DoPreRmSeparator(UBYTE *s)
5487 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5488 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5489 for(;*s !=
'\0';s++){
5490 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5491 set_del(*s,AC.separators);
5502int DoExternal(UBYTE *s)
5504#ifdef WITHEXTERNALCHANNEL
5510 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5511 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5512 if ( AP.preError )
return(0);
5514#ifdef WITHEXTERNALCHANNEL
5515 while ( *s ==
' ' || *s ==
'\t' ) s++;
5519 if ( chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5521 MesPrint(
"@Can't finde closing \"");
5523 case 0:
case 1:
continue;
5528 MesPrint(
"@Illegal name of preprocessor variable to store external channel");
5532 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5536 MesPrint(
"@Illegal external command");
5542 externalD=openExternalChannel(
5550 Error1(
"Can't start external program",s);
5557 NumToStr(buf,externalD);
5558 if (
PutPreVar(prevar,buf,0,1) < 0 )
return(-1);
5561 AX.currentExternalChannel=externalD;
5563 if(AX.currentPrompt!=0){
5564 if(setTerminatorForExternalChannel( (
char *)AX.currentPrompt)){
5565 MesPrint(
"@Prompt is too long");
5569 setKillModeForExternalChannel(AX.killSignal,AX.killWholeGroup);
5573 Error0(
"External channel: not implemented on this computer/system");
5584int DoPrompt(UBYTE *s)
5586#ifndef WITHEXTERNALCHANNEL
5589 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5590 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5592#ifdef WITHEXTERNALCHANNEL
5593 while ( *s ==
' ' || *s ==
'\t' ) s++;
5594 if ( AX.currentPrompt )
5595 M_free(AX.currentPrompt,
"external channel prompt");
5597 AX.currentPrompt = (UBYTE *)strDup1((UBYTE *)
"",
"external channel prompt");
5599 AX.currentPrompt = strDup1(s,
"external channel prompt");
5600 if( setTerminatorForExternalChannel( (
char *)AX.currentPrompt) > 0 ){
5601 MesPrint(
"@Prompt is too long");
5607 Error0(
"External channel: not implemented on this computer/system");
5617int DoSetExternal(UBYTE *s)
5619#ifdef WITHEXTERNALCHANNEL
5624 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5625 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5626 if ( AP.preError )
return(0);
5628#ifdef WITHEXTERNALCHANNEL
5629 while ( *s ==
' ' || *s ==
'\t' ) s++;
5630 while ( chartype[*s] == 1 ) { n = 10*n + *s++ -
'0'; }
5631 while ( *s ==
' ' || *s ==
'\t' ) s++;
5633 MesPrint(
"@setexternal: number expected");
5636 if(selectExternalChannel(n)<0){
5637 MesPrint(
"@setexternal: invalid number");
5640 AX.currentExternalChannel=n;
5643 Error0(
"External channel: not implemented on this computer/system");
5652static FORM_INLINE UBYTE *pickupword(UBYTE *s)
5655 for(;*s>
' ';s++)
switch(*s){
5666static inline int strINCmp(UBYTE *a, UBYTE *b,
int n)
5668 for(;n>0;n--)
if(tolower(*a++)!=tolower(*b++))
5674#define KILLALL "killall"
5675#define DAEMON "daemon"
5676#define SHELL "shell"
5677#define STDERR "stderr"
5679#define TRUE_EXPR "true"
5680#define FALSE_EXPR "false"
5681#define NOSHELL "noshell"
5682#define TERMINAL "terminal"
5687int DoSetExternalAttr(UBYTE *s)
5689#ifdef WITHEXTERNALCHANNEL
5695 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5696 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5697 if ( AP.preError )
return(0);
5699#ifdef WITHEXTERNALCHANNEL
5702 while ( *s ==
' ' || *s ==
'\t' ) s++;
5703 s=pickupword(nam=s);
5705 while ( *s ==
' ' || *s ==
'\t' ) s++;
5707 MesPrint(
"@External channel:'=' expected instead of %s",s-1);
5711 while ( *s ==
' ' || *s ==
'\t' ) s++;
5718 while ( *s ==
' ' || *s ==
'\t' ) s++;
5719 if( (*s ==
',')||(*s ==
'\n')||(*s ==
';')||(*s ==
'\0') ){
5726 while ( *s ==
' ' || *s ==
'\t' ) s++;
5728 if(strINCmp((UBYTE *)SHELL,nam,lnam)==0){
5729 if(AX.shellname!=NULL)
5730 M_free(AX.shellname,
"external channel shellname");
5731 if(strINCmp((UBYTE *)NOSHELL,val,lval)==0)
5735 b=ch=AX.shellname=Malloc1(lval+1,
"external channel shellname");
5740 }
else if(strINCmp((UBYTE *)DAEMON,nam,lnam)==0){
5741 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5743 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5746 MesPrint(
"@External channel:true or false expected for %s",DAEMON);
5749 }
else if(strINCmp((UBYTE *)KILLALL,nam,lnam)==0){
5750 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5751 AX.killWholeGroup = 1;
5752 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5753 AX.killWholeGroup = 0;
5755 MesPrint(
"@External channel: true or false expected for %s",KILLALL);
5758 }
else if(strINCmp((UBYTE *)KILL,nam,lnam)==0){
5760 for(i=0;i<lval;i++) {
5761 if( *val>=
'0' && *val<=
'9' )
5762 n = 10*n + *val++ -
'0';
5764 MesPrint(
"@External channel: number expected for %s",KILL);
5769 }
else if(strINCmp((UBYTE *)STDERR,nam,lnam)==0){
5770 if( AX.stderrname != NULL ) {
5771 M_free(AX.stderrname,
"external channel stderrname");
5773 if(strINCmp((UBYTE *)TERMINAL,val,lval)==0)
5774 AX.stderrname = NULL;
5777 b=ch=AX.stderrname=Malloc1(lval+1,
"external channel stderrname");
5784 MesPrint(
"@External channel: unrecognized attribute",nam);
5787 }
while(*s++ ==
',');
5788 if( (*(s-1)>
' ')&&(*(s-1)!=
';') ){
5789 MesPrint(
"@External channel: syntax error: %s",s-1);
5794 Error0(
"External channel: not implemented on this computer/system");
5804int DoRmExternal(UBYTE *s)
5806#ifdef WITHEXTERNALCHANNEL
5811 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5812 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5813 if ( AP.preError )
return(0);
5815#ifdef WITHEXTERNALCHANNEL
5816 while ( *s ==
' ' || *s ==
'\t' ) s++;
5817 if( chartype[*s] == 1 ){
5818 for(n=0; chartype[*s] == 1 ; s++) { n = 10*n + *s -
'0'; }
5819 while ( *s ==
' ' || *s ==
'\t' ) s++;
5822 MesPrint(
"@rmexternal: invalid number");
5827 closeAllExternalChannels();
5828 AX.currentExternalChannel=0;
5832 n=AX.currentExternalChannel;
5835 closeExternalChannel(n);
5837 if (n == AX.currentExternalChannel)
5838 AX.currentExternalChannel=0;
5841 Error0(
"External channel: not implemented on this computer/system");
5869int DoFromExternal(UBYTE *s)
5871#ifdef WITHEXTERNALCHANNEL
5874 int withNoList=AC.NoShowInput;
5875 int oldpreassignflag;
5879 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5880 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5881 if ( AP.preError )
return(0);
5882#ifdef WITHEXTERNALCHANNEL
5886 while ( *s ==
' ' || *s ==
'\t' ) s++;
5888 if ( *s ==
'-' || *s ==
'+' ) {
5894 while ( *s ==
' ' || *s ==
'\t' ) s++;
5901 if ( *s==
'$' || chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5903 MesPrint(
"@Can't finde closing \"");
5905 case 0:
case 1:
continue;
5910 MesPrint(
"@Illegal name to store output of external channel");
5914 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5918 if( chartype[*s] == 1 ){
5919 for(lbuf=0; chartype[*s] == 1 ; s++) { lbuf = 10*lbuf + *s -
'0'; }
5920 while ( *s ==
' ' || *s ==
'\t' ) s++;
5922 if( (*s!=
'\0')||(lbuf<0) ){
5923 MesPrint(
"@Illegal buffer length in fromexternal");
5928 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5931 if(selectExternalChannel(AX.currentExternalChannel)){
5932 MesPrint(
"@No current external channel");
5943 buf=Malloc1( (lbuf=255)+1,
"Fromexternal");
5949 for(i=0;(cc=getcFromExtChannel())>0;i++){
5953 UBYTE *tmp=Malloc1( (lbuf*=2)+1,
"Fromexternal");
5954 for(j=0;j<i;j++)tmp[j]=buf[j];
5955 M_free(buf,
"Fromexternal");
5962 MesPrint(
"@No current external channel");
5970 buf=Malloc1(lbuf+1,
"Fromexternal");
5971 for(i=0; i<lbuf;i++){
5977 if( (cc=getcFromExtChannel())<1 )
5990 while(getcFromExtChannel()>0);
5992 MesPrint(
"@No current external channel");
5999 int oldNumPotModdollars = NumPotModdollars;
6001 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
6002 AC.RhsExprInModuleFlag = 0;
6006 UBYTE *pbuf=Malloc1(StrLen(prevar)+1+lbuf+1,
"Fromexternal to dollar");
6009 while(*b!=
'\0'){*c++ = *b++;}
6012 while( (*c++=*b++)!=
'\0' );
6013 oldpreassignflag = AP.PreAssignFlag;
6014 AP.PreAssignFlag = 1;
6015 if ( ( cc = CompileStatement(pbuf) ) || ( cc = CatchDollar(0) ) ) {
6016 Error1(
"External channel: can't asign output to dollar variable ",prevar);
6018 AP.PreAssignFlag = oldpreassignflag;
6019 NumPotModdollars = oldNumPotModdollars;
6021 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
6023 M_free(pbuf,
"Fromexternal to dollar");
6028 M_free(buf,
"Fromexternal");
6029 if ( cc )
return(-1);
6033 if ( OpenStream(s,EXTERNALCHANNELSTREAM,0,PRENOACTION) == 0 )
return(-1);
6035 AC.NoShowInput = withNoList;
6039 Error0(
"External channel: not implemented on this computer/system");
6050#ifdef WITHEXTERNALCHANNEL
6053LONG WriteToExternalChannel(
int handle, UBYTE *buffer, LONG size)
6058 if(writeBufToExtChannel((
char*)buffer,size))
6064int DoToExternal(UBYTE *s)
6066#ifdef WITHEXTERNALCHANNEL
6068 LONG (*OldWrite)(
int handle, UBYTE *buffer, LONG size) = WriteFile;
6073 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6074 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6075 if ( AP.preError )
return(0);
6076#ifdef WITHEXTERNALCHANNEL
6078 h.oldsilent=AM.silent;
6079 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
6080 h.newhandle = h.oldhandle = AC.LogHandle;
6081 h.oldprinttype = AO.PrintType;
6083 WriteFile=&WriteToExternalChannel;
6085 while ( *s ==
' ' || *s ==
'\t' ) s++;
6087 if(AX.currentExternalChannel==0){
6088 MesPrint(
"@No current external channel");
6089 goto DoToExternalReady;
6092 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
6093 selectExternalChannel(AX.currentExternalChannel);
6095 ret=writeToChannel(EXTERNALCHANNELOUT,s,&h);
6100 Error0(
"External channel: not implemented on this computer/system");
6111UBYTE *defineChannel(UBYTE *s,
HANDLERS *h)
6120 while ( *s && *s !=
'>' ) {
6121 if ( *s ==
'\\' ) s++;
6125 MesPrint(
"@Improper termination of filename");
6131 h->newhandle = GetChannel((
char *)name,0);
6134 else if ( AC.LogHandle >= 0 ) {
6135 h->newhandle = AC.LogHandle;
6146int writeToChannel(
int wtype, UBYTE *s,
HANDLERS *h)
6148 UBYTE *to, *fstring, *ss, *sss, *s1, c, c1;
6149 WORD num, number, nfac;
6150 WORD oldOptimizationLevel;
6151 UBYTE Out[MAXLINELENGTH+14], *stopper;
6158 while ( *s ==
',' || *s ==
' ' ) s++;
6160 MesPrint(
"@No format string present");
6163 s++; fstring = to = s;
6169 if ( *s ==
'\\' ) *to++ = *s++;
6171 else if ( *s ==
'"' ) *to++ = *s++;
6172 else { *to++ =
'\\'; *to++ = *s++; }
6174 else if ( *s ==
'"' )
break;
6178 MesPrint(
"@No closing \" in format string");
6182 if ( AC.LineLength > 20 && AC.LineLength <= MAXLINELENGTH ) stopper = Out + AC.LineLength;
6183 else stopper = Out + MAXLINELENGTH;
6190 AC.LogHandle = h->newhandle;
6191 AM.FileOnlyFlag = h->newlogonly;
6192 if ( h->newhandle >= 0 ) {
6193 AO.PrintType |= PRINTLFILE;
6195 while ( *fstring ) {
6196 if ( to >= stopper ) {
6197 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6201 WriteString(wtype,Out,num);
6203 if ( AC.OutputMode == FORTRANMODE
6204 || AC.OutputMode == PFORTRANMODE ) {
6206 for ( i = 0; i < number; i++ ) *to++ =
' ';
6210 if ( *fstring ==
'\\' ) {
6212 if ( *fstring ==
'n' ) {
6214 WriteString(wtype,Out,num);
6218 else if ( *fstring ==
't' ) { *to++ =
'\t'; fstring++; }
6219 else if ( *fstring ==
'b' ) { *to++ =
'\\'; fstring++; }
6220 else *to++ = *fstring++;
6222 else if ( *fstring ==
'%' ) {
6226 if ( *fstring ==
'd' ) {
6230 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6232 while ( *s ==
'+' || *s ==
'-' ) {
6233 if ( *s ==
'-' ) sign = -sign;
6236 dig = 0; ss = s;
if ( sign < 0 ) { ss--; *ss =
'-'; dig++; }
6237 while ( *s >=
'0' && *s <=
'9' ) { s++; dig++; }
6240 if ( to >= stopper ) {
6242 WriteString(wtype,Out,num);
6245 if ( *ss ==
'\\' ) ss++;
6250 if ( number < dig ) { dig = number; ss = s - dig; }
6251 while ( number > dig ) {
6252 if ( to >= stopper ) {
6254 WriteString(wtype,Out,num);
6257 *to++ =
' '; number--;
6260 if ( to >= stopper ) {
6262 WriteString(wtype,Out,num);
6265 if ( *ss ==
'\\' ) ss++;
6271 else if ( *fstring ==
'$' ) {
6273 number = AO.OutSkip;
6275 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6276 if ( AC.OutputMode == FORTRANMODE
6277 || AC.OutputMode == PFORTRANMODE ) {
6281nodollar: MesPrint(
"@$-variable expected in #write instruction");
6282 AM.FileOnlyFlag = h->oldlogonly;
6283 AC.LogHandle = h->oldhandle;
6284 AO.PrintType = h->oldprinttype;
6285 AM.silent = h->oldsilent;
6289 while ( chartype[*s] <= 1 ) s++;
6290 if ( s == ss )
goto nodollar;
6292 num = GetDollar(ss);
6294 MesPrint(
"@#write instruction: $%s has not been defined",ss);
6295 AM.FileOnlyFlag = h->oldlogonly;
6296 AC.LogHandle = h->oldhandle;
6297 AO.PrintType = h->oldprinttype;
6298 AM.silent = h->oldsilent;
6303 if ( Dollars[num].nfactors <= 0 ) {
6305 MesPrint(
"@#write instruction: $%s has not been factorized",ss);
6306 AM.FileOnlyFlag = h->oldlogonly;
6307 AC.LogHandle = h->oldhandle;
6308 AO.PrintType = h->oldprinttype;
6309 AM.silent = h->oldsilent;
6315 nfac = GetDollarNumber(&s,Dollars+num);
6317 if ( Dollars[num].nfactors == 1 && nfac == 1 )
goto writewhole;
6319 if ( ( dolalloc = WriteDollarFactorToBuffer(num,nfac,0) ) == 0 ) {
6320 AM.FileOnlyFlag = h->oldlogonly;
6321 AC.LogHandle = h->oldhandle;
6322 AO.PrintType = h->oldprinttype;
6323 AM.silent = h->oldsilent;
6328 else if ( *s && *s !=
' ' && *s !=
',' && *s !=
'\t' ) {
6329 MesPrint(
"@#write instruction: illegal characters after $-variable");
6330 AM.FileOnlyFlag = h->oldlogonly;
6331 AC.LogHandle = h->oldhandle;
6332 AO.PrintType = h->oldprinttype;
6333 AM.silent = h->oldsilent;
6338 if ( ( dolalloc = WriteDollarToBuffer(num,0) ) == 0 ) {
6339 AM.FileOnlyFlag = h->oldlogonly;
6340 AC.LogHandle = h->oldhandle;
6341 AO.PrintType = h->oldprinttype;
6342 AM.silent = h->oldsilent;
6349 if ( to >= stopper ) {
6350 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6354 WriteString(wtype,Out,num);
6356 for ( i = 0; i < number; i++ ) *to++ =
' ';
6357 if ( AC.OutputMode == FORTRANMODE
6358 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6360 if ( chartype[*ss] > 3 ) { *to++ = *ss++; }
6362 sss = ss;
while ( chartype[*ss] <= 3 ) ss++;
6363 if ( ( to + (ss-sss) ) >= stopper ) {
6364 if ( (ss-sss) >= (stopper-Out) ) {
6365 if ( ( to - stopper ) < 10 ) {
6366 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6370 WriteString(wtype,Out,num);
6372 for ( i = 0; i < number; i++ ) *to++ =
' ';
6373 if ( AC.OutputMode == FORTRANMODE
6374 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6376 while ( (ss-sss) >= (stopper-Out) ) {
6377 while ( to < stopper-1 ) {
6380 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6387 WriteString(wtype,Out,num);
6389 if ( AC.OutputMode == FORTRANMODE
6390 || AC.OutputMode == PFORTRANMODE ) {
6391 for ( i = 0; i < number; i++ ) *to++ =
' ';
6397 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6401 WriteString(wtype,Out,num);
6403 for ( i = 0; i < number; i++ ) *to++ =
' ';
6404 if ( AC.OutputMode == FORTRANMODE
6405 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6408 while ( sss < ss ) *to++ = *sss++;
6412 M_free(dolalloc,
"written dollar");
6416 else if ( *fstring ==
's' ) {
6418 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6422 if ( *s ==
'\\' ) s++;
6423 else if ( *s ==
'"' )
break;
6427 MesPrint(
"@#write instruction: Missing \" in string");
6428 AM.FileOnlyFlag = h->oldlogonly;
6429 AC.LogHandle = h->oldhandle;
6430 AO.PrintType = h->oldprinttype;
6431 AM.silent = h->oldsilent;
6435 if ( to >= stopper ) {
6437 WriteString(wtype,Out,num);
6440 if ( *ss ==
'\\' ) ss++;
6447 while ( *s && *s !=
',' ) {
6448 if ( *s ==
'\\' ) { s++; sss = s+1; }
6451 while ( s > sss+1 && ( s[-1] ==
' ' || s[-1] ==
'\t' ) ) s--;
6453 if ( to >= stopper ) {
6455 WriteString(wtype,Out,num);
6458 if ( *ss ==
'\\' ) ss++;
6463 else if ( *fstring ==
'X' ) {
6465 if ( cbuf[AM.sbufnum].numrhs > 0 ) {
6469 UBYTE *s = GetPreVar(AM.oldnumextrasymbols,0);
6471 while ( *s >=
'0' && *s <=
'9' ) x = 10*x + *s++ -
'0';
6473 PrintSubtermList(1,x);
6475 PrintSubtermList(1,cbuf[AM.sbufnum].numrhs);
6478 else if ( *fstring ==
'O' ) {
6479 number = AO.OutSkip;
6485 if ( AO.OptimizeResult.code == NULL && AO.OptimizationLevel != 0 ) {
6486 MesPrint(
"@In #write instruction: no optimization results available!");
6490 WriteString(wtype,Out,num);
6492 if ( AO.OptimizationLevel != 0 ) {
6493 WORD oldoutskip = AO.OutSkip;
6494 AO.OutSkip = number;
6496 AO.OutSkip = oldoutskip;
6499 else if ( *fstring ==
'e' || *fstring ==
'E' ) {
6500 if ( *fstring ==
'E'
6501 || AC.OutputMode == FORTRANMODE
6502 || AC.OutputMode == PFORTRANMODE ) nosemi = 1;
6505 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6506 if ( chartype[*s] != 0 && *s !=
'[' ) {
6507noexpr: MesPrint(
"@expression name expected in #write instruction");
6508 AM.FileOnlyFlag = h->oldlogonly;
6509 AC.LogHandle = h->oldhandle;
6510 AO.PrintType = h->oldprinttype;
6511 AM.silent = h->oldsilent;
6515 if ( ( s =
SkipAName(ss) ) == 0 || s[-1] ==
'_' )
goto noexpr;
6516 s1 = s; c = c1 = *s1;
6520 AO.CurBufWrt = s1+1;
6524 MesPrint(
"@Illegal () specifier in expression name in #write");
6525 AM.FileOnlyFlag = h->oldlogonly;
6526 AC.LogHandle = h->oldhandle;
6527 AO.PrintType = h->oldprinttype;
6528 AM.silent = h->oldsilent;
6532 else AO.CurBufWrt = (UBYTE *)underscore;
6535 if ( num > 0 ) WriteUnfinString(wtype,Out,num);
6537 oldOptimizationLevel = AO.OptimizationLevel;
6538 AO.OptimizationLevel = 0;
6539 if ( WriteOne(ss,(
int)num,nosemi,plus) < 0 ) {
6540 AM.FileOnlyFlag = h->oldlogonly;
6541 AC.LogHandle = h->oldhandle;
6542 AO.PrintType = h->oldprinttype;
6543 AM.silent = h->oldsilent;
6546 AO.OptimizationLevel = oldOptimizationLevel;
6548 if ( s > s1 ) *s++ = c;
6553 else if ( ( *fstring ==
'f' ) || ( *fstring ==
'F' ) ) {
6555 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6557 while ( *s && *s !=
',' ) {
6558 if ( *s ==
'\\' ) s++;
6562 s1 = LoadInputFile(ss,HEADERFILE);
6569 ss = s1;
while ( *ss ) ss++;
6571 WriteString(wtype,s1,n);
6572 M_free(s1,
"copy file");
6574 else if ( *fstring ==
'F' ) {
6576 MesPrint(
"@Error in #write: could not open file %s",ss);
6578 goto ReturnWithError;
6582 else if ( *fstring ==
'%' ) {
6585 else if ( FG.cTable[*fstring] == 1 ) {
6587 while ( FG.cTable[*fstring] == 1 ) {
6588 number = 10*number + *fstring++ -
'0';
6590 if ( *fstring ==
'O' )
goto dooptim;
6591 else if ( *fstring ==
'd' )
goto donumber;
6592 else if ( *fstring ==
'$' )
goto dodollar;
6593 else if ( *fstring ==
't' ) {
6594 if ( number < (WORD)(stopper-Out) ) {
6595 while ( (WORD)(to-Out) < number ) *to++ =
' ';
6599 else if ( *fstring ==
'X' || *fstring ==
'x' ) {
6600 if ( number > 0 && number <= cbuf[AM.sbufnum].numrhs ) {
6601 UBYTE buffer[80], *out, *old1, *old2, *old3;
6603 if ( *fstring ==
'X' ) {
6604 out = StrCopy((UBYTE *)AC.extrasym,buffer);
6605 if ( AC.extrasymbols == 0 ) {
6606 out = NumCopy(number,out);
6607 out = StrCopy((UBYTE *)
"_",out);
6609 else if ( AC.extrasymbols == 1 ) {
6610 if ( AC.OutputMode == CMODE ) {
6611 out = StrCopy((UBYTE *)
"[",out);
6612 out = NumCopy(number,out);
6613 out = StrCopy((UBYTE *)
"]",out);
6616 out = StrCopy((UBYTE *)
"(",out);
6617 out = NumCopy(number,out);
6618 out = StrCopy((UBYTE *)
")",out);
6621 out = StrCopy((UBYTE *)
"=",out);
6623 while ( ss < out ) {
6624 if ( to >= stopper ) {
6626 WriteString(wtype,Out,num);
6632 term = cbuf[AM.sbufnum].rhs[number];
6639 old2 = AO.OutputLine;
6642 AO.OutputLine = Out;
6643 AO.OutStop = Out + AC.LineLength;
6645 if ( WriteInnerTerm(term,first) ) Terminate(-1);
6649 to = Out + (AO.OutFill-AO.OutputLine);
6651 AO.OutputLine = old2;
6658 goto IllegControlSequence;
6661 else if ( *fstring ==
'+' ) {
6662 plus = 1;
goto retry;
6664 else if ( *fstring == 0 ) {
6668IllegControlSequence:
6669 MesPrint(
"@Illegal control sequence in format string in #write instruction");
6671 AM.FileOnlyFlag = h->oldlogonly;
6672 AC.LogHandle = h->oldhandle;
6673 AO.PrintType = h->oldprinttype;
6674 AM.silent = h->oldsilent;
6687 if(wtype==EXTERNALCHANNELOUT){
6689 WriteUnfinString(wtype,Out,num);
6692 WriteString(wtype,Out,num);
6696 AM.FileOnlyFlag = h->oldlogonly;
6697 AC.LogHandle = h->oldhandle;
6698 AO.PrintType = h->oldprinttype;
6699 AM.silent = h->oldsilent;
6711int DoFactDollar(UBYTE *s)
6714 WORD numdollar, *oldworkpointer;
6716 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6717 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6718 while ( *s ==
' ' || *s ==
'\t' ) s++;
6720 if ( GetName(AC.dollarnames,s+1,&numdollar,NOAUTO) != CDOLLAR ) {
6721 MesPrint(
"@%s is undefined",s);
6726 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6730 oldworkpointer = AT.WorkPointer;
6731 if ( DollarFactorize(BHEAD numdollar) )
return(-1);
6732 AT.WorkPointer = oldworkpointer;
6736 else if ( ParenthesesTest(s) )
return(-1);
6738 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6748WORD GetDollarNumber(UBYTE **inp,
DOLLARS d)
6750 UBYTE *s = *inp, c, *name;
6751 WORD number, nfac, *w;
6756 while ( FG.cTable[*s] < 2 ) s++;
6758 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6759 MesPrint(
"@dollar in #write should have been defined previously");
6763 dd = Dollars + number;
6766 nfac = GetDollarNumber(inp,dd);
6769 MesPrint(
"@Illegal factor for dollar variable");
6774 if ( dd->nfactors > d->nfactors ) {
6776 MesPrint(
"@Factor number for dollar variable too large");
6779 return(dd->nfactors);
6781 w = dd->factors[nfac-1].where;
6783 if ( dd->factors[nfac-1].value > d->nfactors ||
6784 dd->factors[nfac-1].value < 0 )
goto TooBig;
6785 return(dd->factors[nfac-1].value);
6787 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6788 && w[1] <= d->nfactors )
return(w[1]);
6789 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6791 MesPrint(
"@Illegal factor number for dollar variable");
6795 if ( dd->type == DOLZERO ) {
6798 else if ( dd->type == DOLTERMS || dd->type == DOLNUMBER ) {
6800 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6801 && w[1] <= d->nfactors )
return(w[1]);
6802 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6808 else if ( FG.cTable[*s] == 1 ) {
6809 WORD x = *s++ -
'0';
6810 while ( FG.cTable[*s] == 1 ) {
6811 x = 10*x + *s++ -
'0';
6812 if ( x > d->nfactors ) {
6813 MesPrint(
"@Factor number %d for dollar variable too large",x);
6818 MesPrint(
"@Illegal factor number for dollar variable");
6825 MesPrint(
"@Illegal factor indicator for dollar variable");
6838int DoSetRandom(UBYTE *s)
6841 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6842 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6843 while ( *s ==
' ' || *s ==
'\t' ) s++;
6845 while ( FG.cTable[*s] == 1 ) {
6846 x = 10*x + (*s++-
'0');
6848 while ( *s ==
' ' || *s ==
'\t' ) s++;
6852 int id, totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
6854 int id, totnum = AM.totalnumberofthreads;
6856 for (
id = 0;
id < totnum;
id++ ) {
6857 AB[id]->R.wranfseed = x;
6858 if ( AB[
id]->R.wranfia ) M_free(AB[
id]->R.wranfia,
"wranf");
6859 AB[id]->R.wranfia = 0;
6863 if ( AR.wranfia ) M_free(AR.wranfia,
"wranf");
6869 MesPrint(
"@proper syntax is #SetRandom number");
6881int DoOptimize(UBYTE *s)
6887 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6888 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6891 if ( *s != 0 && *s !=
';' ) {
6892 MesPrint(
"@proper syntax is #Optimize,expression");
6896 if ( GetName(AC.exprnames,exprname,&numexpr,NOAUTO) != CEXPRESSION ) {
6897 MesPrint(
"@%s is not an expression",exprname);
6900 else if ( AP.preError == 0 ) {
6904 WORD *term = AT.WorkPointer;
6906 if ( AO.OptimizationLevel == 0 )
return(0);
6907 switch ( e->status ) {
6908 case LOCALEXPRESSION:
6909 case GLOBALEXPRESSION:
6912 MesPrint(
"@Expression %s is not an active unhidden local or global expression.",exprname);
6917 if ( PF.me == MASTER )
6920 for ( i = NumExpressions-1; i >= 0; i-- ) {
6921 AS.OldOnFile[i] = Expressions[i].onfile;
6922 AS.OldNumFactors[i] = Expressions[i].numfactors;
6923 AS.Oldvflags[i] = Expressions[i].vflags;
6924 Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
6926 for ( i = 0; i < NumExpressions; i++ ) {
6927 if ( i == numexpr ) {
6929 GetPreVar((UBYTE *)
"EXTRASYMBOLS_",0),0,1);
6931 AO.OptimizeResult.nameofexpr = strDup1(exprname,
"optimize expression name");
6935 if ( PF.me == MASTER ) {
6937 e = Expressions + i;
6938 switch ( e->status ) {
6939 case LOCALEXPRESSION:
6940 case SKIPLEXPRESSION:
6941 case DROPLEXPRESSION:
6942 case DROPPEDEXPRESSION:
6943 case GLOBALEXPRESSION:
6944 case SKIPGEXPRESSION:
6945 case DROPGEXPRESSION:
6946 case HIDELEXPRESSION:
6947 case HIDEGEXPRESSION:
6948 case DROPHLEXPRESSION:
6949 case DROPHGEXPRESSION:
6950 case INTOHIDELEXPRESSION:
6951 case INTOHIDEGEXPRESSION:
6957 SetScratch(AR.infile,&(e->onfile));
6958 if ( GetTerm(BHEAD term) <= 0 ) {
6959 MesPrint(
"@Expression %d has problems reading from scratchfile",i);
6964 SeekScratch(AR.outfile,&position);
6965 e->onfile = position;
6966 *AM.S0->sBuffer = 0; firstterm = -1;
6968 WORD *oldipointer = AR.CompressPointer;
6969 WORD *comprtop = AR.ComprTop;
6970 AR.ComprTop = AM.S0->sTop;
6971 AR.CompressPointer = AM.S0->sBuffer;
6972 if ( firstterm > 0 ) {
6973 if (
PutOut(BHEAD term,&position,AR.outfile,1) < 0 )
goto DoSerr;
6975 else if ( firstterm < 0 ) {
6976 if (
PutOut(BHEAD term,&position,AR.outfile,0) < 0 )
goto DoSerr;
6980 if (
PutOut(BHEAD term,&position,AR.outfile,-1) < 0 )
goto DoSerr;
6983 AR.CompressPointer = oldipointer;
6984 AR.ComprTop = comprtop;
6985 }
while ( GetTerm(BHEAD term) );
6986 if (
FlushOut(&position,AR.outfile,1) ) {
6988 MesPrint(
"@Expression %d has problems writing to scratchfile",i);
7014int DoClearOptimize(UBYTE *s)
7016 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7017 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7034int DoSkipExtraSymbols(UBYTE *s)
7036 CBUF *C = cbuf + AM.sbufnum;
7037 WORD tt = 0, j = 0, oldval = AO.OptimizeResult.minvar;
7038 if ( AO.OptimizeResult.code == NULL )
return(0);
7039 if ( AO.OptimizationLevel == 0 )
return(0);
7040 while ( *s ==
',' ) s++;
7042 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
7045 while ( *s <=
'9' && *s >=
'0' ) j = 10*j + *s++ -
'0';
7047 MesPrint(
"@Illegal use of #SkipExtraSymbols instruction");
7050 AO.OptimizeResult.minvar += j;
7051 if ( AO.OptimizeResult.minvar > AO.OptimizeResult.maxvar )
7052 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
7054 j = AO.OptimizeResult.minvar - oldval;
7059 InsTree(AM.sbufnum,C->numrhs);
7073int DoPreReset(UBYTE *s)
7076 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7077 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7078 while ( *s ==
' ' || *s ==
'\t' ) s++;
7080 MesPrint(
"@proper syntax is #Reset variable");
7084 while ( FG.cTable[*s] == 0 ) s++;
7086 if ( ( StrICmp(ss,(UBYTE *)
"timer") == 0 )
7087 || ( StrICmp(ss,(UBYTE *)
"stopwatch") == 0 ) ) {
7089 AP.StopWatchZero = GetRunningTime();
7094 MesPrint(
"@proper syntax is #Reset variable");
7104static int DoAddPath(UBYTE *s,
int bPrepend)
7108 UBYTE *path, *path_end, *current_dir, *current_dir_end, *NewPath, *t;
7111 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7112 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7115 while ( *s ==
' ' || *s ==
'\t' ) s++;
7118 while ( *s && *s !=
'"' ) {
7119 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
7120 if ( !s[1] )
goto ImproperPath;
7125 if ( *s !=
'"' )
goto ImproperPath;
7130 while ( *s && *s !=
' ' && *s !=
'\t' ) {
7131 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
7132 if ( !s[1] )
goto ImproperPath;
7139 if ( path == path_end )
goto ImproperPath;
7140 while ( *s ==
' ' || *s ==
'\t' ) s++;
7141 if ( *s )
goto ImproperPath;
7145 if ( path[0] == SEPARATOR ) {
7149 else if ( chartype[path[0]] == 0 && path[1] ==
':' ) {
7156 if ( !AC.CurrentStream )
goto FileNameUnavailable;
7157 if ( AC.CurrentStream->type != FILESTREAM && AC.CurrentStream->type != REVERSEFILESTREAM )
goto FileNameUnavailable;
7158 if ( !AC.CurrentStream->name )
goto FileNameUnavailable;
7159 s = current_dir = current_dir_end = AC.CurrentStream->name;
7161 if ( SEPARATOR !=
'\\' && *s ==
'\\' && s[1] ) {
7165 if ( *s == SEPARATOR ) {
7166 current_dir_end = s;
7172 current_dir = current_dir_end = NULL;
7176 n = path_end - path;
7177 if ( AM.Path ) n += StrLen(AM.Path) + 1;
7178 if ( current_dir != current_dir_end ) n+= current_dir_end - current_dir + 1;
7179 s = NewPath = (UBYTE *)Malloc1(n + 1,
"add path");
7183 if ( current_dir != current_dir_end ) {
7185 while ( t != current_dir_end ) *s++ = *t++;
7189 while ( t != path_end ) *s++ = *t++;
7190 if ( AM.Path ) *s++ = PATHSEPARATOR;
7194 while ( *t ) *s++ = *t++;
7197 if ( AM.Path ) *s++ = PATHSEPARATOR;
7198 if ( current_dir != current_dir_end ) {
7200 while ( t != current_dir_end ) *s++ = *t++;
7204 while ( t != path_end ) *s++ = *t++;
7209 if ( AM.Path ) M_free(AM.Path,
"add path");
7215 MesPrint(
"@Improper syntax for %#%sPath", bPrepend ?
"Prepend" :
"Append");
7220 MesPrint(
"@Sorry, %#%sPath can't resolve the current file name from here", bPrepend ?
"Prepend" :
"Append");
7233 return DoAddPath(s, 0);
7250 return DoAddPath(s, 1);
7260int DoTimeOutAfter(UBYTE *s)
7267 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7268 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7270 while ( *s ==
' ' || *s ==
'\t' ) s++;
7272 while ( FG.cTable[*s] == 1 ) {
7273 x = 10*x + (*s++-
'0');
7275 while ( *s ==
' ' || *s ==
'\t' ) s++;
7281 MesPrint(
"@proper syntax is #TimeoutAfter number");
7285 Error0(
"#timeoutafter not implemented on this computer/system");
7312int DoNamespace(UBYTE *s)
7316 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7317 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7318 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7319 if ( FG.cTable[*s] != 0 ) {
7320 MesPrint(
"@Illegal name in #namespace instruction: %s",s);
7324 while ( FG.cTable[*s1] <= 1 ) s1++;
7326 while ( *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' ) s2++;
7328 MesPrint(
"@A #namespace instruction can only have one name with only alphanumeric characters.");
7337 namespace->name = strDup1(s,
"namespace_name");
7338 namespace->usenames = MakeNameTree();
7339 if ( AP.firstnamespace == 0 ) {
7340 namespace->previous = 0;
7341 namespace->next = 0;
7342 AP.firstnamespace =
namespace;
7343 AP.lastnamespace =
namespace;
7346 AP.lastnamespace->next =
namespace;
7347 namespace->next = 0;
7348 namespace->previous = AP.lastnamespace;
7349 AP.lastnamespace =
namespace;
7360int DoEndNamespace(UBYTE *s)
7363 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7364 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7365 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7367 MesPrint(
"@Illegal #endnamespace instruction");
7370 namespace = AP.lastnamespace;
7371 AP.lastnamespace =
namespace->previous;
7372 M_free(namespace->name,
"namespace_name");
7373 FreeNameTree(namespace->usenames);
7374 M_free(
namespace,
"namespace");
7383UBYTE *SkipName(UBYTE *s)
7385 UBYTE *t = s, *s1, c;
7386 int num = 0, block = 0;
7391 MesPrint(
"&Illegal name: '%s'",t);
7395 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) s++;
7396 if ( s1 != s )
goto witherror;
7398 else if ( *s ==
'$' ) {
7400 while ( *s ==
'_' ) { s++; num++; }
7402 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7403 if ( FG.cTable[*s] != 0 && block == 1 ) {
7405 MesPrint(
"&Illegally formed name: %s",t);
7408 if ( *s ==
'_' ) { num++; block = 1; }
7412 if ( s[-1] ==
'_' && num > 1 )
goto built;
7414 else if ( FG.cTable[*s] == 0 ) {
7416 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7417 if ( FG.cTable[*s] != 0 && block == 1 )
goto blocked;
7418 if ( *s ==
'_' ) { block = 1; num++; }
7422 if ( *s ==
'[' )
goto straight;
7423 if ( s[-1] ==
'_' && num > 1 ) {
7426 MesPrint(
"&Built in objects cannot be part of namespaces: %s",t);
7431 else if ( *s ==
'_' ) {
7432 while ( *s ==
'_' ) { s++; num++; }
7433 if ( FG.cTable[*s] == 0 ) { block = 0;
goto regular; }
7436 else if ( *s ==
'@' ) {
7438 if ( *s ==
'_' || FG.cTable[*s] == 1 ) {
7439 MesPrint(
"@Illegally formed name: %s",s-1);
7443 else if ( *s ==
'#' ) {
7445 while ( *s ==
'_' ) { s++; num++; }
7447 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7448 if ( FG.cTable[*s] != 0 && block == 1 )
goto blocked;
7449 if ( *s ==
'_' ) { num++; block = 1; }
7453 if ( s[-1] ==
'_' ) {
7456 MesPrint(
"&Illegally formed name: %s",t);
7461 else if ( *s ==
'<' ) {
7463 while ( *s && *s !=
'>' ) s++;
7464 if ( *s !=
'>' )
goto witherror;
7483UBYTE *ConstructName(UBYTE *s,UBYTE type)
7489 if ( AP.lastnamespace == 0 )
return(s);
7490 if ( *s ==
'@' )
return(s+1);
7491 if ( GetName(AP.lastnamespace->usenames,s,&number,NOAUTO) !=
7492 NAMENOTFOUND )
return(s);
7497 len = StrLen(s) + 1;
7498 namespace = AP.firstnamespace;
7499 while (
namespace ) {
7500 len += StrLen(namespace->name)+1;
7501 namespace = namespace->previous;
7503 if ( len > AP.fullnamesize ) {
7504 while ( len > AP.fullnamesize ) AP.fullnamesize *= 2;
7505 M_free(AP.fullname,
"AP.fullname");
7506 AP.fullname = (UBYTE *)Malloc1(AP.fullnamesize*
sizeof(UBYTE *),
"AP.fullname");
7508 namespace = AP.firstnamespace;
7513 while (
namespace ) {
7514 u =
namespace->name;
7515 while ( *u ) *t++ = *u++;
7517 namespace = namespace->previous;
7519 while ( *s ) *t++ = *s++;
7525 while (
namespace ) {
7526 u =
namespace->name;
7527 while ( *u ) *t++ = *u++;
7529 namespace = namespace->previous;
7531 if ( type ==
'$' ) s++;
7532 while ( *s ) *t++ = *s++;
7536 while (
namespace ) {
7537 u =
namespace->name;
7538 while ( *u ) *t++ = *u++;
7540 namespace = namespace->previous;
7543 while ( *s ) *t++ = *s++;
7548 MesPrint(
"&Unrecognized datatype in ConstructName");
7552 return(AP.fullname);
7580 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7581 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7582 if ( AP.lastnamespace == 0 ) {
7583 MesPrint(
"@It is not allowed to use #use outside the scope of a namespace.");
7586 namespace = AP.lastnamespace;
7587 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7590 if ( ( s = SkipName(t) ) == 0 )
return(-1);
7592 MesPrint(
"@Unrecognized object in #use instruction: %s",t);
7600 AddName(namespace->usenames,t,0,0,&number);
7602 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7623int UserFlags(UBYTE *s,
int par)
7625 int mask = 0, error = 0, i;
7626 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7627 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7628 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7631 for ( i = 0; i < NumExpressions; i++ ) {
7632 switch ( Expressions[i].status ) {
7633 case UNHIDELEXPRESSION:
7634 case UNHIDEGEXPRESSION:
7635 case INTOHIDELEXPRESSION:
7636 case INTOHIDEGEXPRESSION:
7637 case LOCALEXPRESSION:
7638 case GLOBALEXPRESSION:
7639 case SKIPLEXPRESSION:
7640 case SKIPGEXPRESSION:
7641 case HIDELEXPRESSION:
7642 case HIDEGEXPRESSION:
7643 if ( par == 1 ) Expressions[i].uflags |= ~mask;
7644 else Expressions[i].uflags &= mask;
7646 case DROPPEDEXPRESSION:
7647 case DROPLEXPRESSION:
7648 case DROPGEXPRESSION:
7649 case DROPHLEXPRESSION:
7650 case DROPHGEXPRESSION:
7651 case STOREDEXPRESSION:
7652 case HIDDENLEXPRESSION:
7653 case HIDDENGEXPRESSION:
7654 case SPECTATOREXPRESSION:
7660 else if ( FG.cTable[*s] == 1 ) {
7661 mask = (int)WORDMASK;
7662 while ( FG.cTable[*s] == 1 ) {
7664 while ( FG.cTable[*s] == 1 ) { x = 10*x + (*s++-
'0'); }
7665 if ( x < 1 || x > BITSINWORD ) {
7666 MesPrint(
"@Illegal number %d for flag in #...Flag instruction",x);
7670 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7672 if ( *s == 0 )
goto allexpr;
7675 mask = (int)WORDMASK;
7680 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
7683 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
7684 MesPrint(
"@%s is not an active expression",s1);
7688 switch ( Expressions[num1].status ) {
7689 case UNHIDELEXPRESSION:
7690 case UNHIDEGEXPRESSION:
7691 case INTOHIDELEXPRESSION:
7692 case INTOHIDEGEXPRESSION:
7693 case LOCALEXPRESSION:
7694 case GLOBALEXPRESSION:
7695 case SKIPLEXPRESSION:
7696 case SKIPGEXPRESSION:
7697 case HIDELEXPRESSION:
7698 case HIDEGEXPRESSION:
7699 if ( par == 1 ) Expressions[num1].uflags |= ~mask;
7700 else Expressions[num1].uflags &= mask;
7702 case DROPPEDEXPRESSION:
7703 case DROPLEXPRESSION:
7704 case DROPGEXPRESSION:
7705 case DROPHLEXPRESSION:
7706 case DROPHGEXPRESSION:
7707 case STOREDEXPRESSION:
7708 case HIDDENLEXPRESSION:
7709 case HIDDENGEXPRESSION:
7710 case SPECTATOREXPRESSION:
7712 MesPrint(
"@%s is not an active expression",s1);
7717 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7721 MesPrint(
"@Illegal name in #...Flag instruction.");
7730int DoClearUserFlag(UBYTE *s)
7732 return(UserFlags(s,0));
7740int DoSetUserFlag(UBYTE *s)
7742 return(UserFlags(s,1));
7756int DoStartFloat(UBYTE *s)
7762 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7763 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7764 if ( AR.PolyFun != 0 ) {
7765 MesPrint(
"@Simultaneous use of Poly(Rat)Fun and float_ is not allowed.");
7768 if ( AC.ncmod != 0 ) {
7769 MesPrint(
"@Simultaneous use of floating point and modulus arithmetic makes no sense.");
7776 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7781 if ( *s >=
'0' && *s <=
'9' ) {
7784 x = 10*x + (*s++-
'0');
7785 }
while ( *s >=
'0' && *s <=
'9' );
7790 if ( tolower(*s) ==
'd' ) { AC.tDefaultPrecision = (LONG)ceil(x*log2(10.0)); s++; }
7791 else if ( tolower(*s) ==
'b' ) { AC.tDefaultPrecision = x; s++; }
7793 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7798 if ( tolower(*s) ==
'm' && tolower(s[1]) ==
'z' && tolower(s[2]) ==
'v') {
7800 while ( *s ==
' ' || *s ==
'\t' ) s++;
7801 if ( *s !=
'=')
goto IllPar;
7803 while ( *s ==
' ' || *s ==
'\t' ) s++;
7804 if ( *s >=
'0' && *s <=
'9' ) {
7807 x = 10*x + (*s++ -
'0');
7808 }
while ( *s >=
'0' && *s <=
'9' );
7810 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7817 if ( *s )
goto IllPar;
7819 else if ( *s != 0 ) {
7821 MesPrint(
"@Illegal parameter in %#StartFloat: %s ",ss);
7825 if ( AC.tDefaultPrecision && ( AC.tDefaultPrecision != AC.DefaultPrecision
7826 || AT.aux_ == 0 ) ) {
7827 AC.DefaultPrecision = AC.tDefaultPrecision;
7828 AC.tDefaultPrecision = 0;
7830 if ( AC.tMaxWeight && ( AC.tMaxWeight != AC.MaxWeight
7831 || AT.aux_ == 0 ) ) {
7832 AC.MaxWeight = AC.tMaxWeight;
7835 SetFloatPrecision(AC.DefaultPrecision+AC.MaxWeight+1);
7837 if ( AC.MaxWeight > 0 ) SetupMZVTables();
7838 SetfFloatPrecision(AC.DefaultPrecision);
7841 AC.tDefaultPrecision = 0;
7854int DoEndFloat(UBYTE *s)
7857 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7858 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7859 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7861 MesPrint(
"@Illegal parameter in %#EndFloat instruction: %s ",s);
void DoCheckpoint(int moduletype)
int DoRecovery(int *moduletype)
UBYTE * SkipAName(UBYTE *s)
int GetFirstTerm(WORD *, int, int)
void optimize_print_code(int)
void AddPotModdollar(WORD)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
UBYTE * EndOfToken(UBYTE *)
int FlushOut(POSITION *, FILEHANDLE *, int)
int PF_BroadcastRedefinedPreVars(void)
int PF_BroadcastModifiedDollars(void)
int DoContinueDo(UBYTE *s)
int TheDefine(UBYTE *s, int mode)
int PutPreVar(UBYTE *name, UBYTE *value, UBYTE *args, int mode)
int DoPreAppendPath(UBYTE *s)
int DoPrePrependPath(UBYTE *s)
#define VectorReserve(X, newcapacity)