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 ==
':' ) {
1220 AP.FoundFileSetupCount--;
1221 if ( AP.FoundFileSetupCount < 0 ) {
1225 MesPrint(
"Warning: ignoring out-of-place setup command:");
1226 MesPrint(
"@%#%s", t);
1231 key = FindKeyWord(t,precommands,
sizeof(precommands)/
sizeof(
KEYWORD));
1239 MesPrint(
"@Unrecognized preprocessor instruction: %s",t);
1243 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
1246 while ( ( t[-1] ==
';' ) && ( t[-2] !=
'\\' ) ) {
1249 return((key->func)(s));
1269int LoadInstruction(
int mode)
1271 UBYTE *s, *sstart, *t, c, cp;
1272 LONG position, fillpos = 0;
1273 int bralevel = 0, parlevel = 0, first = 1;
1278 if ( s[1] != LINEFEED && s[1] != ENDOFINPUT ) {
1281 else { oldmode = mode;
return(0); }
1283 else { s = AP.preStart; }
1286 if ( ( mode & 1 ) == 1 ) {
1287 if ( pushbackchar && ( mode == 3 || mode == 5 ) ) {
1288 c = pushbackchar; pushbackchar = 0;
1290 else c = GetInput();
1296 if ( mode == 2 && c ==
';' )
break;
1297 if ( ( mode == 1 || mode == 5 ) && c == LINEFEED )
break;
1298 if ( mode == 3 && FG.cTable[c] != 0 ) {
1301 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1302 *s++ =
'g'; *s++ =
'n'; *s++ =
' '; *s = 0;
1304 if ( c ==
'\'' || c ==
'`' ) {
1308 AP.preFill = s; *s++ = 0; *s = c;
1313 if ( mode == 0 && first ) {
1315dodollar: s = sstart;
1316 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1317 *s++ =
'g'; *s++ =
'n'; *s = 0;
1322 if ( c ==
' ' || c ==
'\t' || c ==
',' ) {}
1325 else if ( mode == 1 && first && c ==
'$' && oldmode == 3 )
goto dodollar;
1326 if ( c == ENDOFINPUT || ( c == LINEFEED
1328 && quotelevel == 0 ) ) {
1329 if ( mode == 2 && c == ENDOFINPUT ) {
1330 MesPrint(
"@Unexpected end of instruction");
1341 if ( mode != 2 )
break;
1345 if ( ( mode == 1 ) || ( mode == 5 ) ) c = GetInput();
1349 if ( c == ENDOFINPUT ) {
1350 MesPrint(
"@Unmatched \"");
1351 if ( mode == 2 && c == ENDOFINPUT ) {
1352 MesPrint(
"@Unexpected end of instruction");
1362 else if ( c == LINEFEED ) {}
1363 else if ( c ==
'"' ) { *s++ =
'\\'; }
1368 else if ( c ==
'"' ) {
1373 else if ( c ==
'\\' ) {
1374 if ( ( mode == 1 ) || ( mode == 5 ) ) cp = GetInput();
1378 if ( cp == LINEFEED )
continue;
1379 if ( mode != 2 || cp !=
';' ) *s++ = c;
1382 else if ( c ==
'"' ) {
1388 while ( FG.cTable[*t] <= 1 ) t++;
1390 if ( ( StrICmp(AP.preStart,(UBYTE *)
"define") == 0 )
1391 || ( StrICmp(AP.preStart,(UBYTE *)
"redefine") == 0 ) ) {
1393 oldstream = AC.CurrentStream;
1398 else if ( quotelevel == 0 && bralevel == 0 && c ==
'(' ) {
1400 while ( FG.cTable[*t] <= 1 ) t++;
1402 if ( ( parlevel == 0 )
1403 && ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 ) ) {
1405 oldstream = AC.CurrentStream;
1410 else if ( quotelevel == 0 && bralevel == 0 && c ==
')' ) {
1413 else if ( quotelevel == 0 && parlevel == 0 && c ==
'{' ) {
1415 while ( FG.cTable[*t] <= 1 ) t++;
1417 if ( ( bralevel == 0 )
1418 && ( ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 )
1419 || ( StrICmp(AP.preStart,(UBYTE *)
"do") == 0 ) ) ) {
1421 oldstream = AC.CurrentStream;
1426 else if ( quotelevel == 0 && parlevel == 0 && c ==
'}' ) {
1428 if ( bralevel < 0 ) {
1430 MesPrint(
"@Unmatched brackets");
1437 if ( s >= (AP.preStop-1) ) {
1439 position = s - AP.preStart;
1440 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1441 ppp = &(AP.preStart);
1442 if ( DoubleLList((
void ***)ppp,&AP.pSize,
sizeof(UBYTE),
1443 "instruction buffer") ) { *s = 0; oldmode = mode;
return(-1); }
1444 AP.preStop = AP.preStart + AP.pSize-3;
1445 s = AP.preStart + position;
1446 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1453 if ( ExpandTripleDots(1) < 0 )
return(-1);
1472int LoadStatement(
int type)
1475 int retval = 0, stringlevel = 0, newstatement = 0;
1476 if ( type == NEWSTATEMENT ) { AP.eat = 1; newstatement = 1;
1477 s = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; }
1478 else { s = AC.iPointer; *s = 0; c =
' ';
goto blank; }
1482 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1483 if ( stringlevel == 0 ) {
1484 if ( c == LINEFEED ) {
1485 if ( AP.eat < 0 ) { s--; AP.eat = 0; }
1489 if ( AP.eat < 0 ) { s--; AP.eat = 0; }
1490 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1491 if ( c != LINEFEED ) UngetChar(c);
1498 if ( cp == LINEFEED )
continue;
1503 if ( stringlevel == 0 ) stringlevel = 1;
1504 else stringlevel = 0;
1507 else if ( stringlevel == 0 ) {
1508 if ( c ==
'\t' ) c =
' ';
1510blank:
if ( newstatement < 0 ) newstatement = 0;
1511 if ( AP.eat && ( newstatement == 0 ) )
continue;
1514 if ( newstatement > 0 ) newstatement = -1;
1516 else if ( chartype[c] <= 3 ) {
1518 if ( newstatement < 0 ) newstatement = 0;
1520 else if ( c ==
',' ) {
1521 if ( newstatement > 0 ) {
1526 else if ( AP.eat == -2 ) { AP.eat = 1;
continue; }
1527 else {
goto doall; }
1530doall:;
if ( AP.eat < 0 ) {
1531 if ( newstatement == 0 ) s--;
1532 else { newstatement = 0; }
1534 else if ( newstatement == 1 ) newstatement = 0;
1536 if ( c ==
'*' && s > AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] && s[-1] ==
'*' ) {
1542 if ( s >= AC.iStop ) {
1543 if ( !AP.iBufError ) {
1544 LONG position = s - AC.iBuffer;
1545 LONG position2 = AC.iPointer - AC.iBuffer;
1546 UBYTE **ppp = &(AC.iBuffer);
1547 if ( DoubleLList((
void ***)ppp,&AC.iBufferSize
1548 ,
sizeof(UBYTE),
"statement buffer") ) {
1549 *s = 0; retval = -1; AP.iBufError = 1;
1551 AC.iPointer = AC.iBuffer + position2;
1552 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1553 s = AC.iBuffer + position;
1555 if ( AP.iBufError ) {
1558 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1560 if ( stringlevel > 0 ) stringlevel = 0;
1561 else stringlevel = 1;
1563 else if ( c == LINEFEED && !stringlevel ) { retval = -2;
break; }
1564 else if ( c ==
';' && !stringlevel ) {
1565 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1566 if ( c != LINEFEED ) UngetChar(c);
1570 else if ( c ==
'\\' ) c = GetChar(0);
1579 if ( stringlevel > 0 ) {
1580 MesPrint(
"@Unbalanced \". Runaway string");
1583 if ( retval == 1 ) {
1584 if ( ExpandTripleDots(0) < 0 ) retval = -1;
1594static inline int IsSignChar(UBYTE c)
1596 return c ==
'+' || c ==
'-';
1599static inline int IsAlphanumericChar(UBYTE c)
1601 return FG.cTable[c] == 0 || FG.cTable[c] == 1;
1604static inline int CanParseSignedNumber(
const UBYTE *s)
1606 while ( IsSignChar(*s) ) s++;
1607 return FG.cTable[*s] == 1;
1610int ExpandTripleDots(
int par)
1612 UBYTE *s, *s1, *s2, *n1, *n2, *t1, *t2, *startp, operator1, operator2, c, cc;
1613 UBYTE *nBuffer, *strngs, *Buffer, *Stop;
1614 LONG withquestion, x1, x2, y1, y2, number, inc, newsize, pow, fullsize;
1615 int i, error = 0, i1 ,i2, ii, *nums = 0;
1618 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1621 Buffer = AP.preStart; Stop = AP.preStop;
1623 s = Buffer;
while ( *s ) s++;
1624 fullsize = s - Buffer;
1625 if ( fullsize < 7 )
return(error);
1629 if ( *s !=
'.' || ( s[-1] !=
',' && FG.cTable[s[-1]] != 5 ) )
1631 if ( s[-1] ==
'%' || s[-1] ==
'^' || s[1] !=
'.' || s[2] !=
'.' )
1635 if ( *s != s[-4] && ( *s !=
'+' || s[-4] !=
'-' )
1636 && ( *s !=
'-' || s[-4] !=
'+' ) ) {
1637 MesPrint(
"&Improper operators for ...");
1642 if ( operator1 ==
':' ) operator1 =
'.';
1643 if ( operator2 ==
':' ) operator2 =
'.';
1653 if ( *s2 !=
'<' || *s1 !=
'>' ) {
1655 withquestion = ( *s1 ==
'?' ); s1--;
1656 while ( FG.cTable[*s1] == 1 && s1 >= Buffer ) s1--;
1658 if ( FG.cTable[*n1] != 1 ) {
1659 MesPrint(
"&No first number in ... operator");
1662 while ( FG.cTable[*s1] <= 1 && s1 >= Buffer ) s1--;
1668 while ( t1 < n1 && *t1 == *t2 ) { t1++; t2++; }
1670 if ( FG.cTable[*t2] != 1 ) {
1671 MesPrint(
"&No second number in ... operator");
1675 while ( FG.cTable[*t2] == 1 ) x2 = 10*x2 + *t2++ -
'0';
1677 while ( FG.cTable[*t1] == 1 ) x1 = 10*x1 + *t1++ -
'0';
1678 if ( withquestion != ( *t2 ==
'?' ) ) {
1679 MesPrint(
"&Improper use of ? in ... operator");
1680 if ( *t2 ==
'?' ) t2++;
1683 else if ( withquestion ) t2++;
1684 if ( FG.cTable[*t2] <= 2 ) {
1685 MesPrint(
"&Illegal object after ... construction");
1688 c = *n1; *n1 = 0; s = t2;
1689 if ( error )
continue;
1698 if ( x2 < x1 ) { number = x1-x2; inc = -1; y1 = x2; y2 = x1; }
1699 else { number = x2-x1; inc = 1; y1 = x1; y2 = x2; }
1700 newsize = (number+1)*(n1-s1)
1702 +(number+1)*(withquestion?1:0)
1705 for ( i = 1; i < 10; i++, pow *= 10 ) {
1706 if ( y1 >= pow ) newsize += number+1;
1707 else if ( y2 >= pow ) newsize += y2-pow+1;
1710 while ( Buffer+(fullsize+newsize-(s-s1)) >= Stop ) {
1711 LONG strpos = s1-Buffer;
1712 LONG endstr = n1-Buffer;
1713 LONG startq = startp - Buffer;
1714 LONG position = s - Buffer;
1717 LONG position2 = AC.iPointer - AC.iBuffer;
1718 ppp = &(AC.iBuffer);
1719 if ( DoubleLList((
void ***)ppp,&AC.iBufferSize
1720 ,
sizeof(UBYTE),
"statement buffer") ) {
1723 AC.iPointer = AC.iBuffer + position2;
1724 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1725 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1729 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1730 ppp = &(AP.preStart);
1731 if ( DoubleLList((
void ***)ppp,&AP.pSize,
sizeof(UBYTE),
1732 "instruction buffer") ) {
1735 AP.preStop = AP.preStart + AP.pSize-3;
1736 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1737 Buffer = AP.preStart; Stop = AP.preStop;
1739 s = Buffer + position;
1740 n1 = Buffer + endstr;
1741 s1 = Buffer + strpos;
1742 startp = Buffer + startq;
1750 if ( newsize > (s-s1) ) {
1751 t2 = Buffer + fullsize;
1752 t1 = t2 + (newsize - (s-s1));
1754 while ( t2 > s ) { *--t1 = *--t2; }
1756 else if ( newsize < (s-s1) ) {
1757 t1 = s1 + newsize; t2 = s; s = t1;
1758 while ( *t2 ) *t1++ = *t2++;
1761 for ( x1 += inc, t1 = startp; number > 0; number--, x1 += inc ) {
1763 cc = operator1; operator1 = operator2; operator2 = cc;
1764 t2 = s1;
while ( *t2 ) *t1++ = *t2++;
1767 *t1++ =
'0' + x2 % 10;
1771 while ( s2 > n2 ) { cc = *s2; *s2 = *n2; *n2++ = cc; s2--; }
1772 if ( withquestion ) *t1++ =
'?';
1774 fullsize += newsize - ( s - s1 );
1779 while ( s1 > Buffer ) {
1780 if ( *s1 ==
'<' )
break;
1785 if ( *t2 ==
'>' )
break;
1788 if ( *s1 !=
'<' || *t2 !=
'>' ) {
1789 MesPrint(
"&Illegal attempt to use ... operator");
1793 nums = (
int *)Malloc1((t1-s1)*2*(
sizeof(int)+
sizeof(UBYTE))
1795 strngs = (UBYTE *)(nums + 2*(t1-s1));
1796 n1 = s1; n2 = s2; ii = -1; i = 0;
1798 while ( n1 < t1 || n2 < t2 ) {
1800 if ( CanParseSignedNumber(n1) && CanParseSignedNumber(n2) ) {
1809 int sign1 = IsSignChar(*n1);
1810 int sign2 = IsSignChar(*n2);
1811 int inword1 = s1 < n1 && IsAlphanumericChar(n1[-1]);
1812 int inword2 = s2 < n2 && IsAlphanumericChar(n2[-1]);
1813 if ( ( sign1 ^ sign2 ) && ( inword1 || inword2 ) )
break;
1814 if ( sign1 || sign2 ) {
1819 if ( *n1 == *n2 ) { *s++ = *n1++; n2++;
continue; }
1822 ParseSignedNumber(x1,n1)
1823 ParseSignedNumber(x2,n2)
1825 if ( s != strngs && ( s[-1] ==
'+' || s[-1] ==
'-' ) ) {
1835 nums[2*i] = x1; nums[2*i+1] = x2;
1839 if ( n1 < t1 || n2 < t2 ) {
1840 MesPrint(
"&Improper use of ... operator.");
1841theend: M_free(nums,
"Expand ...");
1845 if ( i == 0 ) ii = 0;
1847 ii = nums[0] - nums[1];
1848 if ( ii < 0 ) ii = -ii;
1849 for ( x1 = 1; x1 < i; x1++ ) {
1850 x2 = nums[2*x1]-nums[2*x1+1];
1851 if ( x2 < 0 ) x2 = -x2;
1853 MesPrint(
"&Improper synchronization of numbers in ... operator");
1868 x2 = s - strngs - i;
1869 for ( i1 = 0; i1 < i; i1++ ) {
1872 if ( i2 < 0 ) i2 = -i2;
1873 if ( x1 < 0 ) x1 = -x1;
1874 if ( x1 > i2 ) i2 = x1;
1876 while ( i2 > 0 ) { i2 /= 10; x1++; }
1882 x2 +=
sizeof(UBYTE *);
1883 x2 = x2 - (x2 & (
sizeof(UBYTE *)-1));
1885 nBuffer = (UBYTE *)Malloc1(x2,
"input buffer");
1886 n1 = nBuffer; s = Buffer; s1--;
1887 while ( s < s1 ) *n1++ = *s++;
1895 if ( ( ( n1 > nBuffer ) && ( ( FG.cTable[n1[-1]] <= 1 )
1896 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1897 ( ( FG.cTable[strngs[0]] <= 1 ) || ( strngs[0] ==
'[' )
1898 || ( strngs[0] ==
'_' ) ) ) *n1++ =
',';
1900 for ( i1 = 0; i1 < ii; i1++ ) {
1901 s = strngs;
while ( *s ) *n1++ = *s++;
1902 for ( i2 = 0; i2 < i; i2++ ) {
1903 if ( n1 > nBuffer && IsSignChar(n1[-1]) ) {
1906 if ( nums[2*i2] >= 0 ) {
1910 n1 = NumCopy((WORD)(nums[2*i2]),n1);
1911 if ( nums[2*i2] > nums[2*i2+1] ) nums[2*i2]--;
1913 s++;
while ( *s ) *n1++ = *s++;
1915 if ( ( i1 & 1 ) == 0 ) *n1++ = operator1;
1916 else *n1++ = operator2;
1919 s = t2 + 1; n2 = n1;
1923 if ( ( ( ( FG.cTable[n1[-1]] <= 1 )
1924 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1925 ( ( FG.cTable[s[0]] <= 1 ) || ( s[0] ==
'[' )
1926 || ( s[0] ==
'_' ) ) ) *n1++ =
',';
1928 while ( *s ) *n1++ = *s++;
1931 LONG nnn1 = n1-nBuffer;
1932 LONG nnn2 = n2-nBuffer;
1934 while ( AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] + x2 >= AC.iStop ) {
1935 LONG position = s-Buffer;
1936 LONG position2 = AC.iPointer - AC.iBuffer;
1938 ppp = &(AC.iBuffer);
1939 if ( DoubleLList((
void ***)ppp,&AC.iBufferSize
1940 ,
sizeof(UBYTE),
"statement buffer") ) {
1943 AC.iPointer = AC.iBuffer + position2;
1944 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1945 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1946 s = Buffer + position;
1951 for ( nnn3 = 0; nnn3 < nnn1; nnn3++ ) Buffer[nnn3] = nBuffer[nnn3];
1955 M_free(nBuffer,
"input buffer");
1956 M_free(nums,
"Expand ...");
1959 AP.preStop = nBuffer + x2 - 2;
1961 M_free(AP.preStart,
"input buffer");
1962 M_free(nums,
"Expand ...");
1963 AP.preStart = nBuffer;
1964 Buffer = AP.preStart; Stop = AP.preStop;
1966 fullsize = n1 - Buffer;
1984 while ( hi >= low ) {
1986 s1 = (UBYTE *)(table[med].name);
1988 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1994 FG.cTable[*s2] != 0 && FG.cTable[*s2] != 1
1998 if ( tolower(*s2) > tolower(*s1) ) low = med+1;
2013 for ( i = 0; i < size; i++ ) {
2014 s1 = (UBYTE *)(table[i].name);
2016 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
2017 if ( *s2 == 0 || *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' )
2041 UBYTE *name, *value, *valpoin, *args = 0, c;
2042 if ( ( mode & 2 ) == 0 ) {
2043 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2044 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2046 else { mode &= ~2; }
2048 if ( chartype[*s] != 0 )
goto illname;
2050 while ( chartype[*s] <= 1 ) s++;
2052 while ( *s ==
' ' || *s ==
'\t' ) s++;
2055 if (
PutPreVar(name,(UBYTE *)
"1",0,mode) < 0 )
return(-1);
2061 if ( chartype[*s] != 0 )
goto illarg;
2063 while ( chartype[*s] <= 1 ) s++;
2064 while ( *s ==
' ' || *s ==
'\t' ) s++;
2065 if ( *s ==
')' )
break;
2066 if ( *s !=
',' )
goto illargs;
2068 while ( *s ==
' ' || *s ==
'\t' ) s++;
2071 while ( *s ==
' ' || *s ==
'\t' ) s++;
2075 s++; valpoin = value = s;
2076 while ( *s !=
'"' ) {
2078 if ( s[1] ==
'n' ) { *valpoin++ = LINEFEED; s += 2; }
2079 else if ( s[1] ==
'"' ) { *valpoin++ =
'"'; s += 2; }
2080 else if ( s[1] == 0 )
goto illval;
2081 else { *valpoin++ = *s++; *valpoin++ = *s++; }
2083 else *valpoin++ = *s++;
2086 if (
PutPreVar(name,value,args,mode) < 0 )
return(-1);
2089 MesPrint(
"@Illegal string for preprocessor variable %s. Forgotten double quotes (\") ?",name);
2094 MesPrint(
"@Illegally formed name of preprocessor variable");
2097 MesPrint(
"@Illegally formed name of argument of preprocessor definition");
2100 MesPrint(
"@Illegally formed arguments of preprocessor definition");
2103 MesPrint(
"@Illegal valpoin for preprocessor variable %s",name);
2112int DoCommentChar(UBYTE *s)
2115 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2116 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2117 while ( *s ==
' ' || *s ==
'\t' ) s++;
2118 if ( *s == 0 || *s ==
'\n' ) {
2119 MesPrint(
"@No valid comment character specified");
2123 while ( *s ==
' ' || *s ==
'\t' ) s++;
2124 if ( *s != 0 && *s !=
'\n' ) {
2125 MesPrint(
"@Comment character should be a single valid character");
2143int DoPreAssign(UBYTE *s)
2146 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
2149 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
2153 MesPrint(
"@Illegal characters in %#assign instruction");
2157 AP.PreAssignFlag = 1;
2174int DoDefine(UBYTE *s)
2184int DoRedefine(UBYTE *s)
2196int ClearMacro(UBYTE *name)
2201 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2202 if ( StrCmp(name,p->name) == 0 )
break;
2204 if ( i < 0 )
return(-1);
2205 if ( p->nargs <= 0 )
return(0);
2207 for ( i = 0; i < p->nargs; i++ ) {
2224int TheUndefine(UBYTE *name)
2226 int i, inum, error = 0;
2228 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2229 if ( StrCmp(name,p->name) == 0 ) {
2230 M_free(p->name,
"undefining PreVar");
2233 while ( i < NumPre ) {
2234 p->name = p[1].name;
2235 p->value = p[1].value;
2238 p->name = 0; p->value = 0;
2240 CBUF *CC = cbuf + AC.cbufnum;
2242 for ( j = 1; j <= CC->numlhs; j++ ) {
2243 if ( CC->
lhs[j][0] == TYPEREDEFPRE ) {
2244 if ( CC->
lhs[j][2] > inum ) CC->
lhs[j][2]--;
2245 else if ( CC->
lhs[j][2] == inum ) {
2246 for ( k = inum - 1; k >= 0; k-- )
2247 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2248 if ( k >= 0 ) CC->
lhs[j][2] = k;
2250 MesPrint(
"@Conflict between undefining a preprocessor variable and a redefine statement");
2257 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2258 if ( AC.pfirstnum[j] > inum ) AC.pfirstnum[j]--;
2259 else if ( AC.pfirstnum[j] == inum ) {
2260 for ( k = inum - 1; k >= 0; k-- )
2261 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2262 if ( k >= 0 ) AC.pfirstnum[j] = k;
2278int DoUndefine(UBYTE *s)
2281 int error = 0, retval;
2286 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2287 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2289 if ( chartype[*s] != 0 )
goto illname;
2291 while ( chartype[*s] <= 1 ) s++;
2293 if ( *s && *s !=
' ' && *s !=
'\t' )
goto illname;
2294 while ( *s ==
' ' || *s ==
'\t' ) s++;
2296 MesPrint(
"@Undefine should just have a variable name");
2300 if ( ( retval = TheUndefine(name) ) != 0 ) {
2301 if ( error == 0 )
return(retval);
2302 if ( error > 0 ) error = retval;
2321 MesPrint(
"@Illegally formed name of preprocessor variable");
2330int DoInclude(UBYTE *s) {
return(Include(s,FILESTREAM)); }
2337int DoReverseInclude(UBYTE *s) {
return(Include(s,REVERSEFILESTREAM)); }
2344int Include(UBYTE *s,
int type)
2346 UBYTE *name = s, *fold, *t, c, c1 = 0, c2 = 0, c3 = 0;
2347 int str1offset, withnolist = AC.NoShowInput;
2348 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2349 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2350 if ( *s ==
'-' || *s ==
'+' ) {
2351 if ( *s ==
'-' ) withnolist = 1;
2352 else withnolist = 0;
2354 while ( *s ==
' ' || *s ==
'\t' ) s++;
2358 while ( *s && *s !=
'"' ) {
2359 if ( *s ==
'\\' ) s++;
2365 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2366 if ( *s ==
'\\' ) s++;
2371 while ( *s ==
' ' || *s ==
'\t' ) s++;
2375 while ( *s ==
' ' || *s ==
'\t' ) s++;
2378 MesPrint(
"@Empty fold name");
2382 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2383 if ( *s ==
'\\' ) s++;
2387 while ( *s ==
' ' || *s ==
'\t' ) s++;
2395 else if ( *s == 0 ) {
2399 MesPrint(
"@Improper syntax for file name");
2404 fold = strDup1(fold,
"foldname");
2409 if ( OpenStream(name,type,0,PRENOACTION) == 0 ) {
2410 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2416 LONG linenum = 0, prevline = 0;
2417 name = strDup1(name,
"name of include file");
2418 AC.CurrentStream->FoldName = strDup1(fold,
"name of fold");
2421 c = GetFromStream(AC.CurrentStream);
2422 if ( c == ENDOFSTREAM ) {
2423 AC.CurrentStream = CloseStream(AC.CurrentStream);
2426 if ( c == AP.ComChar ) {
2427 str1offset = AC.CurrentStream-AC.Streams;
2429 if ( AC.CurrentStream != str1offset+AC.Streams ) {
2434 if ( t[2] ==
'#' && ( ( t[3] ==
'[' && !foldopen )
2435 || ( t[3] ==
']' && foldopen ) ) ) {
2437 while ( *t ==
' ' || *t ==
'\t' ) t++;
2438 s = AC.CurrentStream->FoldName;
2439 while ( *s == *t ) { s++; t++; }
2440 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t'
2442 while ( *t ==
' ' || *t ==
'\t' ) t++;
2444 if ( foldopen == 0 ) {
2446 position = GetStreamPosition(AC.CurrentStream);
2447 linenum = AC.CurrentStream->linenumber;
2448 prevline = AC.CurrentStream->prevline;
2449 c3 = AC.CurrentStream->isnextchar;
2450 c1 = AC.CurrentStream->nextchar[0];
2451 c2 = AC.CurrentStream->nextchar[1];
2455 PositionStream(AC.CurrentStream,position);
2456 AC.CurrentStream->linenumber = linenum;
2457 AC.CurrentStream->prevline = prevline;
2458 AC.CurrentStream->eqnum = 1;
2460 AC.CurrentStream->isnextchar = c3;
2461 AC.CurrentStream->nextchar[0] = c1;
2462 AC.CurrentStream->nextchar[1] = c2;
2471 while ( c != LINEFEED && c != ENDOFSTREAM ) {
2472 c = GetFromStream(AC.CurrentStream);
2473 if ( c == ENDOFSTREAM ) {
2474 AC.CurrentStream = CloseStream(AC.CurrentStream);
2479 if ( c == ENDOFSTREAM ) {
2481 MesPrint(
"@Cannot find fold %s in file %s",fold,name);
2484 M_free(name,
"name of include file");
2488 M_free(name,
"name of include file");
2490 AC.NoShowInput = withnolist;
2491 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2505int DoPreExchange(UBYTE *s)
2510 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2511 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2512 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2514 s++; s1 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2515 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2517 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2518 if ( *s !=
'$' )
goto syntax;
2519 s++; s2 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2520 if ( *s != 0 && *s !=
';' )
goto syntax;
2522 if ( ( num1 = GetDollar(s1) ) <= 0 ) {
2523 MesPrint(
"@$%s has not been defined (yet)",s1);
2526 if ( ( num2 = GetDollar(s2) ) <= 0 ) {
2527 MesPrint(
"@$%s has not been defined (yet)",s2);
2531 ExchangeDollars((
int)num1,(
int)num2);
2536 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2538 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2539 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
2541 if ( *s != 0 && *s !=
';' )
goto syntax;
2543 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
2544 MesPrint(
"@%s is not an expression",s1);
2547 if ( GetName(AC.exprnames,s2,&num2,NOAUTO) != CEXPRESSION ) {
2548 MesPrint(
"@%s is not an expression",s2);
2552 ExchangeExpressions((
int)num1,(
int)num2);
2557 MesPrint(
"@Proper syntax: %#exchange expr1,expr2 or %#exchange $var1,$var2");
2568 UBYTE *t, *u, *v, *name, c, cp, *args1, *args2, *t1, *t2, *wild = 0;
2569 int bratype = 0, wildargs = 0, inwildargs = 0, nwildargs = 0;
2572 int i, namesize, narg1, narg2, bralevel, numpre;
2574 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2575 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2581 for ( i = NumProcedures-1; i >= 0; i-- ) {
2582 if ( StrCmp(Procedures[i].name,name) == 0 )
break;
2585 p = (
PROCEDURE *)FromList(&AP.ProcList);
2589 while ( *t ) { t++; namesize++; }
2590 t = AP.procedureExtension;
2591 while ( *t ) { t++; namesize++; }
2592 t = p->name = (UBYTE *)Malloc1(namesize+2,
"procedure");
2594 while ( *u ) *t++ = *u++;
2596 v = AP.procedureExtension;
2597 while ( *v ) *t++ = *v++;
2601 p->p.buffer = LoadInputFile(p->name,PROCEDUREFILE);
2602 if ( p->p.buffer == 0 )
return(-1);
2606 p->p.buffer = Procedures[i].p.buffer;
2607 p->name = Procedures[i].name;
2613 if ( *t++ !=
'#' )
goto wrongfile;
2619 if ( StrCmp(t,name) != 0 )
goto wrongfile;
2627 bralevel = narg1 = narg2 = 0; args2 = u;
2632 while ( *u !=
')' ) {
2633 if ( *u ==
'?' ) { wildargs++; u++; nwildargs = narg2+1; }
2635 if ( *u ==
',' ) { u++; SKIPBLANKS(u) }
2636 else if ( *u !=
')' || ( wildargs > 1 ) ) {
2637 MesPrint(
"@Illegal argument field in procedure %s",p->name);
2642 while ( *u != LINEFEED ) u++;
2645 if ( *s ==
'(' ) bratype = 1;
2647 if ( *s ==
'{' && bratype == 0 ) bralevel++;
2648 else if ( *s ==
'(' && bratype == 1 ) bralevel++;
2649 else if ( *s ==
'}' && bratype == 0 ) {
2651 if ( bralevel == 0 ) {
2653 if ( wildargs && narg1 == nwildargs ) wild = s;
2656 else if ( *s ==
')' && bratype == 1 ) {
2658 if ( bralevel == 0 ) {
2660 if ( wildargs && narg1 == nwildargs ) wild = s;
2665 else if (set_in(*s,AC.separators)) {
2669 if ( wildargs && narg1 == nwildargs ) wild = s;
2671 else if ( *s ==
'\\' ) s++;
2673 }
while ( bralevel > 0 );
2674 if ( wildargs && narg1 >= narg2-1 ) {
2675 inwildargs = narg1-narg2+1;
2676 if ( inwildargs == 0 ) nwildargs = 0;
2678 while ( inwildargs > 1 ) {
2680 while ( *wild ) wild++;
2685 else if ( narg1 != narg2 && ( narg2 != 0 || narg1 != 1 || *args1 != 0 ) ) {
2686 MesPrint(
"@Arguments of procedure %s are not matching",p->name);
2690 for ( i = 0; i < narg2; i++ ) {
2695 if ( *t ==
'?' && inwildargs == 0 ) {
2696 args2 =
EndOfToken(args2); c = *args2; *args2 = 0;
2697 if (
PutPreVar(t,(UBYTE *)
"",0,0) < 0 )
return(-1);
2700 args2 =
EndOfToken(args2); c = *args2; *args2 = 0;
2703 if ( *t1 ==
'\\' ) t1++;
2704 if ( t1 != t2 ) *t2 = *t1;
2708 if (
PutPreVar(t,args1,0,0) < 0 )
return(-1);
2711 *args2 = c; SKIPBLANKS(args2)
2712 args2++; SKIPBLANKS(args2)
2714 streamoffset = AC.CurrentStream - AC.Streams;
2715 args1 = AC.CurrentStream->name;
2716 AC.CurrentStream->name = p->name;
2717 i1 = AC.CurrentStream->linenumber;
2718 i2 = AC.CurrentStream->prevline;
2719 AC.CurrentStream->prevline =
2720 AC.CurrentStream->linenumber = 2;
2721 OpenStream(u+1,PREREADSTREAM3,numpre,PRENOACTION);
2722 AC.Streams[streamoffset].name = args1;
2723 AC.Streams[streamoffset].linenumber = i1;
2724 AC.Streams[streamoffset].prevline = i2;
2725 AddToPreTypes(PRETYPEPROCEDURE);
2728 if ( i < 0 ) MesPrint(
"@File %s is not a proper procedure",p->name);
2731 MesPrint(
"!>Internal error with procedure names: %s",name);
2742int DoDebug(UBYTE *s)
2745 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2746 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2747 NeedNumber(x,s,nonumber)
2748 if ( x < 0 || x >(PREPROONLY
2759 if ( ( x & PREPROONLY ) != 0 ) AP.PreDebug |= PREPROONLY;
2760 if ( ( x & DUMPTOCOMPILER ) != 0 ) AP.PreDebug |= DUMPTOCOMPILER;
2761 if ( ( x & DUMPOUTTERMS ) != 0 ) AP.PreDebug |= DUMPOUTTERMS;
2762 if ( ( x & DUMPINTERMS ) != 0 ) AP.PreDebug |= DUMPINTERMS;
2763 if ( ( x & DUMPTOSORT ) != 0 ) AP.PreDebug |= DUMPTOSORT;
2764 if ( ( x & DUMPTOPARALLEL ) != 0 ) AP.PreDebug |= DUMPTOPARALLEL;
2766 if ( ( x & THREADSDEBUG ) != 0 ) AP.PreDebug |= THREADSDEBUG;
2770 MesPrint(
"@Illegal argument for debug instruction");
2779int DoTerminate(UBYTE *s)
2782 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2783 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2785 NeedNumber(x,s,nonumber)
2793 MesPrint(
"@Illegal argument for terminate instruction");
2819 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2820 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2822 if ( NumDoLoops <= 0 ) {
2823 MesPrint(
"@%#continuedo without %#do");
2831 else if ( FG.cTable[*s] == 1 ) {
2832 ParseNumber(levels,s);
2834 if ( *s != 0 )
goto improper;
2838 MesPrint(
"@Improper syntax of %#continuedo instruction");
2842 if ( levels > NumDoLoops ) {
2843 MesPrint(
"@Too many loop levels requested in %#continuedo instruction");
2847 result = ExitDoLoops(levels-1,
"continuedo");
2848 if ( result != 0 )
return(result);
2850 if ( levels <= 0 )
return(0);
2852 if ( AC.CurrentStream->type == PREREADSTREAM3
2853 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
2854 MesPrint(
"@Trying to jump out of a procedure with a %#continuedo instruction");
2858 loop = &(DoLoops[NumDoLoops-1]);
2859 AP.NumPreTypes = loop->NumPreTypes+1;
2860 AP.PreIfLevel = loop->PreIfLevel;
2861 AP.PreSwitchLevel = loop->PreSwitchLevel;
2880 UBYTE *t, c, *u, *uu;
2883 LONG linenum = AC.CurrentStream->linenumber;
2884 int oldNoShowInput = AC.NoShowInput, i, oldpreassignflag;
2886 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
2887 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
2888 if ( PreSkip((UBYTE *)
"do",(UBYTE *)
"enddo",1) )
return(-1);
2896 AddToPreTypes(PRETYPEDO);
2898 loop = (
DOLOOP *)FromList(&AP.LoopList);
2899 loop->firstdollar = loop->lastdollar = loop->incdollar = -1;
2900 loop->NumPreTypes = AP.NumPreTypes-1;
2901 loop->PreIfLevel = AP.PreIfLevel;
2902 loop->PreSwitchLevel = AP.PreSwitchLevel;
2904 if ( PreLoad(&(loop->
p),(UBYTE *)
"do",(UBYTE *)
"enddo",1,
"doloop") )
return(-1);
2905 AC.NoShowInput = oldNoShowInput;
2906 loop->NoShowInput = AC.NoShowInput;
2910 s = loop->
p.buffer + (s - AP.preStart);
2913 if ( chartype[*s] != 0 )
goto illname;
2915 while ( chartype[*s] <= 1 ) s++;
2917 while ( *s ==
' ' || *s ==
'\t' ) s++;
2918 if ( *s !=
'=' )
goto illdo;
2920 while ( *s ==
' ' || *s ==
'\t' ) s++;
2924 loop->type = LISTEDLOOP;
2925 s++; loop->vars = s;
2927 while ( *s !=
'}' && *s != 0 ) {
2928 if ( set_in(*s,AC.separators) ) { *s = 0; loop->lastnum++; }
2929 else if ( *s ==
'\\' ) s++;
2932 if ( *s == 0 )
goto illdo;
2938 else if ( *s ==
'-' || *s ==
'+' || chartype[*s] == 1 || *s ==
'$' ) {
2939 loop->type = NUMERICALLOOP;
2941 while ( *s && *s !=
',' ) s++;
2942 if ( *s == 0 )
goto illdo;
2945 if ( GetName(AC.dollarnames,t+1,&loop->firstdollar,NOAUTO) != CDOLLAR ) {
2946 MesPrint(
"@%s is undefined in first parameter in %#do instruction",t);
2949 loop->firstnum = DolToLong(BHEAD loop->firstdollar);
2950 if ( AN.ErrorInDollar ) {
2951 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2958 if ( PreEval(t,&loop->firstnum) == 0 )
goto illdo;
2962 while ( *s && *s !=
',' && *s !=
';' && *s != LINEFEED ) s++;
2966 if ( GetName(AC.dollarnames,t+1,&loop->lastdollar,NOAUTO) != CDOLLAR ) {
2967 MesPrint(
"@%s is undefined in second parameter in %#do instruction",t);
2970 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
2971 if ( AN.ErrorInDollar ) {
2972 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2979 if ( PreEval(t,&loop->lastnum) == 0 )
goto illdo;
2984 while ( *s && *s !=
';' && *s != LINEFEED ) s++;
2987 if ( GetName(AC.dollarnames,t+1,&loop->incdollar,NOAUTO) != CDOLLAR ) {
2988 MesPrint(
"@%s is undefined in third parameter in %#do instruction",t);
2991 loop->incnum = DolToLong(BHEAD loop->incdollar);
2992 if ( AN.ErrorInDollar ) {
2993 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
3000 if ( PreEval(t,&loop->incnum) == 0 )
goto illdo;
3004 else loop->incnum = 1;
3007 else if ( ( chartype[*s] == 0 ) || ( *s ==
'[' ) ) {
3008 int oldNumPotModdollars = NumPotModdollars;
3010 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
3011 AC.RhsExprInModuleFlag = 0;
3014 if ( ( s =
SkipAName(s) ) == 0 )
goto illdo;
3016 if ( GetName(AC.exprnames,t,&expnum,NOAUTO) == CEXPRESSION ) {
3017 loop->type = ONEEXPRESSION;
3026 if ( c ==
',' || c ==
'\t' || c ==
';' ) { s++; }
3027 else if ( c != 0 && c !=
'\n' )
goto illdo;
3028 while ( *s ==
',' || *s ==
'\t' || *s ==
';' ) s++;
3029 if ( *s != 0 && *s !=
'\n' )
goto illdo;
3040 while ( *t ) { t++; i++; }
3042 loop->
dollarname = Malloc1((LONG)i,
"do-loop instruction");
3047 *u++ =
'$'; t = loop->
name;
while ( *t ) *u++ = *t++;
3048 *u++ =
'_'; uu = u; *u++ =
'='; t = loop->vars;
3049 while ( *t ) *u++ = *t++;
3055 oldpreassignflag = AP.PreAssignFlag;
3056 AP.PreAssignFlag = 2;
3058 if ( CatchDollar(0) ) {
3059 MesPrint(
"@Cannot load expression in do loop");
3062 AP.PreAssignFlag = oldpreassignflag;
3063 NumPotModdollars = oldNumPotModdollars;
3065 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
3070 loop->errorsinloop = 0;
3072 loop->startlinenumber = linenum;
3074 loop->firstloopcall = 1;
3077 MesPrint(
"@Improper name for do loop variable");
3080 MesPrint(
"@Improper syntax in do loop instruction");
3092int DoBreakDo(UBYTE *s)
3096 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3097 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3099 if ( NumDoLoops <= 0 ) {
3100 MesPrint(
"@%#breakdo without %#do");
3106 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
3110 else if ( FG.cTable[*s] == 1 ) {
3112 while ( *s >=
'0' && *s <=
'9' ) { levels = 10*levels + *s++ -
'0'; }
3113 if ( *s != 0 )
goto improper;
3117 MesPrint(
"@Improper syntax of %#breakdo instruction");
3120 if ( levels > NumDoLoops ) {
3121 MesPrint(
"@Too many loop levels requested in %#breakdo instruction");
3124 return(ExitDoLoops(levels,
"breakdo"));
3134static int ExitDoLoops(
int levels,
const char *instruction)
3137 while ( levels > 0 ) {
3138 while ( AC.CurrentStream->type != PREREADSTREAM
3139 && AC.CurrentStream->type != PREREADSTREAM2
3140 && AC.CurrentStream->type != PREREADSTREAM3 ) {
3141 AC.CurrentStream = CloseStream(AC.CurrentStream);
3143 while ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO
3144 && AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) AP.NumPreTypes--;
3145 if ( AC.CurrentStream->type == PREREADSTREAM3
3146 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
3147 MesPrint(
"@Trying to jump out of a procedure with a %#%s instruction",instruction);
3150 loop = &(DoLoops[NumDoLoops-1]);
3151 AP.NumPreTypes = loop->NumPreTypes;
3152 AP.PreIfLevel = loop->PreIfLevel;
3153 AP.PreSwitchLevel = loop->PreSwitchLevel;
3155 DoUndefine(loop->
name);
3156 M_free(loop->
p.buffer,
"loop->p.buffer");
3157 loop->firstloopcall = 0;
3159 AC.CurrentStream = CloseStream(AC.CurrentStream);
3172 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3173 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#else without corresponding %#if");
3174 else MessPreNesting(1);
3177 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3178 while ( *s ==
' ' ) s++;
3179 if ( tolower(*s) ==
'i' && tolower(s[1]) ==
'f' && s[2]
3180 && FG.cTable[s[2]] > 1 && s[2] !=
'_' ) {
3182 while ( *s ==
' ' ) s++;
3183 return(DoElseif(s));
3185 if ( AP.PreIfLevel <= 0 ) {
3186 MesPrint(
"@%#else without corresponding %#if");
3189 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3191 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3193 case LOOKINGFORELSE:
3194 AP.PreIfStack[AP.PreIfLevel] = EXECUTINGIF;
3196 case LOOKINGFORENDIF:
3207int DoElseif(UBYTE *s)
3210 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3211 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#elseif without corresponding %#if");
3212 else MessPreNesting(2);
3215 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3216 if ( AP.PreIfLevel <= 0 ) {
3217 MesPrint(
"@%#elseif without corresponding %#if");
3220 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3222 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3224 case LOOKINGFORELSE:
3225 if ( ( condition = EvalPreIf(s) ) < 0 )
return(-1);
3226 AP.PreIfStack[AP.PreIfLevel] = condition;
3228 case LOOKINGFORENDIF:
3242int DoEnddo(UBYTE *s)
3246 UBYTE *t, *tt, *value, numstr[16];
3250 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3251 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3260 if ( NumDoLoops <= 0 ) {
3261 MesPrint(
"@%#enddo without %#do");
3264 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO ) { MessPreNesting(4);
return(-1); }
3265 loop = &(DoLoops[NumDoLoops-1]);
3266 if ( !loop->firstloopcall ) AC.CurrentStream = CloseStream(AC.CurrentStream);
3268 if ( loop->errorsinloop ) {
3269 MesPrint(
"++++Errors in Loop");
3272 if ( loop->type == LISTEDLOOP ) {
3273 if ( loop->firstnum >= loop->lastnum )
goto finish;
3275 t = value = loop->vars;
3276 while ( *value ) value++;
3281 if ( *value ==
'\\' ) value++;
3287 else if ( loop->type == NUMERICALLOOP ) {
3289 if ( !loop->firstloopcall ) {
3298 while ( *value && ( *value ==
' '
3299 || *value ==
'-' || *value ==
'+' ) ) {
3300 if ( *value ==
'-' ) xsign = -xsign;
3303 t = value; xval = 0;
3304 while ( *value >=
'0' && *value <=
'9' ) xval = 10*xval + *value++ -
'0';
3305 while ( *value && *value ==
' ' ) value++;
3306 if ( *value == 0 ) {
3310 if ( xsign < 0 ) xval = -xval;
3311 if ( loop->incdollar >= 0 ) {
3312 loop->incnum = DolToLong(BHEAD loop->incdollar);
3313 if ( AN.ErrorInDollar ) {
3314 MesPrint(
"@%s does not evaluate into a valid third loop parameter",DOLLARNAME(Dollars,loop->incdollar));
3318 loop->firstnum = xval + loop->incnum;
3321 if ( loop->lastdollar >= 0 ) {
3322 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
3323 if ( AN.ErrorInDollar ) {
3324 MesPrint(
"@%s does not evaluate into a valid second loop parameter",DOLLARNAME(Dollars,loop->lastdollar));
3329 if ( ( loop->incnum > 0 && loop->firstnum > loop->lastnum )
3330 || ( loop->incnum < 0 && loop->firstnum < loop->lastnum ) )
goto finish;
3331 NumToStr(numstr,loop->firstnum);
3333 loop->firstnum += loop->incnum;
3336 else if ( loop->type == ONEEXPRESSION ) {
3340 WORD numdollar = GetDollar(loop->dollarname+1);
3341 DOLLARS d = Dollars + numdollar;
3342 WORD *w, *dw, v, *ww;
3343 if ( (d->where) == 0 ) {
3344 d->type = DOLUNDEFINED;
3345 M_free(loop->dollarname,
"do-loop instruction");
3348 w = d->where + loop->incnum;
3350 M_free(d->where,
"dollar");
3352 d->type = DOLUNDEFINED;
3353 M_free(loop->dollarname,
"do-loop instruction");
3360 ww = w + *w; v = *ww; *ww = 0;
3361 dw = d->where; d->where = w;
3362 t = WriteDollarToBuffer(numdollar,1);
3363 d->where = dw; *ww = v;
3367 if ( loop->firstloopcall ) OpenStream(loop->contents,PREREADSTREAM2,0,PRENOACTION);
3368 else OpenStream(loop->contents,PREREADSTREAM,0,PRENOACTION);
3369 AC.CurrentStream->prevline =
3370 AC.CurrentStream->linenumber = loop->startlinenumber;
3371 AC.CurrentStream->eqnum = 0;
3372 loop->firstloopcall = 0;
3376 retval = DoUndefine(loop->name);
3377 M_free(loop->p.buffer,
"loop->p.buffer");
3378 loop->firstloopcall = 0;
3388int DoEndif(UBYTE *s)
3391 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3392 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#endif without corresponding %#if");
3393 else MessPreNesting(5);
3397 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3398 if ( AP.PreIfLevel <= 0 ) {
3399 MesPrint(
"@%#endif without corresponding %#if");
3416int DoEndprocedure(UBYTE *s)
3419 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) {
3424 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3425 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3426 AC.CurrentStream = CloseStream(AC.CurrentStream);
3430 if ( Procedures[NumProcedures].mustfree == 1 ) {
3431 M_free(Procedures[NumProcedures].p.buffer,
"procedures buffer");
3432 M_free(Procedures[NumProcedures].name,
"procedures name");
3434 }
while ( Procedures[NumProcedures].loadmode > 1 );
3446 AddToPreTypes(PRETYPEIF);
3447 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3448 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3449 condition = EvalPreIf(s);
3450 if ( condition < 0 )
return(-1);
3452 else condition = LOOKINGFORENDIF;
3453 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3454 int **ppp = &AP.PreIfStack;
3455 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3456 "PreIfLevels") )
return(-1);
3458 AP.PreIfStack[++AP.PreIfLevel] = condition;
3467int DoIfdef(UBYTE *s,
int par)
3470 AddToPreTypes(PRETYPEIF);
3471 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3472 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3473 while ( *s ==
' ' || *s ==
'\t' ) s++;
3474 if ( ( *s == 0 ) == ( par == 1 ) ) condition = LOOKINGFORELSE;
3475 else condition = EXECUTINGIF;
3477 else condition = LOOKINGFORENDIF;
3478 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3479 int **ppp = &AP.PreIfStack;
3480 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3481 "PreIfLevels") )
return(-1);
3483 AP.PreIfStack[++AP.PreIfLevel] = condition;
3492int DoIfydef(UBYTE *s)
3494 return DoIfdef(s,1);
3502int DoIfndef(UBYTE *s)
3504 return DoIfdef(s,2);
3527int DoInside(UBYTE *s)
3530 int numdol, error = 0;
3531 WORD *nb, newsize, i;
3533 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3534 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3535 if ( AP.PreInsideLevel != 0 ) {
3536 MesPrint(
"@Illegal nesting of %#inside/%#endinside instructions");
3549 AP.inside.numdollars = 0;
3551 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
3552 if ( *s == 0 )
break;
3554 MesPrint(
"@%#inside instruction can have only $ variables for parameters");
3559 while (chartype[*s] <= 1 ) s++;
3561 if ( ( numdol = GetDollar(name) ) < 0 ) {
3562 MesPrint(
"@%#inside: $%s has not (yet) been defined",name);
3568 if ( AP.inside.numdollars >= AP.inside.size ) {
3569 if ( AP.inside.buffer == 0 ) newsize = 20;
3570 else newsize = 2*AP.inside.size;
3571 nb = (WORD *)Malloc1(newsize*
sizeof(WORD),
"insidebuffer");
3572 if ( AP.inside.buffer ) {
3573 for ( i = 0; i < AP.inside.size; i++ ) nb[i] = AP.inside.buffer[i];
3574 M_free(AP.inside.buffer,
"insidebuffer");
3576 AP.inside.buffer = nb;
3577 AP.inside.size = newsize;
3579 AP.inside.buffer[AP.inside.numdollars++] = numdol;
3586 AP.inside.oldcompiletype = AC.compiletype;
3587 AP.inside.oldparallelflag = AC.mparallelflag;
3588 AP.inside.oldnumpotmoddollars = NumPotModdollars;
3589 AP.inside.oldcbuf = AC.cbufnum;
3590 AP.inside.oldrbuf = AM.rbufnum;
3591 AP.inside.oldcnumlhs = AR.Cnumlhs,
3592 AddToPreTypes(PRETYPEINSIDE);
3593 AP.PreInsideLevel = 1;
3594 AC.cbufnum = AP.inside.inscbuf;
3595 AM.rbufnum = AP.inside.inscbuf;
3598 AC.mparallelflag = PARALLELFLAG;
3607 PF_StoreInsideInfo();
3608 AC.RhsExprInModuleFlag = 0;
3609 NumPotModdollars = 0;
3610 AC.numpfirstnum = 0;
3620int DoEndInside(UBYTE *s)
3623 WORD numdol, *oldworkpointer = AT.WorkPointer, *term, *t, j, i;
3625 WORD oldbracketon = AR.BracketOn;
3626 WORD *oldcompresspointer = AR.CompressPointer;
3627 int oldmultithreaded = AS.MultiThreaded;
3634 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3635 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3636 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEINSIDE ) {
3637 if ( AP.PreInsideLevel != 1 ) MesPrint(
"@%#endinside without corresponding %#inside");
3638 else MessPreNesting(11);
3642 if ( AP.PreInsideLevel != 1 ) {
3643 MesPrint(
"@%#endinside without corresponding %#inside");
3646 if ( AP.PreContinuation ) {
3647 MesPrint(
"@%#endinside: previous statement not terminated.");
3650 AC.compiletype = AP.inside.oldcompiletype;
3651 AR.Cnumlhs = cbuf[AM.rbufnum].numlhs;
3658 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
3661 AS.MultiThreaded = 0;
3663 if ( AR.CompressPointer == 0 ) AR.CompressPointer = AR.CompressBuffer;
3664 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3668 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3669 numdol = AP.inside.buffer[i];
3670 nd = d = Dollars + numdol;
3671 if ( d->type != DOLZERO ) {
3672 if ( d->type != DOLTERMS ) nd = DolToTerms(BHEAD numdol);
3676 AR.MaxDum = AM.IndDum;
3678 t = oldworkpointer; j = *term;
3681 AN.IndDum = AM.IndDum;
3682 AR.CurDum = ReNumber(BHEAD term);
3683 if (
Generator(BHEAD oldworkpointer,0) ) {
3684 MesPrint(
"@Called from %#endinside");
3685 MesPrint(
"@Evaluating variable $%s",DOLLARNAME(Dollars,numdol));
3689 AT.WorkPointer = oldworkpointer;
3690 CleanDollarFactors(d);
3691 if ( d->where ) { M_free(d->where,
"dollar contents"); d->where = 0; }
3692 EndSort(BHEAD (WORD *)((
void *)(&(d->where))),2);
3694 term = d->where;
while ( *term ) term += *term;
3695 d->size = term - d->where;
3696 if ( nd != d ) M_free(nd,
"Copy of dollar variable");
3697 if ( d->where[0] == 0 ) {
3698 M_free(d->where,
"dollar contents"); d->where = 0;
3705 if ( AC.RhsExprInModuleFlag ) {
3710 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3718 if ( NumPotModdollars > 0 ) {
3720 if ( error )
goto cleanup;
3722 if ( AC.numpfirstnum > 0 ) {
3724 if ( error )
goto cleanup;
3729 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3730 AC.cbufnum = AP.inside.oldcbuf;
3731 AM.rbufnum = AP.inside.oldrbuf;
3732 AR.Cnumlhs = AP.inside.oldcnumlhs;
3733 AR.BracketOn = oldbracketon;
3734 AP.PreInsideLevel = 0;
3735 AR.CompressPointer = oldcompresspointer;
3736 AS.MultiThreaded = oldmultithreaded;
3737 AC.mparallelflag = AP.inside.oldparallelflag;
3738 NumPotModdollars = AP.inside.oldnumpotmoddollars;
3741 PF_RestoreInsideInfo();
3742 if ( error )
return error;
3752int DoMessage(UBYTE *s)
3754 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3755 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3756 while ( *s ==
' ' || *s ==
'\t' ) s++;
3757 MesPrint(
"~~~%s",s);
3771 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3772 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3775 while ( *s ==
' ' || *s ==
'\t' ) s++;
3776 if ( OpenStream(s,PIPESTREAM,0,PRENOACTION) == 0 )
return(-1);
3779 Error0(
"Pipes not implemented on this computer/system");
3789int DoPrcExtension(UBYTE *s)
3792 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3793 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3794 while ( *s ==
' ' || *s ==
'\t' ) s++;
3795 if ( *s == 0 || *s ==
'\n' ) {
3796 MesPrint(
"@No valid procedure extension specified");
3799 if ( FG.cTable[*s] != 0 ) {
3800 MesPrint(
"@Procedure extension should be a string starting with an alphabetic character. No whitespace.");
3804 while ( *s && *s !=
'\n' && *s !=
' ' && *s !=
'\t' ) s++;
3806 while ( *s ==
' ' || *s ==
'\t' ) s++;
3807 if ( *s != 0 && *s !=
'\n' ) {
3808 MesPrint(
"@Too many parameters in ProcedureExtension instruction");
3812 if ( AP.procedureExtension ) M_free(AP.procedureExtension,
"ProcedureExtension");
3813 AP.procedureExtension = strDup1(t,
"ProcedureExtension");
3823int DoPreOut(UBYTE *s)
3825 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3826 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3827 if ( tolower(*s) ==
'o' ) {
3828 if ( tolower(s[1]) ==
'n' && s[2] == 0 ) {
3832 if ( tolower(s[1]) ==
'f' && tolower(s[2]) ==
'f' && s[3] == 0 ) {
3837 MesPrint(
"@Illegal option in PreOut instruction");
3846int DoPrePrintTimes(UBYTE *s)
3849 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3850 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3860int DoPreSortReallocate(UBYTE *s)
3863 if ( AC.SortReallocateFlag == 0 ) {
3866 AC.SortReallocateFlag = 2;
3880int DoPreAppend(UBYTE *s)
3884 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3885 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3886 if ( AP.preError )
return(0);
3887 while ( *s ==
' ' || *s ==
'\t' ) s++;
3894 while ( *s && *s !=
'>' ) {
3895 if ( *s ==
'\\' ) s++;
3899 MesPrint(
"@Improper termination of filename");
3904 if ( *name ) { GetAppendChannel((
char *)name); }
3909 MesPrint(
"@Proper syntax is: %#append <filename>");
3923int DoPreCreate(UBYTE *s)
3927 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3928 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3929 if ( AP.preError )
return(0);
3930 while ( *s ==
' ' || *s ==
'\t' ) s++;
3937 while ( *s && *s !=
'>' ) {
3938 if ( *s ==
'\\' ) s++;
3942 MesPrint(
"@Improper termination of filename");
3947 if ( *name ) { GetChannel((
char *)name,0); }
3952 MesPrint(
"@Proper syntax is: %#create <filename>");
3963int DoPreRemove(UBYTE *s)
3966 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3967 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3968 if ( AP.preError )
return(0);
3969 while ( *s ==
' ' || *s ==
'\t' ) s++;
3970 if ( *s ==
'<' ) { s++; }
3972 MesPrint(
"@Proper syntax is: %#remove <filename>");
3976 while ( *s && *s !=
'>' ) {
3977 if ( *s ==
'\\' ) s++;
3981 MesPrint(
"@Improper filename");
3986 CloseChannel((
char *)name);
3987 remove((
char *)name);
3996int DoPreClose(UBYTE *s)
3999 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4000 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4001 if ( AP.preError )
return(0);
4002 while ( *s ==
' ' || *s ==
'\t' ) s++;
4003 if ( *s ==
'<' ) { s++; }
4005 MesPrint(
"@Proper syntax is: %#close <filename>");
4009 while ( *s && *s !=
'>' ) {
4010 if ( *s ==
'\\' ) s++;
4014 MesPrint(
"@Improper filename");
4019 return(CloseChannel((
char *)name));
4040int DoPreWrite(UBYTE *s)
4044 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4045 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4046 if ( AP.preError )
return(0);
4049 if ( PF.me != MASTER )
return 0;
4052 h.oldsilent = AM.silent;
4053 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
4054 h.newhandle = h.oldhandle = AC.LogHandle;
4055 h.oldprinttype = AO.PrintType;
4057 while ( *s ==
' ' || *s ==
'\t' ) s++;
4061 if( (s=defineChannel(s,&h))==0 )
return(-1);
4063 return(writeToChannel(WRITEOUT,s,&h));
4081int DoProcedure(UBYTE *s)
4086 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
4087 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
4088 if ( PreSkip((UBYTE *)
"procedure",(UBYTE *)
"endprocedure",1) )
return(-1);
4092 p = (
PROCEDURE *)FromList(&AP.ProcList);
4093 if ( PreLoad(&(p->p),(UBYTE *)
"procedure",(UBYTE *)
"endprocedure"
4094 ,1,(
char *)
"procedure") )
return(-1);
4100 if ( NumProcedures >= 2 &&
4101 ( Procedures[NumProcedures-2].loadmode != 2 || Procedures[NumProcedures-2].mustfree ) ) {
4111 s = p->p.buffer + 10;
4112 while ( *s ==
' ' || *s == LINEFEED ) s++;
4113 if ( chartype[*s] ) {
4114 MesPrint(
"@Illegal name for procedure");
4118 while ( chartype[*s] == 0 || chartype[*s] == 1 ) s++;
4120 p->name = strDup1(p->name,
"procedure");
4125 for ( i = NumProcedures-2; i >= 0; i-- ) {
4126 if ( StrCmp(Procedures[i].name,p->name) == 0 ) {
4127 Error1(
"Multiple occurrence of procedure name ",p->name);
4138int DoPreBreak(UBYTE *s)
4141 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4142 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4143 if ( AP.PreSwitchLevel <= 0 )
4144 MesPrint(
"@Break without corresponding Switch");
4145 else MessPreNesting(7);
4148 if ( AP.PreSwitchLevel <= 0 ) {
4149 MesPrint(
"@Break without corresponding Switch");
4152 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH )
4153 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4162int DoPreCase(UBYTE *s)
4165 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4166 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4167 if ( AP.PreSwitchLevel <= 0 )
4168 MesPrint(
"@Case without corresponding Switch");
4169 else MessPreNesting(8);
4172 if ( AP.PreSwitchLevel <= 0 ) {
4173 MesPrint(
"@Case without corresponding Switch");
4176 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
4180 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
4181 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
4182 if ( s[-2] ==
'\\' ) s--;
4185 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
4189 s = AP.PreSwitchStrings[AP.PreSwitchLevel];
4190 while ( *t == *s && *t ) { s++; t++; }
4191 if ( *t || *s )
return(0);
4192 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
4201int DoPreDefault(UBYTE *s)
4204 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4205 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4206 if ( AP.PreSwitchLevel <= 0 )
4207 MesPrint(
"@Default without corresponding Switch");
4208 else MessPreNesting(9);
4211 if ( AP.PreSwitchLevel <= 0 ) {
4212 MesPrint(
"@Default without corresponding Switch");
4215 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
4216 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
4225int DoPreEndSwitch(UBYTE *s)
4228 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4229 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4230 if ( AP.PreSwitchLevel <= 0 )
4231 MesPrint(
"@EndSwitch without corresponding Switch");
4232 else MessPreNesting(10);
4236 if ( AP.PreSwitchLevel <= 0 ) {
4237 MesPrint(
"@EndSwitch without corresponding Switch");
4240 M_free(AP.PreSwitchStrings[AP.PreSwitchLevel--],
"pre switch string");
4252int DoPreSwitch(UBYTE *s)
4254 UBYTE *t, *switchstring, **newstrings;
4255 int newnum, i, *newmodes;
4256 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4259 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
4260 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
4261 if ( s[-2] ==
'\\' ) s--;
4264 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
4268 switchstring = (UBYTE *)Malloc1((s-t)+1,
"case string");
4271 if ( *t ==
'\\' ) t++;
4275 if ( AP.PreSwitchLevel >= AP.NumPreSwitchStrings ) {
4276 newnum = 2*AP.NumPreSwitchStrings;
4277 newstrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*(newnum+1),
"case strings");
4278 newmodes = (
int *)Malloc1(
sizeof(
int)*(newnum+1),
"case strings");
4279 for ( i = 0; i < AP.NumPreSwitchStrings; i++ )
4280 newstrings[i] = AP.PreSwitchStrings[i];
4281 M_free(AP.PreSwitchStrings,
"AP.PreSwitchStrings");
4282 for ( i = 0; i <= AP.NumPreSwitchStrings; i++ )
4283 newmodes[i] = AP.PreSwitchModes[i];
4284 M_free(AP.PreSwitchModes,
"AP.PreSwitchModes");
4285 AP.PreSwitchStrings = newstrings;
4286 AP.PreSwitchModes = newmodes;
4287 AP.NumPreSwitchStrings = newnum;
4289 AP.PreSwitchStrings[++AP.PreSwitchLevel] = switchstring;
4290 if ( ( AP.PreSwitchLevel > 1 )
4291 && ( AP.PreSwitchModes[AP.PreSwitchLevel-1] != EXECUTINGPRESWITCH ) )
4292 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4294 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPRECASE;
4295 AddToPreTypes(PRETYPESWITCH);
4306int DoPreShow(UBYTE *s)
4310 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4311 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4312 while ( *s ==
' ' || *s ==
'\t' ) s++;
4314 MesPrint(
"%#The preprocessor variables:");
4315 for ( i = 0; i < NumPre; i++ ) {
4316 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4321 name = s;
while ( *s && *s !=
' ' && *s !=
'\t' && *s !=
',' ) s++;
4323 for ( i = 0; i < NumPre; i++ ) {
4324 if ( StrCmp(PreVar[i].name,name) == 0 )
4325 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4328 while ( *s ==
' ' || *s ==
'\t' ) s++;
4342#define STRINGIFY(x) STRINGIFY__(x)
4343#define STRINGIFY__(x) #x
4345int DoSystem(UBYTE *s)
4347 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4348 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4349 if ( AP.preError )
return(0);
4352 while ( *s ==
' ' || *s ==
'\t' ) s++;
4353 if ( *s ==
'-' && s[1] ==
'e' ) {
4358 MesPrint(
"@Syntax error in #system command.");
4361 while ( *s ==
' ' || *s ==
'\t' ) s++;
4362 err = system((
char *)s);
4364 PutPreVar((UBYTE *)
"SYSTEMERROR_",str,0,1);
4366 else if ( system((
char *)s) ) {
4367 MesPrint(
"@System call returned with error condition");
4372 Error0(
"External programs not implemented on this computer/system");
4385int PreLoad(
PRELOAD *p, UBYTE *start, UBYTE *stop,
int mode,
char *message)
4387 UBYTE *s, *t, *top, *newbuffer, c;
4388 LONG i, ppsize, linenum = AC.CurrentStream->linenumber;
4389 int size1, size2, level, com=0, last=1, strng = 0;
4391 p->buffer = (UBYTE *)Malloc1(p->size+1,message);
4392 top = p->buffer + p->size - 2;
4393 t = p->buffer; *t++ =
'#';
4394 s = start; size1 = size2 = 0;
4395 while ( *s ) { s++; size1++; }
4396 s = stop;
while ( *s ) { s++; size2++; }
4397 s = AP.preStart;
while ( *s ) *t++ = *s++; *t++ = LINEFEED;
4402 if ( c == ENDOFINPUT ) {
4403 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4406 if ( c == AP.ComChar && last == 1 ) com = 1;
4407 if ( c == LINEFEED ) { last = 1; com = 0; }
4410 if ( ( c ==
'"' ) && ( com == 0 ) ) { strng ^= 1; }
4412 if ( ( c ==
'#' ) && ( com == 0 ) ) i = 0;
4416 ppsize = t - p->buffer;
4418 newbuffer = (UBYTE *)Malloc1(p->size,message);
4419 t = newbuffer; s = p->buffer;
4420 while ( --ppsize >= 0 ) *t++ = *s++;
4421 M_free(p->buffer,
"loading do loop");
4422 p->buffer = newbuffer;
4423 top = p->buffer + p->size - 2;
4427 if ( ( i == size2 ) && ( com == 0 ) ) {
4429 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4430 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4432 if ( level <= 0 )
break;
4433 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4434 *t++ = LINEFEED; *t = 0; last = 1;
4437 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4439 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4447 if ( i == 1 && t[-2] == LINEFEED ) {
4448 if ( c ==
'-' ) AC.NoShowInput = 1;
4449 else if ( c ==
'+' ) AC.NoShowInput = 0;
4466#define SKIPBUFSIZE 20
4468int PreSkip(UBYTE *start, UBYTE *stop,
int mode)
4470 UBYTE *s, *t, buffer[SKIPBUFSIZE+2], c;
4471 LONG i, linenum = AC.CurrentStream->linenumber;
4472 int size1, size2, level, com=0, last=1;
4474 t = buffer; *t++ =
'#';
4475 s = start; size1 = size2 = 0;
4476 while ( *s ) { s++; size1++; }
4477 s = stop;
while ( *s ) { s++; size2++; }
4482 if ( c == ENDOFINPUT ) {
4483 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4486 if ( c == AP.ComChar && last == 1 ) com = 1;
4487 if ( c == LINEFEED ) { last = 1; com = 0; i = 0; t = buffer; }
4489 if ( ( c ==
'#' ) && ( com == 0 ) ) { i = 0; t = buffer; }
4492 if ( i < SKIPBUFSIZE ) *t++ = c;
4493 if ( ( i == size2 ) && ( com == 0 ) ) {
4495 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4496 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4499 pushbackchar = LINEFEED;
4502 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4506 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4508 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4509 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4523void StartPrepro(
void)
4526 AP.MaxPreIfLevel = 2;
4527 ppp = &AP.PreIfStack;
4528 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
4529 "PreIfLevels") ) Terminate(-1);
4530 AP.PreIfLevel = 0; AP.PreIfStack[0] = EXECUTINGIF;
4532 AP.NumPreSwitchStrings = 10;
4533 AP.PreSwitchStrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*
4534 (AP.NumPreSwitchStrings+1),
"case strings");
4535 AP.PreSwitchModes = (
int *)Malloc1(
sizeof(
int)*
4536 (AP.NumPreSwitchStrings+1),
"case strings");
4537 AP.PreSwitchModes[0] = EXECUTINGPRESWITCH;
4538 AP.PreSwitchLevel = 0;
4551int EvalPreIf(UBYTE *s)
4559 if ( ( u = PreIfEval(s,&val) ) == 0 )
return(-1);
4561 MesPrint(
"@Unmatched parentheses in condition");
4564 if ( val )
return(EXECUTINGIF);
4565 else return(LOOKINGFORELSE);
4586UBYTE *PreIfEval(UBYTE *s,
int *value)
4588 int orlevel = 0, andlevel = 0, eqlevel = 0, cmplevel = 0;
4591 int ortype, orval, cmptype, cmpval, eqtype, eqval, andtype, andval;
4592 UBYTE *t, *eqt, *cmpt, c;
4594 ortype = orval = cmptype = cmpval = eqtype = eqval = andtype = andval = 0;
4598 while ( *s !=
')' ) {
4599 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4601 s = pParseObject(s,&type,&val2);
4602 if ( s == 0 )
return(0);
4606 while ( c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' ) {
4609 if ( *t ==
'"' ) t++;
4612 if ( *s !=
'|' )
goto illoper;
4617 if ( type == 0 || cmptype == 0 )
goto illobject;
4618 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4623 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4628 if ( andtype != 0 || type != 0 )
goto illobject;
4633 if ( ortype != 0 || type != 0 )
goto illobject;
4645 if ( *s !=
'&' )
goto illoper;
4648 if ( type == 0 || cmptype == 0 )
goto illobject;
4649 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4654 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4659 if ( andtype != 0 || type != 0 )
goto illobject;
4668 if ( eqlevel )
goto illorder;
4670 if ( type == 0 || cmptype == 0 )
goto illobject;
4671 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4675 if ( c ==
'!' && *s !=
'=' )
goto illoper;
4676 if ( *s ==
'=' ) s++;
4677 if ( c ==
'!' ) eqop = 1;
4679 eqlevel = 1; eqt = t; eqval = val; eqtype = type;
4683 if ( cmplevel )
goto illorder;
4684 if ( c ==
'<' ) cmpop = -1;
4686 cmplevel = 1; cmpt = t; cmpval = val; cmptype = type;
4689 if ( *s ==
'~' ) { s++; cmpop *= 4; }
4692 else if ( *s ==
'~' ) { s++; cmpop *= 3; }
4700 MesPrint(
"@illegal order of operators");
4703 MesPrint(
"@illegal object for this operator");
4706 MesPrint(
"@illegal operator");
4715int PreCmp(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int cmpop)
4717 if ( type == 2 || type2 == 2 || cmpop < -2 || cmpop > 2 ) {
4718 if ( cmpop < 0 && cmpop > -3 ) cmpop -= 2;
4719 if ( cmpop > 0 && cmpop < 3 ) cmpop += 2;
4720 if ( cmpop == 3 ) val = StrCmp(t2,t) > 0;
4721 else if ( cmpop == 4 ) val = StrCmp(t2,t) >= 0;
4722 else if ( cmpop == -3 ) val = StrCmp(t2,t) < 0;
4723 else if ( cmpop == -4 ) val = StrCmp(t2,t) <= 0;
4726 if ( cmpop == 1 ) val = ( val2 > val );
4727 else if ( cmpop == 2 ) val = ( val2 >= val );
4728 else if ( cmpop == -1 ) val = ( val2 < val );
4729 else if ( cmpop == -2 ) val = ( val2 <= val );
4739int PreEq(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int eqop)
4742 if ( type == 2 || type2 == 2 ) {
4743 if ( type != 2 ) { NumToStr(str,val ); t = str; }
4744 if ( type2 != 2 ) { NumToStr(str,val2); t2 = str; }
4745 if ( eqop == 1 ) val = StrCmp(t,t2) != 0;
4746 else val = StrCmp(t,t2) == 0;
4749 if ( eqop ) val = val != val2;
4750 else val = val == val2;
4768UBYTE *pParseObject(UBYTE *s,
int *type, LONG *val2)
4773 while ( *s ==
' ' || *s ==
'\t' ) s++;
4776 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4777 s = PreIfEval(s,&val);
4782 else if ( *s ==
'$' && s[1] ==
'(' ) {
4784 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4785 s = PreIfDollarEval(s,&val);
4786 *type = 0; *val2 = val;
4791 MesPrint(
"@illegal end of condition");
4796 while ( *s && *s !=
'"' ) {
4797 if ( *s ==
'\\' ) s++;
4800 if ( *s == 0 )
goto illend;
4805 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4809 t = s; sign = 1; x = 0;
4810 if ( chartype[*t] == 0 ) {
4811 do { t++; }
while ( chartype[*t] <= 1 );
4815 if ( StrICmp(s,(UBYTE *)
"termsin") == 0 ) {
4817 WORD numdol, numexp;
4821 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4823 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4825 if ( ( numdol = GetDollar(t) ) > 0 ) {
4828 x = SizeOfDollar(numdol);
4831 x = TermsInDollar(numdol);
4835 MesPrint(
"@$%s has not (yet) been defined",t);
4843 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4844 MesPrint(
"@%s has not (yet) been defined",t);
4851 x = SizeOfExpression(numexp);
4854 x = TermsInExpression(numexp);
4858 while ( *tt ==
' ' || *tt ==
'\t'
4859 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4861 MesPrint(
"@Improper use of terms($var) or terms(expr)");
4869 else if ( StrICmp(s,(UBYTE *)
"sizeof") == 0 ) {
4873 else if ( StrICmp(s,(UBYTE *)
"exists") == 0 ) {
4875 WORD numdol, numexp;
4877 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4879 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4881 if ( ( numdol = GetDollar(t) ) >= 0 ) { x = 1; }
4885 else if ( *t ==
'"' ) {
4889 if ( *tt ==
'\\' ) tt++;
4890 else if ( *tt ==
'"' )
break;
4903 x = OpenFile((
char *)t);
4920 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) { x = 0; }
4924 while ( *tt ==
' ' || *tt ==
'\t'
4925 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4927 MesPrint(
"@Improper use of exists($var) or exists(expr)");
4935 else if ( StrICmp(s,(UBYTE *)
"isnumerical") == 0 ) {
4938 WORD numdol, numexp;
4940 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4942 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4944 if ( ( numdol = GetDollar(t) ) < 0 ) {
4945 MesPrint(
"@$ variable in isnumerical(%s) does not exist",t);
4948 x = DolToLong(BHEAD numdol);
4949 if ( AN.ErrorInDollar ) {
4952 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
4953 if ( d->where[0] == 0 ) x = 1;
4954 else if ( d->where[d->where[0]] == 0 ) {
4955 if ( ABS(d->where[d->where[0]-1]) == d->where[0]-1 )
4966 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4967 MesPrint(
"@expression in isnumerical(%s) does not exist",t);
4970 x = TermsInExpression(numexp);
4971 if ( x != 1 ) x = 0;
4973 WORD *term = AT.WorkPointer;
4975 MesPrint(
"@error reading expression in isnumerical(%s)",t);
4978 if ( *term == ABS(term[*term-1])+1 ) x = 1;
4983 while ( *tt ==
' ' || *tt ==
'\t'
4984 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4986 MesPrint(
"@Improper use of isnumerical($var) or numerical(expr)");
4994 else if ( StrICmp(s,(UBYTE *)(
"maxpowerof")) == 0 ) {
4999 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5002 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
5003 MesPrint(
"@%s has not (yet) been defined",t);
5007 else if ( stype != CSYMBOL ) {
5008 MesPrint(
"@%s should be a symbol",t);
5014 x = symbols[numsym].maxpower;
5016 while ( *tt ==
' ' || *tt ==
'\t'
5017 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5019 MesPrint(
"@Improper use of maxpowerof(symbol)");
5027 else if ( StrICmp(s,(UBYTE *)(
"minpowerof")) == 0 ) {
5032 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5035 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
5036 MesPrint(
"@%s has not (yet) been defined",t);
5040 else if ( stype != CSYMBOL ) {
5041 MesPrint(
"@%s should be a symbol",t);
5047 x = symbols[numsym].minpower;
5049 while ( *tt ==
' ' || *tt ==
'\t'
5050 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5052 MesPrint(
"@Improper use of minpowerof(symbol)");
5060 else if ( StrICmp(s,(UBYTE *)
"isfactorized") == 0 ) {
5062 WORD numdol, numexp;
5064 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5066 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
5068 if ( ( numdol = GetDollar(t) ) > 0 ) {
5069 if ( Dollars[numdol].factors != 0 ) x = 1;
5073 MesPrint(
"@ %s should be the name of an expression or a $ variable",t-1);
5081 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
5082 MesPrint(
"@ %s should be the name of an expression or a $ variable",t);
5086 if ( ( Expressions[numexp].vflags & ISFACTORIZED ) != 0 ) x = 1;
5091 while ( *tt ==
' ' || *tt ==
'\t'
5092 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5094 MesPrint(
"@Improper use of isfactorized($var) or isfactorized(expr)");
5102 else if ( StrICmp(s,(UBYTE *)
"isdefined") == 0 ) {
5105 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5111 while ( *tt ==
' ' || *tt ==
'\t'
5112 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5114 MesPrint(
"@Improper use of isdefined(var)");
5122 else if ( StrICmp(s,(UBYTE *)
"flag") == 0 ) {
5127 while ( *t ==
' ' || *t ==
'\t' ) t++;
5128 if ( FG.cTable[*t] != 1 )
goto flagerror;
5129 while ( FG.cTable[*t] == 1 ) x = 10*x + (*t++ -
'0');
5130 if ( x < 1 || x > BITSINWORD ) {
5131 MesPrint(
"@Illegal number %d for flag in flag condition",x);
5134 while ( *t ==
' ' || *t ==
'\t' ) t++;
5135 if ( *t !=
',' )
goto flagerror;
5137 while ( *t ==
' ' || *t ==
'\t' ) t++;
5140 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
5141 MesPrint(
"@ %s should be the name of an expression",t);
5145 while ( *t ==
' ' || *t ==
'\t' ) t++;
5148 MesPrint(
"@Improper use of flag(num,expr)");
5152 if ( ( Expressions[numexp].uflags & ( 1 << (x-1) ) ) != 0 )
5162 else if ( *t ==
'=' || *t ==
'<' || *t ==
'>' || *t ==
'!'
5163 || *t ==
')' || *t ==
' ' || *t ==
'\t' || *t == 0 || *t ==
'\n' ) {
5169 MesPrint(
"@Illegal use of string in preprocessor condition: %s",s);
5173 while ( *t ==
'-' || *t ==
'+' || *t ==
' ' || *t ==
'\t' ) {
5174 if ( *t ==
'-' ) sign = -sign;
5177 while ( chartype[*t] == 1 ) { x = 10*x + *t++ -
'0'; }
5178 while ( *t ==
' ' || *t ==
'\t' ) t++;
5179 if ( chartype[*t] == 8 || *t ==
')' || *t ==
'=' || *t == 0 ) {
5180 *val2 = sign > 0 ? x: -x;
5184 while ( chartype[*t] != 8 && *t !=
')' && *t !=
'=' && *t ) t++;
5185 while ( ( t > s ) && ( t[-1] ==
' ' || t[-1] ==
'\t' ) ) t--;
5206 UBYTE *buff, *s = 0, *t, *newb, c;
5207 int size, i, n, parlevel = 0, bralevel = 0;
5214 if ( size == 0 ) size = 72;
5216 if ( ( newb = (UBYTE *)Malloc1(size+2,
"{}") ) == 0 )
return(0);
5222 M_free(buff,
"pre calc buffer");
5230 Error0(
"Unmatched {}");
5231 M_free(buff,
"precalc buffer");
5234 else if ( c ==
'{' ) { bralevel++; }
5235 else if ( c ==
'}' ) {
5236 if ( --bralevel < 0 ) { *s++ = c; *s = 0;
break; }
5238 else if ( c ==
'(' ) { parlevel++; }
5239 else if ( c ==
')' ) {
5240 if ( --parlevel < 0 ) { *s++ = c; *s = 0;
goto setstring; }
5242 else if ( chartype[c] != 1 && chartype[c] != 5
5243 && chartype[c] != 6 && c !=
'!' && c !=
'&'
5244 && c !=
'|' && c !=
'\\' ) { *s++ = c; *s = 0;
goto setstring; }
5246 if ( parlevel > 0 )
goto setstring;
5252 if ( PreEval(buff+1,&answer) == 0 )
goto setstring;
5255 if ( answer < 0 ) { *s++ =
'-'; }
5256 uanswer = LongAbs(answer);
5259 *--t = ( uanswer % 10 ) +
'0';
5262 }
while ( uanswer > 0 );
5270 if ( OpenStream(buff,PRECALCSTREAM,0,PRENOACTION) == 0 )
return(0);
5282UBYTE *PreEval(UBYTE *s, LONG *x)
5285 int tobemultiplied, tobeadded = 1, expsign, i;
5288 while ( *s ==
' ' || *s ==
'\t' ) s++;
5290 if ( *s ==
'+' || *s ==
'-' ) {
5291 if ( *s ==
'-' ) tobeadded = -1;
5294 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5295 if ( *s ==
'-' ) tobeadded = -tobeadded;
5301 while ( *s ==
' ' || *s ==
'\t' ) s++;
5302 if ( *s <=
'9' && *s >=
'0' ) {
5307 else if ( *s ==
'(' || *s ==
'{' ) {
5308 if ( ( t = PreEval(s+1,&y) ) == 0 )
return(0);
5312 while ( *s ==
' ' || *s ==
'\t' ) s++;
5314 while ( *s ==
'^' || *s ==
'!' ) {
5316 if ( s[-1] ==
'!' ) {
5317 while ( *s ==
' ' || *s ==
'\t' ) s++;
5319 MesPrint(
"@Negative value in preprocessor factorial: %l",y);
5322 else if ( y == 0 ) y = 1;
5325 while ( z > 0 ) { y = y*z; z--; }
5329 else if ( *s ==
'%' ) {
5331 while ( *s ==
' ' || *s ==
'\t' ) s++;
5334 MesPrint(
"@Illegal value in preprocessor logarithm: %l",z);
5338 while ( z ) { y++; z >>= 1; }
5341 else if ( *s ==
'/' ) {
5344 while ( *s ==
' ' || *s ==
'\t' ) s++;
5347 MesPrint(
"@Illegal value in preprocessor square root: %l",z);
5353 while ( zz ) { yy++; zz >>= 1; }
5354 zz = z >> (yy/2); i = 10; y = 0;
5356 yy = zz/2 + z/(2*zz); i--;
5357 if ( y == yy )
break;
5359 }
while ( y != yy && i > 0 );
5360 while ( y*y < z ) y++;
5361 while ( y*y > z ) y--;
5363 else if ( z >= 4 ) y = 2;
5364 else if ( z == 0 ) y = 0;
5368 while ( *s ==
' ' || *s ==
'\t' ) s++;
5369 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5370 if ( *s ==
'-' ) expsign = -expsign;
5372 if ( *s <=
'9' && *s >=
'0' ) {
5375 else if ( *s ==
'(' || *s ==
'{' ) {
5376 if ( ( t = PreEval(s+1,&z) ) == 0 )
return(0);
5380 while ( *s ==
' ' || *s ==
'\t' ) s++;
5383 if ( tobemultiplied == 0 ) {
5384 if ( expsign < 0 ) a = 1/y;
5388 if ( tobemultiplied > 2 && expsign != 1 ) {
5389 MesPrint(
"&Incorrect use of ^ with & or |. Use brackets!");
5392 tobemultiplied *= expsign;
5393 if ( tobemultiplied == 1 ) a *= y;
5394 else if ( tobemultiplied == 3 ) a &= y;
5395 else if ( tobemultiplied == 4 ) a |= y;
5397 if ( y == 0 || tobemultiplied == -2 ) {
5398 MesPrint(
"@Division by zero in preprocessor calculator");
5401 if ( tobemultiplied == 2 ) a %= y;
5405 if ( *s ==
'%' ) tobemultiplied = 2;
5406 else if ( *s ==
'*' ) tobemultiplied = 1;
5407 else if ( *s ==
'/' ) tobemultiplied = -1;
5408 else if ( *s ==
'&' ) tobemultiplied = 3;
5409 else if ( *s ==
'|' ) tobemultiplied = 4;
5414 if ( tobeadded >= 0 ) ux += ua;
5416 *x = ULongToLong(ux);
5417 if ( *s ==
')' || *s ==
'}' )
return(s+1);
5418 else if ( *s ==
'-' || *s ==
'+' ) { tobeadded = 1;
break; }
5432void AddToPreTypes(
int type)
5434 if ( AP.NumPreTypes >= AP.MaxPreTypes ) {
5435 int i, *newlist = (
int *)Malloc1(
sizeof(
int)*(2*AP.MaxPreTypes+1)
5436 ,
"preprocessor type lists");
5437 for ( i = 0; i <= AP.MaxPreTypes; i++ ) newlist[i] = AP.PreTypes[i];
5438 M_free(AP.PreTypes,
"preprocessor type lists");
5439 AP.PreTypes = newlist;
5440 AP.MaxPreTypes = 2*AP.MaxPreTypes;
5442 AP.PreTypes[++AP.NumPreTypes] = type;
5450void MessPreNesting(
int par)
5452 MesPrint(
"@(%d)Illegal nesting of %#if, %#do, %#procedure and/or %#switch",par);
5473int DoPreAddSeparator(UBYTE *s)
5475 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5476 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5477 for(;*s !=
'\0';s++){
5478 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5485 set_set(*s,AC.separators);
5498int DoPreRmSeparator(UBYTE *s)
5500 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5501 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5502 for(;*s !=
'\0';s++){
5503 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5504 set_del(*s,AC.separators);
5515int DoExternal(UBYTE *s)
5517#ifdef WITHEXTERNALCHANNEL
5523 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5524 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5525 if ( AP.preError )
return(0);
5527#ifdef WITHEXTERNALCHANNEL
5528 while ( *s ==
' ' || *s ==
'\t' ) s++;
5532 if ( chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5534 MesPrint(
"@Can't finde closing \"");
5536 case 0:
case 1:
continue;
5541 MesPrint(
"@Illegal name of preprocessor variable to store external channel");
5545 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5549 MesPrint(
"@Illegal external command");
5555 externalD=openExternalChannel(
5563 Error1(
"Can't start external program",s);
5570 NumToStr(buf,externalD);
5571 if (
PutPreVar(prevar,buf,0,1) < 0 )
return(-1);
5574 AX.currentExternalChannel=externalD;
5576 if(AX.currentPrompt!=0){
5577 if(setTerminatorForExternalChannel( (
char *)AX.currentPrompt)){
5578 MesPrint(
"@Prompt is too long");
5582 setKillModeForExternalChannel(AX.killSignal,AX.killWholeGroup);
5586 Error0(
"External channel: not implemented on this computer/system");
5597int DoPrompt(UBYTE *s)
5599#ifndef WITHEXTERNALCHANNEL
5602 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5603 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5605#ifdef WITHEXTERNALCHANNEL
5606 while ( *s ==
' ' || *s ==
'\t' ) s++;
5607 if ( AX.currentPrompt )
5608 M_free(AX.currentPrompt,
"external channel prompt");
5610 AX.currentPrompt = (UBYTE *)strDup1((UBYTE *)
"",
"external channel prompt");
5612 AX.currentPrompt = strDup1(s,
"external channel prompt");
5613 if( setTerminatorForExternalChannel( (
char *)AX.currentPrompt) > 0 ){
5614 MesPrint(
"@Prompt is too long");
5620 Error0(
"External channel: not implemented on this computer/system");
5630int DoSetExternal(UBYTE *s)
5632#ifdef WITHEXTERNALCHANNEL
5637 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5638 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5639 if ( AP.preError )
return(0);
5641#ifdef WITHEXTERNALCHANNEL
5642 while ( *s ==
' ' || *s ==
'\t' ) s++;
5643 while ( chartype[*s] == 1 ) { n = 10*n + *s++ -
'0'; }
5644 while ( *s ==
' ' || *s ==
'\t' ) s++;
5646 MesPrint(
"@setexternal: number expected");
5649 if(selectExternalChannel(n)<0){
5650 MesPrint(
"@setexternal: invalid number");
5653 AX.currentExternalChannel=n;
5656 Error0(
"External channel: not implemented on this computer/system");
5665static FORM_INLINE UBYTE *pickupword(UBYTE *s)
5668 for(;*s>
' ';s++)
switch(*s){
5679static inline int strINCmp(UBYTE *a, UBYTE *b,
int n)
5681 for(;n>0;n--)
if(tolower(*a++)!=tolower(*b++))
5687#define KILLALL "killall"
5688#define DAEMON "daemon"
5689#define SHELL "shell"
5690#define STDERR "stderr"
5692#define TRUE_EXPR "true"
5693#define FALSE_EXPR "false"
5694#define NOSHELL "noshell"
5695#define TERMINAL "terminal"
5700int DoSetExternalAttr(UBYTE *s)
5702#ifdef WITHEXTERNALCHANNEL
5708 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5709 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5710 if ( AP.preError )
return(0);
5712#ifdef WITHEXTERNALCHANNEL
5715 while ( *s ==
' ' || *s ==
'\t' ) s++;
5716 s=pickupword(nam=s);
5718 while ( *s ==
' ' || *s ==
'\t' ) s++;
5720 MesPrint(
"@External channel:'=' expected instead of %s",s-1);
5724 while ( *s ==
' ' || *s ==
'\t' ) s++;
5731 while ( *s ==
' ' || *s ==
'\t' ) s++;
5732 if( (*s ==
',')||(*s ==
'\n')||(*s ==
';')||(*s ==
'\0') ){
5739 while ( *s ==
' ' || *s ==
'\t' ) s++;
5741 if(strINCmp((UBYTE *)SHELL,nam,lnam)==0){
5742 if(AX.shellname!=NULL)
5743 M_free(AX.shellname,
"external channel shellname");
5744 if(strINCmp((UBYTE *)NOSHELL,val,lval)==0)
5748 b=ch=AX.shellname=Malloc1(lval+1,
"external channel shellname");
5753 }
else if(strINCmp((UBYTE *)DAEMON,nam,lnam)==0){
5754 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5756 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5759 MesPrint(
"@External channel:true or false expected for %s",DAEMON);
5762 }
else if(strINCmp((UBYTE *)KILLALL,nam,lnam)==0){
5763 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5764 AX.killWholeGroup = 1;
5765 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5766 AX.killWholeGroup = 0;
5768 MesPrint(
"@External channel: true or false expected for %s",KILLALL);
5771 }
else if(strINCmp((UBYTE *)KILL,nam,lnam)==0){
5773 for(i=0;i<lval;i++) {
5774 if( *val>=
'0' && *val<=
'9' )
5775 n = 10*n + *val++ -
'0';
5777 MesPrint(
"@External channel: number expected for %s",KILL);
5782 }
else if(strINCmp((UBYTE *)STDERR,nam,lnam)==0){
5783 if( AX.stderrname != NULL ) {
5784 M_free(AX.stderrname,
"external channel stderrname");
5786 if(strINCmp((UBYTE *)TERMINAL,val,lval)==0)
5787 AX.stderrname = NULL;
5790 b=ch=AX.stderrname=Malloc1(lval+1,
"external channel stderrname");
5797 MesPrint(
"@External channel: unrecognized attribute",nam);
5800 }
while(*s++ ==
',');
5801 if( (*(s-1)>
' ')&&(*(s-1)!=
';') ){
5802 MesPrint(
"@External channel: syntax error: %s",s-1);
5807 Error0(
"External channel: not implemented on this computer/system");
5817int DoRmExternal(UBYTE *s)
5819#ifdef WITHEXTERNALCHANNEL
5824 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5825 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5826 if ( AP.preError )
return(0);
5828#ifdef WITHEXTERNALCHANNEL
5829 while ( *s ==
' ' || *s ==
'\t' ) s++;
5830 if( chartype[*s] == 1 ){
5831 for(n=0; chartype[*s] == 1 ; s++) { n = 10*n + *s -
'0'; }
5832 while ( *s ==
' ' || *s ==
'\t' ) s++;
5835 MesPrint(
"@rmexternal: invalid number");
5840 closeAllExternalChannels();
5841 AX.currentExternalChannel=0;
5845 n=AX.currentExternalChannel;
5848 closeExternalChannel(n);
5850 if (n == AX.currentExternalChannel)
5851 AX.currentExternalChannel=0;
5854 Error0(
"External channel: not implemented on this computer/system");
5882int DoFromExternal(UBYTE *s)
5884#ifdef WITHEXTERNALCHANNEL
5887 int withNoList=AC.NoShowInput;
5888 int oldpreassignflag;
5892 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5893 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5894 if ( AP.preError )
return(0);
5895#ifdef WITHEXTERNALCHANNEL
5899 while ( *s ==
' ' || *s ==
'\t' ) s++;
5901 if ( *s ==
'-' || *s ==
'+' ) {
5907 while ( *s ==
' ' || *s ==
'\t' ) s++;
5914 if ( *s==
'$' || chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5916 MesPrint(
"@Can't finde closing \"");
5918 case 0:
case 1:
continue;
5923 MesPrint(
"@Illegal name to store output of external channel");
5927 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5931 if( chartype[*s] == 1 ){
5932 for(lbuf=0; chartype[*s] == 1 ; s++) { lbuf = 10*lbuf + *s -
'0'; }
5933 while ( *s ==
' ' || *s ==
'\t' ) s++;
5935 if( (*s!=
'\0')||(lbuf<0) ){
5936 MesPrint(
"@Illegal buffer length in fromexternal");
5941 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5944 if(selectExternalChannel(AX.currentExternalChannel)){
5945 MesPrint(
"@No current external channel");
5956 buf=Malloc1( (lbuf=255)+1,
"Fromexternal");
5962 for(i=0;(cc=getcFromExtChannel())>0;i++){
5966 UBYTE *tmp=Malloc1( (lbuf*=2)+1,
"Fromexternal");
5967 for(j=0;j<i;j++)tmp[j]=buf[j];
5968 M_free(buf,
"Fromexternal");
5975 MesPrint(
"@No current external channel");
5983 buf=Malloc1(lbuf+1,
"Fromexternal");
5984 for(i=0; i<lbuf;i++){
5990 if( (cc=getcFromExtChannel())<1 )
6003 while(getcFromExtChannel()>0);
6005 MesPrint(
"@No current external channel");
6012 int oldNumPotModdollars = NumPotModdollars;
6014 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
6015 AC.RhsExprInModuleFlag = 0;
6019 UBYTE *pbuf=Malloc1(StrLen(prevar)+1+lbuf+1,
"Fromexternal to dollar");
6022 while(*b!=
'\0'){*c++ = *b++;}
6025 while( (*c++=*b++)!=
'\0' );
6026 oldpreassignflag = AP.PreAssignFlag;
6027 AP.PreAssignFlag = 1;
6028 if ( ( cc = CompileStatement(pbuf) ) || ( cc = CatchDollar(0) ) ) {
6029 Error1(
"External channel: can't asign output to dollar variable ",prevar);
6031 AP.PreAssignFlag = oldpreassignflag;
6032 NumPotModdollars = oldNumPotModdollars;
6034 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
6036 M_free(pbuf,
"Fromexternal to dollar");
6041 M_free(buf,
"Fromexternal");
6042 if ( cc )
return(-1);
6046 if ( OpenStream(s,EXTERNALCHANNELSTREAM,0,PRENOACTION) == 0 )
return(-1);
6048 AC.NoShowInput = withNoList;
6052 Error0(
"External channel: not implemented on this computer/system");
6063#ifdef WITHEXTERNALCHANNEL
6066LONG WriteToExternalChannel(
int handle, UBYTE *buffer, LONG size)
6071 if(writeBufToExtChannel((
char*)buffer,size))
6077int DoToExternal(UBYTE *s)
6079#ifdef WITHEXTERNALCHANNEL
6081 LONG (*OldWrite)(
int handle, UBYTE *buffer, LONG size) = WriteFile;
6086 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6087 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6088 if ( AP.preError )
return(0);
6089#ifdef WITHEXTERNALCHANNEL
6091 h.oldsilent=AM.silent;
6092 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
6093 h.newhandle = h.oldhandle = AC.LogHandle;
6094 h.oldprinttype = AO.PrintType;
6096 WriteFile=&WriteToExternalChannel;
6098 while ( *s ==
' ' || *s ==
'\t' ) s++;
6100 if(AX.currentExternalChannel==0){
6101 MesPrint(
"@No current external channel");
6102 goto DoToExternalReady;
6105 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
6106 selectExternalChannel(AX.currentExternalChannel);
6108 ret=writeToChannel(EXTERNALCHANNELOUT,s,&h);
6113 Error0(
"External channel: not implemented on this computer/system");
6124UBYTE *defineChannel(UBYTE *s,
HANDLERS *h)
6133 while ( *s && *s !=
'>' ) {
6134 if ( *s ==
'\\' ) s++;
6138 MesPrint(
"@Improper termination of filename");
6144 h->newhandle = GetChannel((
char *)name,0);
6147 else if ( AC.LogHandle >= 0 ) {
6148 h->newhandle = AC.LogHandle;
6159int writeToChannel(
int wtype, UBYTE *s,
HANDLERS *h)
6161 UBYTE *to, *fstring, *ss, *sss, *s1, c, c1;
6162 WORD num, number, nfac;
6163 WORD oldOptimizationLevel;
6164 UBYTE Out[MAXLINELENGTH+14], *stopper;
6171 while ( *s ==
',' || *s ==
' ' ) s++;
6173 MesPrint(
"@No format string present");
6176 s++; fstring = to = s;
6182 if ( *s ==
'\\' ) *to++ = *s++;
6184 else if ( *s ==
'"' ) *to++ = *s++;
6185 else { *to++ =
'\\'; *to++ = *s++; }
6187 else if ( *s ==
'"' )
break;
6191 MesPrint(
"@No closing \" in format string");
6195 if ( AC.LineLength > 20 && AC.LineLength <= MAXLINELENGTH ) stopper = Out + AC.LineLength;
6196 else stopper = Out + MAXLINELENGTH;
6203 AC.LogHandle = h->newhandle;
6204 AM.FileOnlyFlag = h->newlogonly;
6205 if ( h->newhandle >= 0 ) {
6206 AO.PrintType |= PRINTLFILE;
6208 while ( *fstring ) {
6209 if ( to >= stopper ) {
6210 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6214 WriteString(wtype,Out,num);
6216 if ( AC.OutputMode == FORTRANMODE
6217 || AC.OutputMode == PFORTRANMODE ) {
6219 for ( i = 0; i < number; i++ ) *to++ =
' ';
6223 if ( *fstring ==
'\\' ) {
6225 if ( *fstring ==
'n' ) {
6227 WriteString(wtype,Out,num);
6231 else if ( *fstring ==
't' ) { *to++ =
'\t'; fstring++; }
6232 else if ( *fstring ==
'b' ) { *to++ =
'\\'; fstring++; }
6233 else *to++ = *fstring++;
6235 else if ( *fstring ==
'%' ) {
6239 if ( *fstring ==
'd' ) {
6243 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6245 while ( *s ==
'+' || *s ==
'-' ) {
6246 if ( *s ==
'-' ) sign = -sign;
6249 dig = 0; ss = s;
if ( sign < 0 ) { ss--; *ss =
'-'; dig++; }
6250 while ( *s >=
'0' && *s <=
'9' ) { s++; dig++; }
6253 if ( to >= stopper ) {
6255 WriteString(wtype,Out,num);
6258 if ( *ss ==
'\\' ) ss++;
6263 if ( number < dig ) { dig = number; ss = s - dig; }
6264 while ( number > dig ) {
6265 if ( to >= stopper ) {
6267 WriteString(wtype,Out,num);
6270 *to++ =
' '; number--;
6273 if ( to >= stopper ) {
6275 WriteString(wtype,Out,num);
6278 if ( *ss ==
'\\' ) ss++;
6284 else if ( *fstring ==
'$' ) {
6286 number = AO.OutSkip;
6288 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6289 if ( AC.OutputMode == FORTRANMODE
6290 || AC.OutputMode == PFORTRANMODE ) {
6294nodollar: MesPrint(
"@$-variable expected in #write instruction");
6295 AM.FileOnlyFlag = h->oldlogonly;
6296 AC.LogHandle = h->oldhandle;
6297 AO.PrintType = h->oldprinttype;
6298 AM.silent = h->oldsilent;
6302 while ( chartype[*s] <= 1 ) s++;
6303 if ( s == ss )
goto nodollar;
6305 num = GetDollar(ss);
6307 MesPrint(
"@#write instruction: $%s has not been defined",ss);
6308 AM.FileOnlyFlag = h->oldlogonly;
6309 AC.LogHandle = h->oldhandle;
6310 AO.PrintType = h->oldprinttype;
6311 AM.silent = h->oldsilent;
6316 if ( Dollars[num].nfactors <= 0 ) {
6318 MesPrint(
"@#write instruction: $%s has not been factorized",ss);
6319 AM.FileOnlyFlag = h->oldlogonly;
6320 AC.LogHandle = h->oldhandle;
6321 AO.PrintType = h->oldprinttype;
6322 AM.silent = h->oldsilent;
6328 nfac = GetDollarNumber(&s,Dollars+num);
6330 if ( Dollars[num].nfactors == 1 && nfac == 1 )
goto writewhole;
6332 if ( ( dolalloc = WriteDollarFactorToBuffer(num,nfac,0) ) == 0 ) {
6333 AM.FileOnlyFlag = h->oldlogonly;
6334 AC.LogHandle = h->oldhandle;
6335 AO.PrintType = h->oldprinttype;
6336 AM.silent = h->oldsilent;
6341 else if ( *s && *s !=
' ' && *s !=
',' && *s !=
'\t' ) {
6342 MesPrint(
"@#write instruction: illegal characters after $-variable");
6343 AM.FileOnlyFlag = h->oldlogonly;
6344 AC.LogHandle = h->oldhandle;
6345 AO.PrintType = h->oldprinttype;
6346 AM.silent = h->oldsilent;
6351 if ( ( dolalloc = WriteDollarToBuffer(num,0) ) == 0 ) {
6352 AM.FileOnlyFlag = h->oldlogonly;
6353 AC.LogHandle = h->oldhandle;
6354 AO.PrintType = h->oldprinttype;
6355 AM.silent = h->oldsilent;
6362 if ( to >= stopper ) {
6363 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6367 WriteString(wtype,Out,num);
6369 for ( i = 0; i < number; i++ ) *to++ =
' ';
6370 if ( AC.OutputMode == FORTRANMODE
6371 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6373 if ( chartype[*ss] > 3 ) { *to++ = *ss++; }
6375 sss = ss;
while ( chartype[*ss] <= 3 ) ss++;
6376 if ( ( to + (ss-sss) ) >= stopper ) {
6377 if ( (ss-sss) >= (stopper-Out) ) {
6378 if ( ( to - stopper ) < 10 ) {
6379 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6383 WriteString(wtype,Out,num);
6385 for ( i = 0; i < number; i++ ) *to++ =
' ';
6386 if ( AC.OutputMode == FORTRANMODE
6387 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6389 while ( (ss-sss) >= (stopper-Out) ) {
6390 while ( to < stopper-1 ) {
6393 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6400 WriteString(wtype,Out,num);
6402 if ( AC.OutputMode == FORTRANMODE
6403 || AC.OutputMode == PFORTRANMODE ) {
6404 for ( i = 0; i < number; i++ ) *to++ =
' ';
6410 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6414 WriteString(wtype,Out,num);
6416 for ( i = 0; i < number; i++ ) *to++ =
' ';
6417 if ( AC.OutputMode == FORTRANMODE
6418 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6421 while ( sss < ss ) *to++ = *sss++;
6425 M_free(dolalloc,
"written dollar");
6429 else if ( *fstring ==
's' ) {
6431 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6435 if ( *s ==
'\\' ) s++;
6436 else if ( *s ==
'"' )
break;
6440 MesPrint(
"@#write instruction: Missing \" in string");
6441 AM.FileOnlyFlag = h->oldlogonly;
6442 AC.LogHandle = h->oldhandle;
6443 AO.PrintType = h->oldprinttype;
6444 AM.silent = h->oldsilent;
6448 if ( to >= stopper ) {
6450 WriteString(wtype,Out,num);
6453 if ( *ss ==
'\\' ) ss++;
6460 while ( *s && *s !=
',' ) {
6461 if ( *s ==
'\\' ) { s++; sss = s+1; }
6464 while ( s > sss+1 && ( s[-1] ==
' ' || s[-1] ==
'\t' ) ) s--;
6466 if ( to >= stopper ) {
6468 WriteString(wtype,Out,num);
6471 if ( *ss ==
'\\' ) ss++;
6476 else if ( *fstring ==
'X' ) {
6478 if ( cbuf[AM.sbufnum].numrhs > 0 ) {
6482 UBYTE *s = GetPreVar(AM.oldnumextrasymbols,0);
6484 while ( *s >=
'0' && *s <=
'9' ) x = 10*x + *s++ -
'0';
6486 PrintSubtermList(1,x);
6488 PrintSubtermList(1,cbuf[AM.sbufnum].numrhs);
6491 else if ( *fstring ==
'O' ) {
6492 number = AO.OutSkip;
6498 if ( AO.OptimizeResult.code == NULL && AO.OptimizationLevel != 0 ) {
6499 MesPrint(
"@In #write instruction: no optimization results available!");
6503 WriteString(wtype,Out,num);
6505 if ( AO.OptimizationLevel != 0 ) {
6506 WORD oldoutskip = AO.OutSkip;
6507 AO.OutSkip = number;
6509 AO.OutSkip = oldoutskip;
6512 else if ( *fstring ==
'e' || *fstring ==
'E' ) {
6513 if ( *fstring ==
'E'
6514 || AC.OutputMode == FORTRANMODE
6515 || AC.OutputMode == PFORTRANMODE ) nosemi = 1;
6518 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6519 if ( chartype[*s] != 0 && *s !=
'[' ) {
6520noexpr: MesPrint(
"@expression name expected in #write instruction");
6521 AM.FileOnlyFlag = h->oldlogonly;
6522 AC.LogHandle = h->oldhandle;
6523 AO.PrintType = h->oldprinttype;
6524 AM.silent = h->oldsilent;
6528 if ( ( s =
SkipAName(ss) ) == 0 || s[-1] ==
'_' )
goto noexpr;
6529 s1 = s; c = c1 = *s1;
6533 AO.CurBufWrt = s1+1;
6537 MesPrint(
"@Illegal () specifier in expression name in #write");
6538 AM.FileOnlyFlag = h->oldlogonly;
6539 AC.LogHandle = h->oldhandle;
6540 AO.PrintType = h->oldprinttype;
6541 AM.silent = h->oldsilent;
6545 else AO.CurBufWrt = (UBYTE *)underscore;
6548 if ( num > 0 ) WriteUnfinString(wtype,Out,num);
6550 oldOptimizationLevel = AO.OptimizationLevel;
6551 AO.OptimizationLevel = 0;
6552 if ( WriteOne(ss,(
int)num,nosemi,plus) < 0 ) {
6553 AM.FileOnlyFlag = h->oldlogonly;
6554 AC.LogHandle = h->oldhandle;
6555 AO.PrintType = h->oldprinttype;
6556 AM.silent = h->oldsilent;
6559 AO.OptimizationLevel = oldOptimizationLevel;
6561 if ( s > s1 ) *s++ = c;
6566 else if ( ( *fstring ==
'f' ) || ( *fstring ==
'F' ) ) {
6568 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6570 while ( *s && *s !=
',' ) {
6571 if ( *s ==
'\\' ) s++;
6575 s1 = LoadInputFile(ss,HEADERFILE);
6582 ss = s1;
while ( *ss ) ss++;
6584 WriteString(wtype,s1,n);
6585 M_free(s1,
"copy file");
6587 else if ( *fstring ==
'F' ) {
6589 MesPrint(
"@Error in #write: could not open file %s",ss);
6591 goto ReturnWithError;
6595 else if ( *fstring ==
'%' ) {
6598 else if ( FG.cTable[*fstring] == 1 ) {
6600 while ( FG.cTable[*fstring] == 1 ) {
6601 number = 10*number + *fstring++ -
'0';
6603 if ( *fstring ==
'O' )
goto dooptim;
6604 else if ( *fstring ==
'd' )
goto donumber;
6605 else if ( *fstring ==
'$' )
goto dodollar;
6606 else if ( *fstring ==
't' ) {
6607 if ( number < (WORD)(stopper-Out) ) {
6608 while ( (WORD)(to-Out) < number ) *to++ =
' ';
6612 else if ( *fstring ==
'X' || *fstring ==
'x' ) {
6613 if ( number > 0 && number <= cbuf[AM.sbufnum].numrhs ) {
6614 UBYTE buffer[80], *out, *old1, *old2, *old3;
6616 if ( *fstring ==
'X' ) {
6617 out = StrCopy((UBYTE *)AC.extrasym,buffer);
6618 if ( AC.extrasymbols == 0 ) {
6619 out = NumCopy(number,out);
6620 out = StrCopy((UBYTE *)
"_",out);
6622 else if ( AC.extrasymbols == 1 ) {
6623 if ( AC.OutputMode == CMODE ) {
6624 out = StrCopy((UBYTE *)
"[",out);
6625 out = NumCopy(number,out);
6626 out = StrCopy((UBYTE *)
"]",out);
6629 out = StrCopy((UBYTE *)
"(",out);
6630 out = NumCopy(number,out);
6631 out = StrCopy((UBYTE *)
")",out);
6634 out = StrCopy((UBYTE *)
"=",out);
6636 while ( ss < out ) {
6637 if ( to >= stopper ) {
6639 WriteString(wtype,Out,num);
6645 term = cbuf[AM.sbufnum].rhs[number];
6652 old2 = AO.OutputLine;
6655 AO.OutputLine = Out;
6656 AO.OutStop = Out + AC.LineLength;
6658 if ( WriteInnerTerm(term,first) ) Terminate(-1);
6662 to = Out + (AO.OutFill-AO.OutputLine);
6664 AO.OutputLine = old2;
6671 goto IllegControlSequence;
6674 else if ( *fstring ==
'+' ) {
6675 plus = 1;
goto retry;
6677 else if ( *fstring == 0 ) {
6681IllegControlSequence:
6682 MesPrint(
"@Illegal control sequence in format string in #write instruction");
6684 AM.FileOnlyFlag = h->oldlogonly;
6685 AC.LogHandle = h->oldhandle;
6686 AO.PrintType = h->oldprinttype;
6687 AM.silent = h->oldsilent;
6700 if(wtype==EXTERNALCHANNELOUT){
6702 WriteUnfinString(wtype,Out,num);
6705 WriteString(wtype,Out,num);
6709 AM.FileOnlyFlag = h->oldlogonly;
6710 AC.LogHandle = h->oldhandle;
6711 AO.PrintType = h->oldprinttype;
6712 AM.silent = h->oldsilent;
6724int DoFactDollar(UBYTE *s)
6727 WORD numdollar, *oldworkpointer;
6729 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6730 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6731 while ( *s ==
' ' || *s ==
'\t' ) s++;
6733 if ( GetName(AC.dollarnames,s+1,&numdollar,NOAUTO) != CDOLLAR ) {
6734 MesPrint(
"@%s is undefined",s);
6739 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6743 oldworkpointer = AT.WorkPointer;
6744 if ( DollarFactorize(BHEAD numdollar) )
return(-1);
6745 AT.WorkPointer = oldworkpointer;
6749 else if ( ParenthesesTest(s) )
return(-1);
6751 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6761WORD GetDollarNumber(UBYTE **inp,
DOLLARS d)
6763 UBYTE *s = *inp, c, *name;
6764 WORD number, nfac, *w;
6769 while ( FG.cTable[*s] < 2 ) s++;
6771 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6772 MesPrint(
"@dollar in #write should have been defined previously");
6776 dd = Dollars + number;
6779 nfac = GetDollarNumber(inp,dd);
6782 MesPrint(
"@Illegal factor for dollar variable");
6787 if ( dd->nfactors > d->nfactors ) {
6789 MesPrint(
"@Factor number for dollar variable too large");
6792 return(dd->nfactors);
6794 w = dd->factors[nfac-1].where;
6796 if ( dd->factors[nfac-1].value > d->nfactors ||
6797 dd->factors[nfac-1].value < 0 )
goto TooBig;
6798 return(dd->factors[nfac-1].value);
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;
6804 MesPrint(
"@Illegal factor number for dollar variable");
6808 if ( dd->type == DOLZERO ) {
6811 else if ( dd->type == DOLTERMS || dd->type == DOLNUMBER ) {
6813 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6814 && w[1] <= d->nfactors )
return(w[1]);
6815 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6821 else if ( FG.cTable[*s] == 1 ) {
6822 WORD x = *s++ -
'0';
6823 while ( FG.cTable[*s] == 1 ) {
6824 x = 10*x + *s++ -
'0';
6825 if ( x > d->nfactors ) {
6826 MesPrint(
"@Factor number %d for dollar variable too large",x);
6831 MesPrint(
"@Illegal factor number for dollar variable");
6838 MesPrint(
"@Illegal factor indicator for dollar variable");
6851int DoSetRandom(UBYTE *s)
6854 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6855 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6856 while ( *s ==
' ' || *s ==
'\t' ) s++;
6858 while ( FG.cTable[*s] == 1 ) {
6859 x = 10*x + (*s++-
'0');
6861 while ( *s ==
' ' || *s ==
'\t' ) s++;
6865 int id, totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
6867 int id, totnum = AM.totalnumberofthreads;
6869 for (
id = 0;
id < totnum;
id++ ) {
6870 AB[id]->R.wranfseed = x;
6871 if ( AB[
id]->R.wranfia ) M_free(AB[
id]->R.wranfia,
"wranf");
6872 AB[id]->R.wranfia = 0;
6876 if ( AR.wranfia ) M_free(AR.wranfia,
"wranf");
6882 MesPrint(
"@proper syntax is #SetRandom number");
6894int DoOptimize(UBYTE *s)
6900 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6901 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6904 if ( *s != 0 && *s !=
';' ) {
6905 MesPrint(
"@proper syntax is #Optimize,expression");
6909 if ( GetName(AC.exprnames,exprname,&numexpr,NOAUTO) != CEXPRESSION ) {
6910 MesPrint(
"@%s is not an expression",exprname);
6913 else if ( AP.preError == 0 ) {
6917 WORD *term = AT.WorkPointer;
6919 if ( AO.OptimizationLevel == 0 )
return(0);
6920 switch ( e->status ) {
6921 case LOCALEXPRESSION:
6922 case GLOBALEXPRESSION:
6925 MesPrint(
"@Expression %s is not an active unhidden local or global expression.",exprname);
6930 if ( PF.me == MASTER )
6933 for ( i = NumExpressions-1; i >= 0; i-- ) {
6934 AS.OldOnFile[i] = Expressions[i].onfile;
6935 AS.OldNumFactors[i] = Expressions[i].numfactors;
6936 AS.Oldvflags[i] = Expressions[i].vflags;
6937 Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
6939 for ( i = 0; i < NumExpressions; i++ ) {
6940 if ( i == numexpr ) {
6942 GetPreVar((UBYTE *)
"EXTRASYMBOLS_",0),0,1);
6944 AO.OptimizeResult.nameofexpr = strDup1(exprname,
"optimize expression name");
6948 if ( PF.me == MASTER ) {
6950 e = Expressions + i;
6951 switch ( e->status ) {
6952 case LOCALEXPRESSION:
6953 case SKIPLEXPRESSION:
6954 case DROPLEXPRESSION:
6955 case DROPPEDEXPRESSION:
6956 case GLOBALEXPRESSION:
6957 case SKIPGEXPRESSION:
6958 case DROPGEXPRESSION:
6959 case HIDELEXPRESSION:
6960 case HIDEGEXPRESSION:
6961 case DROPHLEXPRESSION:
6962 case DROPHGEXPRESSION:
6963 case INTOHIDELEXPRESSION:
6964 case INTOHIDEGEXPRESSION:
6970 SetScratch(AR.infile,&(e->onfile));
6971 if ( GetTerm(BHEAD term) <= 0 ) {
6973 MesPrint(
"!>Expression %d has problems reading from scratchfile",i);
6979 SeekScratch(AR.outfile,&position);
6980 e->onfile = position;
6981 *AM.S0->sBuffer = 0; firstterm = -1;
6983 WORD *oldipointer = AR.CompressPointer;
6984 WORD *comprtop = AR.ComprTop;
6985 AR.ComprTop = AM.S0->sTop;
6986 AR.CompressPointer = AM.S0->sBuffer;
6987 if ( firstterm > 0 ) {
6988 if (
PutOut(BHEAD term,&position,AR.outfile,1) < 0 )
goto DoSerr;
6990 else if ( firstterm < 0 ) {
6991 if (
PutOut(BHEAD term,&position,AR.outfile,0) < 0 )
goto DoSerr;
6995 if (
PutOut(BHEAD term,&position,AR.outfile,-1) < 0 )
goto DoSerr;
6998 AR.CompressPointer = oldipointer;
6999 AR.ComprTop = comprtop;
7000 }
while ( GetTerm(BHEAD term) );
7001 if (
FlushOut(&position,AR.outfile,1) ) {
7004 MesPrint(
"!>Expression %d has problems writing to scratchfile",i);
7031int DoClearOptimize(UBYTE *s)
7033 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7034 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7051int DoSkipExtraSymbols(UBYTE *s)
7053 CBUF *C = cbuf + AM.sbufnum;
7054 WORD tt = 0, j = 0, oldval = AO.OptimizeResult.minvar;
7055 if ( AO.OptimizeResult.code == NULL )
return(0);
7056 if ( AO.OptimizationLevel == 0 )
return(0);
7057 while ( *s ==
',' ) s++;
7059 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
7062 while ( *s <=
'9' && *s >=
'0' ) j = 10*j + *s++ -
'0';
7064 MesPrint(
"@Illegal use of #SkipExtraSymbols instruction");
7067 AO.OptimizeResult.minvar += j;
7068 if ( AO.OptimizeResult.minvar > AO.OptimizeResult.maxvar )
7069 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
7071 j = AO.OptimizeResult.minvar - oldval;
7076 InsTree(AM.sbufnum,C->numrhs);
7090int DoPreReset(UBYTE *s)
7093 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7094 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7095 while ( *s ==
' ' || *s ==
'\t' ) s++;
7097 MesPrint(
"@proper syntax is #Reset variable");
7101 while ( FG.cTable[*s] == 0 ) s++;
7103 if ( ( StrICmp(ss,(UBYTE *)
"timer") == 0 )
7104 || ( StrICmp(ss,(UBYTE *)
"stopwatch") == 0 ) ) {
7106 AP.StopWatchZero = GetRunningTime();
7111 MesPrint(
"@proper syntax is #Reset variable");
7121static int DoAddPath(UBYTE *s,
int bPrepend)
7125 UBYTE *path, *path_end, *current_dir, *current_dir_end, *NewPath, *t;
7128 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7129 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7132 while ( *s ==
' ' || *s ==
'\t' ) s++;
7135 while ( *s && *s !=
'"' ) {
7136 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
7137 if ( !s[1] )
goto ImproperPath;
7142 if ( *s !=
'"' )
goto ImproperPath;
7147 while ( *s && *s !=
' ' && *s !=
'\t' ) {
7148 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
7149 if ( !s[1] )
goto ImproperPath;
7156 if ( path == path_end )
goto ImproperPath;
7157 while ( *s ==
' ' || *s ==
'\t' ) s++;
7158 if ( *s )
goto ImproperPath;
7162 if ( path[0] == SEPARATOR ) {
7166 else if ( chartype[path[0]] == 0 && path[1] ==
':' ) {
7173 if ( !AC.CurrentStream )
goto FileNameUnavailable;
7174 if ( AC.CurrentStream->type != FILESTREAM && AC.CurrentStream->type != REVERSEFILESTREAM )
goto FileNameUnavailable;
7175 if ( !AC.CurrentStream->name )
goto FileNameUnavailable;
7176 s = current_dir = current_dir_end = AC.CurrentStream->name;
7178 if ( SEPARATOR !=
'\\' && *s ==
'\\' && s[1] ) {
7182 if ( *s == SEPARATOR ) {
7183 current_dir_end = s;
7189 current_dir = current_dir_end = NULL;
7193 n = path_end - path;
7194 if ( AM.Path ) n += StrLen(AM.Path) + 1;
7195 if ( current_dir != current_dir_end ) n+= current_dir_end - current_dir + 1;
7196 s = NewPath = (UBYTE *)Malloc1(n + 1,
"add path");
7200 if ( current_dir != current_dir_end ) {
7202 while ( t != current_dir_end ) *s++ = *t++;
7206 while ( t != path_end ) *s++ = *t++;
7207 if ( AM.Path ) *s++ = PATHSEPARATOR;
7211 while ( *t ) *s++ = *t++;
7214 if ( AM.Path ) *s++ = PATHSEPARATOR;
7215 if ( current_dir != current_dir_end ) {
7217 while ( t != current_dir_end ) *s++ = *t++;
7221 while ( t != path_end ) *s++ = *t++;
7226 if ( AM.Path ) M_free(AM.Path,
"add path");
7232 MesPrint(
"@Improper syntax for %#%sPath", bPrepend ?
"Prepend" :
"Append");
7237 MesPrint(
"@Sorry, %#%sPath can't resolve the current file name from here", bPrepend ?
"Prepend" :
"Append");
7250 return DoAddPath(s, 0);
7267 return DoAddPath(s, 1);
7277int DoTimeOutAfter(UBYTE *s)
7284 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7285 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7287 while ( *s ==
' ' || *s ==
'\t' ) s++;
7289 while ( FG.cTable[*s] == 1 ) {
7290 x = 10*x + (*s++-
'0');
7292 while ( *s ==
' ' || *s ==
'\t' ) s++;
7298 MesPrint(
"@proper syntax is #TimeoutAfter number");
7302 Error0(
"#timeoutafter not implemented on this computer/system");
7329int DoNamespace(UBYTE *s)
7333 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7334 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7335 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7336 if ( FG.cTable[*s] != 0 ) {
7337 MesPrint(
"@Illegal name in #namespace instruction: %s",s);
7341 while ( FG.cTable[*s1] <= 1 ) s1++;
7343 while ( *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' ) s2++;
7345 MesPrint(
"@A #namespace instruction can only have one name with only alphanumeric characters.");
7354 namespace->name = strDup1(s,
"namespace_name");
7355 namespace->usenames = MakeNameTree();
7356 if ( AP.firstnamespace == 0 ) {
7357 namespace->previous = 0;
7358 namespace->next = 0;
7359 AP.firstnamespace =
namespace;
7360 AP.lastnamespace =
namespace;
7363 AP.lastnamespace->next =
namespace;
7364 namespace->next = 0;
7365 namespace->previous = AP.lastnamespace;
7366 AP.lastnamespace =
namespace;
7377int DoEndNamespace(UBYTE *s)
7380 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7381 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7382 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7384 MesPrint(
"@Illegal #endnamespace instruction");
7387 namespace = AP.lastnamespace;
7388 AP.lastnamespace =
namespace->previous;
7389 M_free(namespace->name,
"namespace_name");
7390 FreeNameTree(namespace->usenames);
7391 M_free(
namespace,
"namespace");
7400UBYTE *SkipName(UBYTE *s)
7402 UBYTE *t = s, *s1, c;
7403 int num = 0, block = 0;
7408 MesPrint(
"&Illegal name: '%s'",t);
7412 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) s++;
7413 if ( s1 != s )
goto witherror;
7415 else if ( *s ==
'$' ) {
7417 while ( *s ==
'_' ) { s++; num++; }
7419 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7420 if ( FG.cTable[*s] != 0 && block == 1 ) {
7422 MesPrint(
"&Illegally formed name: %s",t);
7425 if ( *s ==
'_' ) { num++; block = 1; }
7429 if ( s[-1] ==
'_' && num > 1 )
goto built;
7431 else if ( FG.cTable[*s] == 0 ) {
7433 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7434 if ( FG.cTable[*s] != 0 && block == 1 )
goto blocked;
7435 if ( *s ==
'_' ) { block = 1; num++; }
7439 if ( *s ==
'[' )
goto straight;
7440 if ( s[-1] ==
'_' && num > 1 ) {
7443 MesPrint(
"&Built in objects cannot be part of namespaces: %s",t);
7448 else if ( *s ==
'_' ) {
7449 while ( *s ==
'_' ) { s++; num++; }
7450 if ( FG.cTable[*s] == 0 ) { block = 0;
goto regular; }
7453 else if ( *s ==
'@' ) {
7455 if ( *s ==
'_' || FG.cTable[*s] == 1 ) {
7456 MesPrint(
"@Illegally formed name: %s",s-1);
7460 else if ( *s ==
'#' ) {
7462 while ( *s ==
'_' ) { s++; num++; }
7464 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7465 if ( FG.cTable[*s] != 0 && block == 1 )
goto blocked;
7466 if ( *s ==
'_' ) { num++; block = 1; }
7470 if ( s[-1] ==
'_' ) {
7473 MesPrint(
"&Illegally formed name: %s",t);
7478 else if ( *s ==
'<' ) {
7480 while ( *s && *s !=
'>' ) s++;
7481 if ( *s !=
'>' )
goto witherror;
7500UBYTE *ConstructName(UBYTE *s,UBYTE type)
7506 if ( AP.lastnamespace == 0 )
return(s);
7507 if ( *s ==
'@' )
return(s+1);
7508 if ( GetName(AP.lastnamespace->usenames,s,&number,NOAUTO) !=
7509 NAMENOTFOUND )
return(s);
7514 len = StrLen(s) + 1;
7515 namespace = AP.firstnamespace;
7516 while (
namespace ) {
7517 len += StrLen(namespace->name)+1;
7518 namespace = namespace->previous;
7520 if ( len > AP.fullnamesize ) {
7521 while ( len > AP.fullnamesize ) AP.fullnamesize *= 2;
7522 M_free(AP.fullname,
"AP.fullname");
7523 AP.fullname = (UBYTE *)Malloc1(AP.fullnamesize*
sizeof(UBYTE *),
"AP.fullname");
7525 namespace = AP.firstnamespace;
7530 while (
namespace ) {
7531 u =
namespace->name;
7532 while ( *u ) *t++ = *u++;
7534 namespace = namespace->previous;
7536 while ( *s ) *t++ = *s++;
7542 while (
namespace ) {
7543 u =
namespace->name;
7544 while ( *u ) *t++ = *u++;
7546 namespace = namespace->previous;
7548 if ( type ==
'$' ) s++;
7549 while ( *s ) *t++ = *s++;
7553 while (
namespace ) {
7554 u =
namespace->name;
7555 while ( *u ) *t++ = *u++;
7557 namespace = namespace->previous;
7560 while ( *s ) *t++ = *s++;
7566 MesPrint(
"!>Unrecognized datatype in ConstructName");
7571 return(AP.fullname);
7599 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7600 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7601 if ( AP.lastnamespace == 0 ) {
7602 MesPrint(
"@It is not allowed to use #use outside the scope of a namespace.");
7605 namespace = AP.lastnamespace;
7606 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7609 if ( ( s = SkipName(t) ) == 0 )
return(-1);
7611 MesPrint(
"@Unrecognized object in #use instruction: %s",t);
7619 AddName(namespace->usenames,t,0,0,&number);
7621 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7642int UserFlags(UBYTE *s,
int par)
7644 int mask = 0, error = 0, i;
7645 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7646 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7647 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7650 for ( i = 0; i < NumExpressions; i++ ) {
7651 switch ( Expressions[i].status ) {
7652 case UNHIDELEXPRESSION:
7653 case UNHIDEGEXPRESSION:
7654 case INTOHIDELEXPRESSION:
7655 case INTOHIDEGEXPRESSION:
7656 case LOCALEXPRESSION:
7657 case GLOBALEXPRESSION:
7658 case SKIPLEXPRESSION:
7659 case SKIPGEXPRESSION:
7660 case HIDELEXPRESSION:
7661 case HIDEGEXPRESSION:
7662 if ( par == 1 ) Expressions[i].uflags |= ~mask;
7663 else Expressions[i].uflags &= mask;
7665 case DROPPEDEXPRESSION:
7666 case DROPLEXPRESSION:
7667 case DROPGEXPRESSION:
7668 case DROPHLEXPRESSION:
7669 case DROPHGEXPRESSION:
7670 case STOREDEXPRESSION:
7671 case HIDDENLEXPRESSION:
7672 case HIDDENGEXPRESSION:
7673 case SPECTATOREXPRESSION:
7679 else if ( FG.cTable[*s] == 1 ) {
7680 mask = (int)WORDMASK;
7681 while ( FG.cTable[*s] == 1 ) {
7683 while ( FG.cTable[*s] == 1 ) { x = 10*x + (*s++-
'0'); }
7684 if ( x < 1 || x > BITSINWORD ) {
7685 MesPrint(
"@Illegal number %d for flag in #...Flag instruction",x);
7689 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7691 if ( *s == 0 )
goto allexpr;
7694 mask = (int)WORDMASK;
7699 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
7702 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
7703 MesPrint(
"@%s is not an active expression",s1);
7707 switch ( Expressions[num1].status ) {
7708 case UNHIDELEXPRESSION:
7709 case UNHIDEGEXPRESSION:
7710 case INTOHIDELEXPRESSION:
7711 case INTOHIDEGEXPRESSION:
7712 case LOCALEXPRESSION:
7713 case GLOBALEXPRESSION:
7714 case SKIPLEXPRESSION:
7715 case SKIPGEXPRESSION:
7716 case HIDELEXPRESSION:
7717 case HIDEGEXPRESSION:
7718 if ( par == 1 ) Expressions[num1].uflags |= ~mask;
7719 else Expressions[num1].uflags &= mask;
7721 case DROPPEDEXPRESSION:
7722 case DROPLEXPRESSION:
7723 case DROPGEXPRESSION:
7724 case DROPHLEXPRESSION:
7725 case DROPHGEXPRESSION:
7726 case STOREDEXPRESSION:
7727 case HIDDENLEXPRESSION:
7728 case HIDDENGEXPRESSION:
7729 case SPECTATOREXPRESSION:
7731 MesPrint(
"@%s is not an active expression",s1);
7736 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7740 MesPrint(
"@Illegal name in #...Flag instruction.");
7749int DoClearUserFlag(UBYTE *s)
7751 return(UserFlags(s,0));
7759int DoSetUserFlag(UBYTE *s)
7761 return(UserFlags(s,1));
7775int DoStartFloat(UBYTE *s)
7781 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7782 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7783 if ( AR.PolyFun != 0 ) {
7784 MesPrint(
"@Simultaneous use of Poly(Rat)Fun and float_ is not allowed.");
7787 if ( AC.ncmod != 0 ) {
7788 MesPrint(
"@Simultaneous use of floating point and modulus arithmetic makes no sense.");
7795 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7800 if ( *s >=
'0' && *s <=
'9' ) {
7803 x = 10*x + (*s++-
'0');
7804 }
while ( *s >=
'0' && *s <=
'9' );
7809 if ( tolower(*s) ==
'd' ) { AC.tDefaultPrecision = (LONG)ceil(x*log2(10.0)); s++; }
7810 else if ( tolower(*s) ==
'b' ) { AC.tDefaultPrecision = x; s++; }
7812 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7817 if ( tolower(*s) ==
'm' && tolower(s[1]) ==
'z' && tolower(s[2]) ==
'v') {
7819 while ( *s ==
' ' || *s ==
'\t' ) s++;
7820 if ( *s !=
'=')
goto IllPar;
7822 while ( *s ==
' ' || *s ==
'\t' ) s++;
7823 if ( *s >=
'0' && *s <=
'9' ) {
7826 x = 10*x + (*s++ -
'0');
7827 }
while ( *s >=
'0' && *s <=
'9' );
7829 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7836 if ( *s )
goto IllPar;
7838 else if ( *s != 0 ) {
7840 MesPrint(
"@Illegal parameter in %#StartFloat: %s ",ss);
7844 if ( AC.tDefaultPrecision && ( AC.tDefaultPrecision != AC.DefaultPrecision
7845 || AT.aux_ == 0 ) ) {
7846 AC.DefaultPrecision = AC.tDefaultPrecision;
7847 AC.tDefaultPrecision = 0;
7849 if ( AC.tMaxWeight && ( AC.tMaxWeight != AC.MaxWeight
7850 || AT.aux_ == 0 ) ) {
7851 AC.MaxWeight = AC.tMaxWeight;
7854 SetFloatPrecision(AC.DefaultPrecision+AC.MaxWeight+1);
7856 if ( AC.MaxWeight > 0 ) SetupMZVTables();
7857 SetfFloatPrecision(AC.DefaultPrecision);
7860 AC.tDefaultPrecision = 0;
7873int DoEndFloat(UBYTE *s)
7876 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7877 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7878 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7880 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)