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);
2729 else MesPrint(
"!!!Internal error with procedure names: %s",name);
2738int DoDebug(UBYTE *s)
2741 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2742 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2743 NeedNumber(x,s,nonumber)
2744 if ( x < 0 || x >(PREPROONLY
2755 if ( ( x & PREPROONLY ) != 0 ) AP.PreDebug |= PREPROONLY;
2756 if ( ( x & DUMPTOCOMPILER ) != 0 ) AP.PreDebug |= DUMPTOCOMPILER;
2757 if ( ( x & DUMPOUTTERMS ) != 0 ) AP.PreDebug |= DUMPOUTTERMS;
2758 if ( ( x & DUMPINTERMS ) != 0 ) AP.PreDebug |= DUMPINTERMS;
2759 if ( ( x & DUMPTOSORT ) != 0 ) AP.PreDebug |= DUMPTOSORT;
2760 if ( ( x & DUMPTOPARALLEL ) != 0 ) AP.PreDebug |= DUMPTOPARALLEL;
2762 if ( ( x & THREADSDEBUG ) != 0 ) AP.PreDebug |= THREADSDEBUG;
2766 MesPrint(
"@Illegal argument for debug instruction");
2775int DoTerminate(UBYTE *s)
2778 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2779 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2781 NeedNumber(x,s,nonumber)
2789 MesPrint(
"@Illegal argument for terminate instruction");
2815 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2816 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2818 if ( NumDoLoops <= 0 ) {
2819 MesPrint(
"@%#continuedo without %#do");
2827 else if ( FG.cTable[*s] == 1 ) {
2828 ParseNumber(levels,s);
2830 if ( *s != 0 )
goto improper;
2834 MesPrint(
"@Improper syntax of %#continuedo instruction");
2838 if ( levels > NumDoLoops ) {
2839 MesPrint(
"@Too many loop levels requested in %#continuedo instruction");
2843 result = ExitDoLoops(levels-1,
"continuedo");
2844 if ( result != 0 )
return(result);
2846 if ( levels <= 0 )
return(0);
2848 if ( AC.CurrentStream->type == PREREADSTREAM3
2849 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
2850 MesPrint(
"@Trying to jump out of a procedure with a %#continuedo instruction");
2854 loop = &(DoLoops[NumDoLoops-1]);
2855 AP.NumPreTypes = loop->NumPreTypes+1;
2856 AP.PreIfLevel = loop->PreIfLevel;
2857 AP.PreSwitchLevel = loop->PreSwitchLevel;
2876 UBYTE *t, c, *u, *uu;
2879 LONG linenum = AC.CurrentStream->linenumber;
2880 int oldNoShowInput = AC.NoShowInput, i, oldpreassignflag;
2882 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
2883 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
2884 if ( PreSkip((UBYTE *)
"do",(UBYTE *)
"enddo",1) )
return(-1);
2892 AddToPreTypes(PRETYPEDO);
2894 loop = (
DOLOOP *)FromList(&AP.LoopList);
2895 loop->firstdollar = loop->lastdollar = loop->incdollar = -1;
2896 loop->NumPreTypes = AP.NumPreTypes-1;
2897 loop->PreIfLevel = AP.PreIfLevel;
2898 loop->PreSwitchLevel = AP.PreSwitchLevel;
2900 if ( PreLoad(&(loop->
p),(UBYTE *)
"do",(UBYTE *)
"enddo",1,
"doloop") )
return(-1);
2901 AC.NoShowInput = oldNoShowInput;
2902 loop->NoShowInput = AC.NoShowInput;
2906 s = loop->
p.buffer + (s - AP.preStart);
2909 if ( chartype[*s] != 0 )
goto illname;
2911 while ( chartype[*s] <= 1 ) s++;
2913 while ( *s ==
' ' || *s ==
'\t' ) s++;
2914 if ( *s !=
'=' )
goto illdo;
2916 while ( *s ==
' ' || *s ==
'\t' ) s++;
2920 loop->type = LISTEDLOOP;
2921 s++; loop->vars = s;
2923 while ( *s !=
'}' && *s != 0 ) {
2924 if ( set_in(*s,AC.separators) ) { *s = 0; loop->lastnum++; }
2925 else if ( *s ==
'\\' ) s++;
2928 if ( *s == 0 )
goto illdo;
2934 else if ( *s ==
'-' || *s ==
'+' || chartype[*s] == 1 || *s ==
'$' ) {
2935 loop->type = NUMERICALLOOP;
2937 while ( *s && *s !=
',' ) s++;
2938 if ( *s == 0 )
goto illdo;
2941 if ( GetName(AC.dollarnames,t+1,&loop->firstdollar,NOAUTO) != CDOLLAR ) {
2942 MesPrint(
"@%s is undefined in first parameter in %#do instruction",t);
2945 loop->firstnum = DolToLong(BHEAD loop->firstdollar);
2946 if ( AN.ErrorInDollar ) {
2947 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2954 if ( PreEval(t,&loop->firstnum) == 0 )
goto illdo;
2958 while ( *s && *s !=
',' && *s !=
';' && *s != LINEFEED ) s++;
2962 if ( GetName(AC.dollarnames,t+1,&loop->lastdollar,NOAUTO) != CDOLLAR ) {
2963 MesPrint(
"@%s is undefined in second parameter in %#do instruction",t);
2966 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
2967 if ( AN.ErrorInDollar ) {
2968 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2975 if ( PreEval(t,&loop->lastnum) == 0 )
goto illdo;
2980 while ( *s && *s !=
';' && *s != LINEFEED ) s++;
2983 if ( GetName(AC.dollarnames,t+1,&loop->incdollar,NOAUTO) != CDOLLAR ) {
2984 MesPrint(
"@%s is undefined in third parameter in %#do instruction",t);
2987 loop->incnum = DolToLong(BHEAD loop->incdollar);
2988 if ( AN.ErrorInDollar ) {
2989 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2996 if ( PreEval(t,&loop->incnum) == 0 )
goto illdo;
3000 else loop->incnum = 1;
3003 else if ( ( chartype[*s] == 0 ) || ( *s ==
'[' ) ) {
3004 int oldNumPotModdollars = NumPotModdollars;
3006 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
3007 AC.RhsExprInModuleFlag = 0;
3010 if ( ( s =
SkipAName(s) ) == 0 )
goto illdo;
3012 if ( GetName(AC.exprnames,t,&expnum,NOAUTO) == CEXPRESSION ) {
3013 loop->type = ONEEXPRESSION;
3022 if ( c ==
',' || c ==
'\t' || c ==
';' ) { s++; }
3023 else if ( c != 0 && c !=
'\n' )
goto illdo;
3024 while ( *s ==
',' || *s ==
'\t' || *s ==
';' ) s++;
3025 if ( *s != 0 && *s !=
'\n' )
goto illdo;
3036 while ( *t ) { t++; i++; }
3038 loop->
dollarname = Malloc1((LONG)i,
"do-loop instruction");
3043 *u++ =
'$'; t = loop->
name;
while ( *t ) *u++ = *t++;
3044 *u++ =
'_'; uu = u; *u++ =
'='; t = loop->vars;
3045 while ( *t ) *u++ = *t++;
3051 oldpreassignflag = AP.PreAssignFlag;
3052 AP.PreAssignFlag = 2;
3054 if ( CatchDollar(0) ) {
3055 MesPrint(
"@Cannot load expression in do loop");
3058 AP.PreAssignFlag = oldpreassignflag;
3059 NumPotModdollars = oldNumPotModdollars;
3061 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
3066 loop->errorsinloop = 0;
3068 loop->startlinenumber = linenum;
3070 loop->firstloopcall = 1;
3073 MesPrint(
"@Improper name for do loop variable");
3076 MesPrint(
"@Improper syntax in do loop instruction");
3088int DoBreakDo(UBYTE *s)
3092 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3093 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3095 if ( NumDoLoops <= 0 ) {
3096 MesPrint(
"@%#breakdo without %#do");
3102 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
3106 else if ( FG.cTable[*s] == 1 ) {
3108 while ( *s >=
'0' && *s <=
'9' ) { levels = 10*levels + *s++ -
'0'; }
3109 if ( *s != 0 )
goto improper;
3113 MesPrint(
"@Improper syntax of %#breakdo instruction");
3116 if ( levels > NumDoLoops ) {
3117 MesPrint(
"@Too many loop levels requested in %#breakdo instruction");
3120 return(ExitDoLoops(levels,
"breakdo"));
3130static int ExitDoLoops(
int levels,
const char *instruction)
3133 while ( levels > 0 ) {
3134 while ( AC.CurrentStream->type != PREREADSTREAM
3135 && AC.CurrentStream->type != PREREADSTREAM2
3136 && AC.CurrentStream->type != PREREADSTREAM3 ) {
3137 AC.CurrentStream = CloseStream(AC.CurrentStream);
3139 while ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO
3140 && AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) AP.NumPreTypes--;
3141 if ( AC.CurrentStream->type == PREREADSTREAM3
3142 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
3143 MesPrint(
"@Trying to jump out of a procedure with a %#%s instruction",instruction);
3146 loop = &(DoLoops[NumDoLoops-1]);
3147 AP.NumPreTypes = loop->NumPreTypes;
3148 AP.PreIfLevel = loop->PreIfLevel;
3149 AP.PreSwitchLevel = loop->PreSwitchLevel;
3151 DoUndefine(loop->
name);
3152 M_free(loop->
p.buffer,
"loop->p.buffer");
3153 loop->firstloopcall = 0;
3155 AC.CurrentStream = CloseStream(AC.CurrentStream);
3168 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3169 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#else without corresponding %#if");
3170 else MessPreNesting(1);
3173 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3174 while ( *s ==
' ' ) s++;
3175 if ( tolower(*s) ==
'i' && tolower(s[1]) ==
'f' && s[2]
3176 && FG.cTable[s[2]] > 1 && s[2] !=
'_' ) {
3178 while ( *s ==
' ' ) s++;
3179 return(DoElseif(s));
3181 if ( AP.PreIfLevel <= 0 ) {
3182 MesPrint(
"@%#else without corresponding %#if");
3185 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3187 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3189 case LOOKINGFORELSE:
3190 AP.PreIfStack[AP.PreIfLevel] = EXECUTINGIF;
3192 case LOOKINGFORENDIF:
3203int DoElseif(UBYTE *s)
3206 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3207 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#elseif without corresponding %#if");
3208 else MessPreNesting(2);
3211 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3212 if ( AP.PreIfLevel <= 0 ) {
3213 MesPrint(
"@%#elseif without corresponding %#if");
3216 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3218 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3220 case LOOKINGFORELSE:
3221 if ( ( condition = EvalPreIf(s) ) < 0 )
return(-1);
3222 AP.PreIfStack[AP.PreIfLevel] = condition;
3224 case LOOKINGFORENDIF:
3238int DoEnddo(UBYTE *s)
3242 UBYTE *t, *tt, *value, numstr[16];
3246 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3247 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3256 if ( NumDoLoops <= 0 ) {
3257 MesPrint(
"@%#enddo without %#do");
3260 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO ) { MessPreNesting(4);
return(-1); }
3261 loop = &(DoLoops[NumDoLoops-1]);
3262 if ( !loop->firstloopcall ) AC.CurrentStream = CloseStream(AC.CurrentStream);
3264 if ( loop->errorsinloop ) {
3265 MesPrint(
"++++Errors in Loop");
3268 if ( loop->type == LISTEDLOOP ) {
3269 if ( loop->firstnum >= loop->lastnum )
goto finish;
3271 t = value = loop->vars;
3272 while ( *value ) value++;
3277 if ( *value ==
'\\' ) value++;
3283 else if ( loop->type == NUMERICALLOOP ) {
3285 if ( !loop->firstloopcall ) {
3294 while ( *value && ( *value ==
' '
3295 || *value ==
'-' || *value ==
'+' ) ) {
3296 if ( *value ==
'-' ) xsign = -xsign;
3299 t = value; xval = 0;
3300 while ( *value >=
'0' && *value <=
'9' ) xval = 10*xval + *value++ -
'0';
3301 while ( *value && *value ==
' ' ) value++;
3302 if ( *value == 0 ) {
3306 if ( xsign < 0 ) xval = -xval;
3307 if ( loop->incdollar >= 0 ) {
3308 loop->incnum = DolToLong(BHEAD loop->incdollar);
3309 if ( AN.ErrorInDollar ) {
3310 MesPrint(
"@%s does not evaluate into a valid third loop parameter",DOLLARNAME(Dollars,loop->incdollar));
3314 loop->firstnum = xval + loop->incnum;
3317 if ( loop->lastdollar >= 0 ) {
3318 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
3319 if ( AN.ErrorInDollar ) {
3320 MesPrint(
"@%s does not evaluate into a valid second loop parameter",DOLLARNAME(Dollars,loop->lastdollar));
3325 if ( ( loop->incnum > 0 && loop->firstnum > loop->lastnum )
3326 || ( loop->incnum < 0 && loop->firstnum < loop->lastnum ) )
goto finish;
3327 NumToStr(numstr,loop->firstnum);
3329 loop->firstnum += loop->incnum;
3332 else if ( loop->type == ONEEXPRESSION ) {
3336 WORD numdollar = GetDollar(loop->dollarname+1);
3337 DOLLARS d = Dollars + numdollar;
3338 WORD *w, *dw, v, *ww;
3339 if ( (d->where) == 0 ) {
3340 d->type = DOLUNDEFINED;
3341 M_free(loop->dollarname,
"do-loop instruction");
3344 w = d->where + loop->incnum;
3346 M_free(d->where,
"dollar");
3348 d->type = DOLUNDEFINED;
3349 M_free(loop->dollarname,
"do-loop instruction");
3356 ww = w + *w; v = *ww; *ww = 0;
3357 dw = d->where; d->where = w;
3358 t = WriteDollarToBuffer(numdollar,1);
3359 d->where = dw; *ww = v;
3363 if ( loop->firstloopcall ) OpenStream(loop->contents,PREREADSTREAM2,0,PRENOACTION);
3364 else OpenStream(loop->contents,PREREADSTREAM,0,PRENOACTION);
3365 AC.CurrentStream->prevline =
3366 AC.CurrentStream->linenumber = loop->startlinenumber;
3367 AC.CurrentStream->eqnum = 0;
3368 loop->firstloopcall = 0;
3372 retval = DoUndefine(loop->name);
3373 M_free(loop->p.buffer,
"loop->p.buffer");
3374 loop->firstloopcall = 0;
3384int DoEndif(UBYTE *s)
3387 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3388 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#endif without corresponding %#if");
3389 else MessPreNesting(5);
3393 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3394 if ( AP.PreIfLevel <= 0 ) {
3395 MesPrint(
"@%#endif without corresponding %#if");
3412int DoEndprocedure(UBYTE *s)
3415 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) {
3420 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3421 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3422 AC.CurrentStream = CloseStream(AC.CurrentStream);
3426 if ( Procedures[NumProcedures].mustfree == 1 ) {
3427 M_free(Procedures[NumProcedures].p.buffer,
"procedures buffer");
3428 M_free(Procedures[NumProcedures].name,
"procedures name");
3430 }
while ( Procedures[NumProcedures].loadmode > 1 );
3442 AddToPreTypes(PRETYPEIF);
3443 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3444 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3445 condition = EvalPreIf(s);
3446 if ( condition < 0 )
return(-1);
3448 else condition = LOOKINGFORENDIF;
3449 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3450 int **ppp = &AP.PreIfStack;
3451 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3452 "PreIfLevels") )
return(-1);
3454 AP.PreIfStack[++AP.PreIfLevel] = condition;
3463int DoIfdef(UBYTE *s,
int par)
3466 AddToPreTypes(PRETYPEIF);
3467 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3468 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3469 while ( *s ==
' ' || *s ==
'\t' ) s++;
3470 if ( ( *s == 0 ) == ( par == 1 ) ) condition = LOOKINGFORELSE;
3471 else condition = EXECUTINGIF;
3473 else condition = LOOKINGFORENDIF;
3474 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3475 int **ppp = &AP.PreIfStack;
3476 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3477 "PreIfLevels") )
return(-1);
3479 AP.PreIfStack[++AP.PreIfLevel] = condition;
3488int DoIfydef(UBYTE *s)
3490 return DoIfdef(s,1);
3498int DoIfndef(UBYTE *s)
3500 return DoIfdef(s,2);
3523int DoInside(UBYTE *s)
3526 int numdol, error = 0;
3527 WORD *nb, newsize, i;
3529 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3530 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3531 if ( AP.PreInsideLevel != 0 ) {
3532 MesPrint(
"@Illegal nesting of %#inside/%#endinside instructions");
3545 AP.inside.numdollars = 0;
3547 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
3548 if ( *s == 0 )
break;
3550 MesPrint(
"@%#inside instruction can have only $ variables for parameters");
3555 while (chartype[*s] <= 1 ) s++;
3557 if ( ( numdol = GetDollar(name) ) < 0 ) {
3558 MesPrint(
"@%#inside: $%s has not (yet) been defined",name);
3564 if ( AP.inside.numdollars >= AP.inside.size ) {
3565 if ( AP.inside.buffer == 0 ) newsize = 20;
3566 else newsize = 2*AP.inside.size;
3567 nb = (WORD *)Malloc1(newsize*
sizeof(WORD),
"insidebuffer");
3568 if ( AP.inside.buffer ) {
3569 for ( i = 0; i < AP.inside.size; i++ ) nb[i] = AP.inside.buffer[i];
3570 M_free(AP.inside.buffer,
"insidebuffer");
3572 AP.inside.buffer = nb;
3573 AP.inside.size = newsize;
3575 AP.inside.buffer[AP.inside.numdollars++] = numdol;
3582 AP.inside.oldcompiletype = AC.compiletype;
3583 AP.inside.oldparallelflag = AC.mparallelflag;
3584 AP.inside.oldnumpotmoddollars = NumPotModdollars;
3585 AP.inside.oldcbuf = AC.cbufnum;
3586 AP.inside.oldrbuf = AM.rbufnum;
3587 AP.inside.oldcnumlhs = AR.Cnumlhs,
3588 AddToPreTypes(PRETYPEINSIDE);
3589 AP.PreInsideLevel = 1;
3590 AC.cbufnum = AP.inside.inscbuf;
3591 AM.rbufnum = AP.inside.inscbuf;
3594 AC.mparallelflag = PARALLELFLAG;
3603 PF_StoreInsideInfo();
3604 AC.RhsExprInModuleFlag = 0;
3605 NumPotModdollars = 0;
3606 AC.numpfirstnum = 0;
3616int DoEndInside(UBYTE *s)
3619 WORD numdol, *oldworkpointer = AT.WorkPointer, *term, *t, j, i;
3621 WORD oldbracketon = AR.BracketOn;
3622 WORD *oldcompresspointer = AR.CompressPointer;
3623 int oldmultithreaded = AS.MultiThreaded;
3630 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3631 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3632 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEINSIDE ) {
3633 if ( AP.PreInsideLevel != 1 ) MesPrint(
"@%#endinside without corresponding %#inside");
3634 else MessPreNesting(11);
3638 if ( AP.PreInsideLevel != 1 ) {
3639 MesPrint(
"@%#endinside without corresponding %#inside");
3642 if ( AP.PreContinuation ) {
3643 MesPrint(
"@%#endinside: previous statement not terminated.");
3646 AC.compiletype = AP.inside.oldcompiletype;
3647 AR.Cnumlhs = cbuf[AM.rbufnum].numlhs;
3654 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
3657 AS.MultiThreaded = 0;
3659 if ( AR.CompressPointer == 0 ) AR.CompressPointer = AR.CompressBuffer;
3660 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3664 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3665 numdol = AP.inside.buffer[i];
3666 nd = d = Dollars + numdol;
3667 if ( d->type != DOLZERO ) {
3668 if ( d->type != DOLTERMS ) nd = DolToTerms(BHEAD numdol);
3672 AR.MaxDum = AM.IndDum;
3674 t = oldworkpointer; j = *term;
3677 AN.IndDum = AM.IndDum;
3678 AR.CurDum = ReNumber(BHEAD term);
3679 if (
Generator(BHEAD oldworkpointer,0) ) {
3680 MesPrint(
"@Called from %#endinside");
3681 MesPrint(
"@Evaluating variable $%s",DOLLARNAME(Dollars,numdol));
3685 AT.WorkPointer = oldworkpointer;
3686 CleanDollarFactors(d);
3687 if ( d->where ) { M_free(d->where,
"dollar contents"); d->where = 0; }
3688 EndSort(BHEAD (WORD *)((
void *)(&(d->where))),2);
3690 term = d->where;
while ( *term ) term += *term;
3691 d->size = term - d->where;
3692 if ( nd != d ) M_free(nd,
"Copy of dollar variable");
3693 if ( d->where[0] == 0 ) {
3694 M_free(d->where,
"dollar contents"); d->where = 0;
3701 if ( AC.RhsExprInModuleFlag ) {
3706 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3714 if ( NumPotModdollars > 0 ) {
3716 if ( error )
goto cleanup;
3718 if ( AC.numpfirstnum > 0 ) {
3720 if ( error )
goto cleanup;
3725 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3726 AC.cbufnum = AP.inside.oldcbuf;
3727 AM.rbufnum = AP.inside.oldrbuf;
3728 AR.Cnumlhs = AP.inside.oldcnumlhs;
3729 AR.BracketOn = oldbracketon;
3730 AP.PreInsideLevel = 0;
3731 AR.CompressPointer = oldcompresspointer;
3732 AS.MultiThreaded = oldmultithreaded;
3733 AC.mparallelflag = AP.inside.oldparallelflag;
3734 NumPotModdollars = AP.inside.oldnumpotmoddollars;
3737 PF_RestoreInsideInfo();
3738 if ( error )
return error;
3748int DoMessage(UBYTE *s)
3750 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3751 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3752 while ( *s ==
' ' || *s ==
'\t' ) s++;
3753 MesPrint(
"~~~%s",s);
3767 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3768 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3771 while ( *s ==
' ' || *s ==
'\t' ) s++;
3772 if ( OpenStream(s,PIPESTREAM,0,PRENOACTION) == 0 )
return(-1);
3775 Error0(
"Pipes not implemented on this computer/system");
3785int DoPrcExtension(UBYTE *s)
3788 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3789 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3790 while ( *s ==
' ' || *s ==
'\t' ) s++;
3791 if ( *s == 0 || *s ==
'\n' ) {
3792 MesPrint(
"@No valid procedure extension specified");
3795 if ( FG.cTable[*s] != 0 ) {
3796 MesPrint(
"@Procedure extension should be a string starting with an alphabetic character. No whitespace.");
3800 while ( *s && *s !=
'\n' && *s !=
' ' && *s !=
'\t' ) s++;
3802 while ( *s ==
' ' || *s ==
'\t' ) s++;
3803 if ( *s != 0 && *s !=
'\n' ) {
3804 MesPrint(
"@Too many parameters in ProcedureExtension instruction");
3808 if ( AP.procedureExtension ) M_free(AP.procedureExtension,
"ProcedureExtension");
3809 AP.procedureExtension = strDup1(t,
"ProcedureExtension");
3819int DoPreOut(UBYTE *s)
3821 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3822 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3823 if ( tolower(*s) ==
'o' ) {
3824 if ( tolower(s[1]) ==
'n' && s[2] == 0 ) {
3828 if ( tolower(s[1]) ==
'f' && tolower(s[2]) ==
'f' && s[3] == 0 ) {
3833 MesPrint(
"@Illegal option in PreOut instruction");
3842int DoPrePrintTimes(UBYTE *s)
3845 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3846 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3856int DoPreSortReallocate(UBYTE *s)
3859 if ( AC.SortReallocateFlag == 0 ) {
3862 AC.SortReallocateFlag = 2;
3876int DoPreAppend(UBYTE *s)
3880 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3881 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3882 if ( AP.preError )
return(0);
3883 while ( *s ==
' ' || *s ==
'\t' ) s++;
3890 while ( *s && *s !=
'>' ) {
3891 if ( *s ==
'\\' ) s++;
3895 MesPrint(
"@Improper termination of filename");
3900 if ( *name ) { GetAppendChannel((
char *)name); }
3905 MesPrint(
"@Proper syntax is: %#append <filename>");
3919int DoPreCreate(UBYTE *s)
3923 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3924 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3925 if ( AP.preError )
return(0);
3926 while ( *s ==
' ' || *s ==
'\t' ) s++;
3933 while ( *s && *s !=
'>' ) {
3934 if ( *s ==
'\\' ) s++;
3938 MesPrint(
"@Improper termination of filename");
3943 if ( *name ) { GetChannel((
char *)name,0); }
3948 MesPrint(
"@Proper syntax is: %#create <filename>");
3959int DoPreRemove(UBYTE *s)
3962 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3963 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3964 if ( AP.preError )
return(0);
3965 while ( *s ==
' ' || *s ==
'\t' ) s++;
3966 if ( *s ==
'<' ) { s++; }
3968 MesPrint(
"@Proper syntax is: %#remove <filename>");
3972 while ( *s && *s !=
'>' ) {
3973 if ( *s ==
'\\' ) s++;
3977 MesPrint(
"@Improper filename");
3982 CloseChannel((
char *)name);
3983 remove((
char *)name);
3992int DoPreClose(UBYTE *s)
3995 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3996 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3997 if ( AP.preError )
return(0);
3998 while ( *s ==
' ' || *s ==
'\t' ) s++;
3999 if ( *s ==
'<' ) { s++; }
4001 MesPrint(
"@Proper syntax is: %#close <filename>");
4005 while ( *s && *s !=
'>' ) {
4006 if ( *s ==
'\\' ) s++;
4010 MesPrint(
"@Improper filename");
4015 return(CloseChannel((
char *)name));
4036int DoPreWrite(UBYTE *s)
4040 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4041 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4042 if ( AP.preError )
return(0);
4045 if ( PF.me != MASTER )
return 0;
4048 h.oldsilent = AM.silent;
4049 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
4050 h.newhandle = h.oldhandle = AC.LogHandle;
4051 h.oldprinttype = AO.PrintType;
4053 while ( *s ==
' ' || *s ==
'\t' ) s++;
4057 if( (s=defineChannel(s,&h))==0 )
return(-1);
4059 return(writeToChannel(WRITEOUT,s,&h));
4077int DoProcedure(UBYTE *s)
4082 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
4083 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
4084 if ( PreSkip((UBYTE *)
"procedure",(UBYTE *)
"endprocedure",1) )
return(-1);
4088 p = (
PROCEDURE *)FromList(&AP.ProcList);
4089 if ( PreLoad(&(p->p),(UBYTE *)
"procedure",(UBYTE *)
"endprocedure"
4090 ,1,(
char *)
"procedure") )
return(-1);
4096 if ( NumProcedures >= 2 &&
4097 ( Procedures[NumProcedures-2].loadmode != 2 || Procedures[NumProcedures-2].mustfree ) ) {
4107 s = p->p.buffer + 10;
4108 while ( *s ==
' ' || *s == LINEFEED ) s++;
4109 if ( chartype[*s] ) {
4110 MesPrint(
"@Illegal name for procedure");
4114 while ( chartype[*s] == 0 || chartype[*s] == 1 ) s++;
4116 p->name = strDup1(p->name,
"procedure");
4121 for ( i = NumProcedures-2; i >= 0; i-- ) {
4122 if ( StrCmp(Procedures[i].name,p->name) == 0 ) {
4123 Error1(
"Multiple occurrence of procedure name ",p->name);
4134int DoPreBreak(UBYTE *s)
4137 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4138 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4139 if ( AP.PreSwitchLevel <= 0 )
4140 MesPrint(
"@Break without corresponding Switch");
4141 else MessPreNesting(7);
4144 if ( AP.PreSwitchLevel <= 0 ) {
4145 MesPrint(
"@Break without corresponding Switch");
4148 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH )
4149 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4158int DoPreCase(UBYTE *s)
4161 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4162 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4163 if ( AP.PreSwitchLevel <= 0 )
4164 MesPrint(
"@Case without corresponding Switch");
4165 else MessPreNesting(8);
4168 if ( AP.PreSwitchLevel <= 0 ) {
4169 MesPrint(
"@Case without corresponding Switch");
4172 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
4176 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
4177 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
4178 if ( s[-2] ==
'\\' ) s--;
4181 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
4185 s = AP.PreSwitchStrings[AP.PreSwitchLevel];
4186 while ( *t == *s && *t ) { s++; t++; }
4187 if ( *t || *s )
return(0);
4188 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
4197int DoPreDefault(UBYTE *s)
4200 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4201 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4202 if ( AP.PreSwitchLevel <= 0 )
4203 MesPrint(
"@Default without corresponding Switch");
4204 else MessPreNesting(9);
4207 if ( AP.PreSwitchLevel <= 0 ) {
4208 MesPrint(
"@Default without corresponding Switch");
4211 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
4212 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
4221int DoPreEndSwitch(UBYTE *s)
4224 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4225 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
4226 if ( AP.PreSwitchLevel <= 0 )
4227 MesPrint(
"@EndSwitch without corresponding Switch");
4228 else MessPreNesting(10);
4232 if ( AP.PreSwitchLevel <= 0 ) {
4233 MesPrint(
"@EndSwitch without corresponding Switch");
4236 M_free(AP.PreSwitchStrings[AP.PreSwitchLevel--],
"pre switch string");
4248int DoPreSwitch(UBYTE *s)
4250 UBYTE *t, *switchstring, **newstrings;
4251 int newnum, i, *newmodes;
4252 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4255 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
4256 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
4257 if ( s[-2] ==
'\\' ) s--;
4260 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
4264 switchstring = (UBYTE *)Malloc1((s-t)+1,
"case string");
4267 if ( *t ==
'\\' ) t++;
4271 if ( AP.PreSwitchLevel >= AP.NumPreSwitchStrings ) {
4272 newnum = 2*AP.NumPreSwitchStrings;
4273 newstrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*(newnum+1),
"case strings");
4274 newmodes = (
int *)Malloc1(
sizeof(
int)*(newnum+1),
"case strings");
4275 for ( i = 0; i < AP.NumPreSwitchStrings; i++ )
4276 newstrings[i] = AP.PreSwitchStrings[i];
4277 M_free(AP.PreSwitchStrings,
"AP.PreSwitchStrings");
4278 for ( i = 0; i <= AP.NumPreSwitchStrings; i++ )
4279 newmodes[i] = AP.PreSwitchModes[i];
4280 M_free(AP.PreSwitchModes,
"AP.PreSwitchModes");
4281 AP.PreSwitchStrings = newstrings;
4282 AP.PreSwitchModes = newmodes;
4283 AP.NumPreSwitchStrings = newnum;
4285 AP.PreSwitchStrings[++AP.PreSwitchLevel] = switchstring;
4286 if ( ( AP.PreSwitchLevel > 1 )
4287 && ( AP.PreSwitchModes[AP.PreSwitchLevel-1] != EXECUTINGPRESWITCH ) )
4288 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4290 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPRECASE;
4291 AddToPreTypes(PRETYPESWITCH);
4302int DoPreShow(UBYTE *s)
4306 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4307 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4308 while ( *s ==
' ' || *s ==
'\t' ) s++;
4310 MesPrint(
"%#The preprocessor variables:");
4311 for ( i = 0; i < NumPre; i++ ) {
4312 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4317 name = s;
while ( *s && *s !=
' ' && *s !=
'\t' && *s !=
',' ) s++;
4319 for ( i = 0; i < NumPre; i++ ) {
4320 if ( StrCmp(PreVar[i].name,name) == 0 )
4321 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4324 while ( *s ==
' ' || *s ==
'\t' ) s++;
4338#define STRINGIFY(x) STRINGIFY__(x)
4339#define STRINGIFY__(x) #x
4341int DoSystem(UBYTE *s)
4343 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4344 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4345 if ( AP.preError )
return(0);
4348 while ( *s ==
' ' || *s ==
'\t' ) s++;
4349 if ( *s ==
'-' && s[1] ==
'e' ) {
4354 MesPrint(
"@Syntax error in #system command.");
4357 while ( *s ==
' ' || *s ==
'\t' ) s++;
4358 err = system((
char *)s);
4360 PutPreVar((UBYTE *)
"SYSTEMERROR_",str,0,1);
4362 else if ( system((
char *)s) ) {
4363 MesPrint(
"@System call returned with error condition");
4368 Error0(
"External programs not implemented on this computer/system");
4381int PreLoad(
PRELOAD *p, UBYTE *start, UBYTE *stop,
int mode,
char *message)
4383 UBYTE *s, *t, *top, *newbuffer, c;
4384 LONG i, ppsize, linenum = AC.CurrentStream->linenumber;
4385 int size1, size2, level, com=0, last=1, strng = 0;
4387 p->buffer = (UBYTE *)Malloc1(p->size+1,message);
4388 top = p->buffer + p->size - 2;
4389 t = p->buffer; *t++ =
'#';
4390 s = start; size1 = size2 = 0;
4391 while ( *s ) { s++; size1++; }
4392 s = stop;
while ( *s ) { s++; size2++; }
4393 s = AP.preStart;
while ( *s ) *t++ = *s++; *t++ = LINEFEED;
4398 if ( c == ENDOFINPUT ) {
4399 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4402 if ( c == AP.ComChar && last == 1 ) com = 1;
4403 if ( c == LINEFEED ) { last = 1; com = 0; }
4406 if ( ( c ==
'"' ) && ( com == 0 ) ) { strng ^= 1; }
4408 if ( ( c ==
'#' ) && ( com == 0 ) ) i = 0;
4412 ppsize = t - p->buffer;
4414 newbuffer = (UBYTE *)Malloc1(p->size,message);
4415 t = newbuffer; s = p->buffer;
4416 while ( --ppsize >= 0 ) *t++ = *s++;
4417 M_free(p->buffer,
"loading do loop");
4418 p->buffer = newbuffer;
4419 top = p->buffer + p->size - 2;
4423 if ( ( i == size2 ) && ( com == 0 ) ) {
4425 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4426 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4428 if ( level <= 0 )
break;
4429 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4430 *t++ = LINEFEED; *t = 0; last = 1;
4433 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4435 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4443 if ( i == 1 && t[-2] == LINEFEED ) {
4444 if ( c ==
'-' ) AC.NoShowInput = 1;
4445 else if ( c ==
'+' ) AC.NoShowInput = 0;
4462#define SKIPBUFSIZE 20
4464int PreSkip(UBYTE *start, UBYTE *stop,
int mode)
4466 UBYTE *s, *t, buffer[SKIPBUFSIZE+2], c;
4467 LONG i, linenum = AC.CurrentStream->linenumber;
4468 int size1, size2, level, com=0, last=1;
4470 t = buffer; *t++ =
'#';
4471 s = start; size1 = size2 = 0;
4472 while ( *s ) { s++; size1++; }
4473 s = stop;
while ( *s ) { s++; size2++; }
4478 if ( c == ENDOFINPUT ) {
4479 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4482 if ( c == AP.ComChar && last == 1 ) com = 1;
4483 if ( c == LINEFEED ) { last = 1; com = 0; i = 0; t = buffer; }
4485 if ( ( c ==
'#' ) && ( com == 0 ) ) { i = 0; t = buffer; }
4488 if ( i < SKIPBUFSIZE ) *t++ = c;
4489 if ( ( i == size2 ) && ( com == 0 ) ) {
4491 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4492 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4495 pushbackchar = LINEFEED;
4498 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4502 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4504 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4505 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4519void StartPrepro(
void)
4522 AP.MaxPreIfLevel = 2;
4523 ppp = &AP.PreIfStack;
4524 if ( DoubleList((
void ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
4525 "PreIfLevels") ) Terminate(-1);
4526 AP.PreIfLevel = 0; AP.PreIfStack[0] = EXECUTINGIF;
4528 AP.NumPreSwitchStrings = 10;
4529 AP.PreSwitchStrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*
4530 (AP.NumPreSwitchStrings+1),
"case strings");
4531 AP.PreSwitchModes = (
int *)Malloc1(
sizeof(
int)*
4532 (AP.NumPreSwitchStrings+1),
"case strings");
4533 AP.PreSwitchModes[0] = EXECUTINGPRESWITCH;
4534 AP.PreSwitchLevel = 0;
4547int EvalPreIf(UBYTE *s)
4555 if ( ( u = PreIfEval(s,&val) ) == 0 )
return(-1);
4557 MesPrint(
"@Unmatched parentheses in condition");
4560 if ( val )
return(EXECUTINGIF);
4561 else return(LOOKINGFORELSE);
4582UBYTE *PreIfEval(UBYTE *s,
int *value)
4584 int orlevel = 0, andlevel = 0, eqlevel = 0, cmplevel = 0;
4587 int ortype, orval, cmptype, cmpval, eqtype, eqval, andtype, andval;
4588 UBYTE *t, *eqt, *cmpt, c;
4590 ortype = orval = cmptype = cmpval = eqtype = eqval = andtype = andval = 0;
4594 while ( *s !=
')' ) {
4595 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4597 s = pParseObject(s,&type,&val2);
4598 if ( s == 0 )
return(0);
4602 while ( c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' ) {
4605 if ( *t ==
'"' ) t++;
4608 if ( *s !=
'|' )
goto illoper;
4613 if ( type == 0 || cmptype == 0 )
goto illobject;
4614 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4619 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4624 if ( andtype != 0 || type != 0 )
goto illobject;
4629 if ( ortype != 0 || type != 0 )
goto illobject;
4641 if ( *s !=
'&' )
goto illoper;
4644 if ( type == 0 || cmptype == 0 )
goto illobject;
4645 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4650 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4655 if ( andtype != 0 || type != 0 )
goto illobject;
4664 if ( eqlevel )
goto illorder;
4666 if ( type == 0 || cmptype == 0 )
goto illobject;
4667 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4671 if ( c ==
'!' && *s !=
'=' )
goto illoper;
4672 if ( *s ==
'=' ) s++;
4673 if ( c ==
'!' ) eqop = 1;
4675 eqlevel = 1; eqt = t; eqval = val; eqtype = type;
4679 if ( cmplevel )
goto illorder;
4680 if ( c ==
'<' ) cmpop = -1;
4682 cmplevel = 1; cmpt = t; cmpval = val; cmptype = type;
4685 if ( *s ==
'~' ) { s++; cmpop *= 4; }
4688 else if ( *s ==
'~' ) { s++; cmpop *= 3; }
4696 MesPrint(
"@illegal order of operators");
4699 MesPrint(
"@illegal object for this operator");
4702 MesPrint(
"@illegal operator");
4711int PreCmp(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int cmpop)
4713 if ( type == 2 || type2 == 2 || cmpop < -2 || cmpop > 2 ) {
4714 if ( cmpop < 0 && cmpop > -3 ) cmpop -= 2;
4715 if ( cmpop > 0 && cmpop < 3 ) cmpop += 2;
4716 if ( cmpop == 3 ) val = StrCmp(t2,t) > 0;
4717 else if ( cmpop == 4 ) val = StrCmp(t2,t) >= 0;
4718 else if ( cmpop == -3 ) val = StrCmp(t2,t) < 0;
4719 else if ( cmpop == -4 ) val = StrCmp(t2,t) <= 0;
4722 if ( cmpop == 1 ) val = ( val2 > val );
4723 else if ( cmpop == 2 ) val = ( val2 >= val );
4724 else if ( cmpop == -1 ) val = ( val2 < val );
4725 else if ( cmpop == -2 ) val = ( val2 <= val );
4735int PreEq(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int eqop)
4738 if ( type == 2 || type2 == 2 ) {
4739 if ( type != 2 ) { NumToStr(str,val ); t = str; }
4740 if ( type2 != 2 ) { NumToStr(str,val2); t2 = str; }
4741 if ( eqop == 1 ) val = StrCmp(t,t2) != 0;
4742 else val = StrCmp(t,t2) == 0;
4745 if ( eqop ) val = val != val2;
4746 else val = val == val2;
4764UBYTE *pParseObject(UBYTE *s,
int *type, LONG *val2)
4769 while ( *s ==
' ' || *s ==
'\t' ) s++;
4772 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4773 s = PreIfEval(s,&val);
4778 else if ( *s ==
'$' && s[1] ==
'(' ) {
4780 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4781 s = PreIfDollarEval(s,&val);
4782 *type = 0; *val2 = val;
4787 MesPrint(
"@illegal end of condition");
4792 while ( *s && *s !=
'"' ) {
4793 if ( *s ==
'\\' ) s++;
4796 if ( *s == 0 )
goto illend;
4801 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4805 t = s; sign = 1; x = 0;
4806 if ( chartype[*t] == 0 ) {
4807 do { t++; }
while ( chartype[*t] <= 1 );
4811 if ( StrICmp(s,(UBYTE *)
"termsin") == 0 ) {
4813 WORD numdol, numexp;
4817 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4819 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4821 if ( ( numdol = GetDollar(t) ) > 0 ) {
4824 x = SizeOfDollar(numdol);
4827 x = TermsInDollar(numdol);
4831 MesPrint(
"@$%s has not (yet) been defined",t);
4839 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4840 MesPrint(
"@%s has not (yet) been defined",t);
4847 x = SizeOfExpression(numexp);
4850 x = TermsInExpression(numexp);
4854 while ( *tt ==
' ' || *tt ==
'\t'
4855 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4857 MesPrint(
"@Improper use of terms($var) or terms(expr)");
4865 else if ( StrICmp(s,(UBYTE *)
"sizeof") == 0 ) {
4869 else if ( StrICmp(s,(UBYTE *)
"exists") == 0 ) {
4871 WORD numdol, numexp;
4873 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4875 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4877 if ( ( numdol = GetDollar(t) ) >= 0 ) { x = 1; }
4881 else if ( *t ==
'"' ) {
4885 if ( *tt ==
'\\' ) tt++;
4886 else if ( *tt ==
'"' )
break;
4899 x = OpenFile((
char *)t);
4916 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) { x = 0; }
4920 while ( *tt ==
' ' || *tt ==
'\t'
4921 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4923 MesPrint(
"@Improper use of exists($var) or exists(expr)");
4931 else if ( StrICmp(s,(UBYTE *)
"isnumerical") == 0 ) {
4934 WORD numdol, numexp;
4936 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4938 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4940 if ( ( numdol = GetDollar(t) ) < 0 ) {
4941 MesPrint(
"@$ variable in isnumerical(%s) does not exist",t);
4944 x = DolToLong(BHEAD numdol);
4945 if ( AN.ErrorInDollar ) {
4948 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
4949 if ( d->where[0] == 0 ) x = 1;
4950 else if ( d->where[d->where[0]] == 0 ) {
4951 if ( ABS(d->where[d->where[0]-1]) == d->where[0]-1 )
4962 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4963 MesPrint(
"@expression in isnumerical(%s) does not exist",t);
4966 x = TermsInExpression(numexp);
4967 if ( x != 1 ) x = 0;
4969 WORD *term = AT.WorkPointer;
4971 MesPrint(
"@error reading expression in isnumerical(%s)",t);
4974 if ( *term == ABS(term[*term-1])+1 ) x = 1;
4979 while ( *tt ==
' ' || *tt ==
'\t'
4980 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4982 MesPrint(
"@Improper use of isnumerical($var) or numerical(expr)");
4990 else if ( StrICmp(s,(UBYTE *)(
"maxpowerof")) == 0 ) {
4995 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4998 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4999 MesPrint(
"@%s has not (yet) been defined",t);
5003 else if ( stype != CSYMBOL ) {
5004 MesPrint(
"@%s should be a symbol",t);
5010 x = symbols[numsym].maxpower;
5012 while ( *tt ==
' ' || *tt ==
'\t'
5013 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5015 MesPrint(
"@Improper use of maxpowerof(symbol)");
5023 else if ( StrICmp(s,(UBYTE *)(
"minpowerof")) == 0 ) {
5028 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5031 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
5032 MesPrint(
"@%s has not (yet) been defined",t);
5036 else if ( stype != CSYMBOL ) {
5037 MesPrint(
"@%s should be a symbol",t);
5043 x = symbols[numsym].minpower;
5045 while ( *tt ==
' ' || *tt ==
'\t'
5046 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5048 MesPrint(
"@Improper use of minpowerof(symbol)");
5056 else if ( StrICmp(s,(UBYTE *)
"isfactorized") == 0 ) {
5058 WORD numdol, numexp;
5060 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5062 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
5064 if ( ( numdol = GetDollar(t) ) > 0 ) {
5065 if ( Dollars[numdol].factors != 0 ) x = 1;
5069 MesPrint(
"@ %s should be the name of an expression or a $ variable",t-1);
5077 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
5078 MesPrint(
"@ %s should be the name of an expression or a $ variable",t);
5082 if ( ( Expressions[numexp].vflags & ISFACTORIZED ) != 0 ) x = 1;
5087 while ( *tt ==
' ' || *tt ==
'\t'
5088 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5090 MesPrint(
"@Improper use of isfactorized($var) or isfactorized(expr)");
5098 else if ( StrICmp(s,(UBYTE *)
"isdefined") == 0 ) {
5101 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
5107 while ( *tt ==
' ' || *tt ==
'\t'
5108 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
5110 MesPrint(
"@Improper use of isdefined(var)");
5118 else if ( StrICmp(s,(UBYTE *)
"flag") == 0 ) {
5123 while ( *t ==
' ' || *t ==
'\t' ) t++;
5124 if ( FG.cTable[*t] != 1 )
goto flagerror;
5125 while ( FG.cTable[*t] == 1 ) x = 10*x + (*t++ -
'0');
5126 if ( x < 1 || x > BITSINWORD ) {
5127 MesPrint(
"@Illegal number %d for flag in flag condition",x);
5130 while ( *t ==
' ' || *t ==
'\t' ) t++;
5131 if ( *t !=
',' )
goto flagerror;
5133 while ( *t ==
' ' || *t ==
'\t' ) t++;
5136 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
5137 MesPrint(
"@ %s should be the name of an expression",t);
5141 while ( *t ==
' ' || *t ==
'\t' ) t++;
5144 MesPrint(
"@Improper use of flag(num,expr)");
5148 if ( ( Expressions[numexp].uflags & ( 1 << (x-1) ) ) != 0 )
5158 else if ( *t ==
'=' || *t ==
'<' || *t ==
'>' || *t ==
'!'
5159 || *t ==
')' || *t ==
' ' || *t ==
'\t' || *t == 0 || *t ==
'\n' ) {
5165 MesPrint(
"@Illegal use of string in preprocessor condition: %s",s);
5169 while ( *t ==
'-' || *t ==
'+' || *t ==
' ' || *t ==
'\t' ) {
5170 if ( *t ==
'-' ) sign = -sign;
5173 while ( chartype[*t] == 1 ) { x = 10*x + *t++ -
'0'; }
5174 while ( *t ==
' ' || *t ==
'\t' ) t++;
5175 if ( chartype[*t] == 8 || *t ==
')' || *t ==
'=' || *t == 0 ) {
5176 *val2 = sign > 0 ? x: -x;
5180 while ( chartype[*t] != 8 && *t !=
')' && *t !=
'=' && *t ) t++;
5181 while ( ( t > s ) && ( t[-1] ==
' ' || t[-1] ==
'\t' ) ) t--;
5202 UBYTE *buff, *s = 0, *t, *newb, c;
5203 int size, i, n, parlevel = 0, bralevel = 0;
5210 if ( size == 0 ) size = 72;
5212 if ( ( newb = (UBYTE *)Malloc1(size+2,
"{}") ) == 0 )
return(0);
5218 M_free(buff,
"pre calc buffer");
5226 Error0(
"Unmatched {}");
5227 M_free(buff,
"precalc buffer");
5230 else if ( c ==
'{' ) { bralevel++; }
5231 else if ( c ==
'}' ) {
5232 if ( --bralevel < 0 ) { *s++ = c; *s = 0;
break; }
5234 else if ( c ==
'(' ) { parlevel++; }
5235 else if ( c ==
')' ) {
5236 if ( --parlevel < 0 ) { *s++ = c; *s = 0;
goto setstring; }
5238 else if ( chartype[c] != 1 && chartype[c] != 5
5239 && chartype[c] != 6 && c !=
'!' && c !=
'&'
5240 && c !=
'|' && c !=
'\\' ) { *s++ = c; *s = 0;
goto setstring; }
5242 if ( parlevel > 0 )
goto setstring;
5248 if ( PreEval(buff+1,&answer) == 0 )
goto setstring;
5251 if ( answer < 0 ) { *s++ =
'-'; }
5252 uanswer = LongAbs(answer);
5255 *--t = ( uanswer % 10 ) +
'0';
5258 }
while ( uanswer > 0 );
5266 if ( OpenStream(buff,PRECALCSTREAM,0,PRENOACTION) == 0 )
return(0);
5278UBYTE *PreEval(UBYTE *s, LONG *x)
5281 int tobemultiplied, tobeadded = 1, expsign, i;
5284 while ( *s ==
' ' || *s ==
'\t' ) s++;
5286 if ( *s ==
'+' || *s ==
'-' ) {
5287 if ( *s ==
'-' ) tobeadded = -1;
5290 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5291 if ( *s ==
'-' ) tobeadded = -tobeadded;
5297 while ( *s ==
' ' || *s ==
'\t' ) s++;
5298 if ( *s <=
'9' && *s >=
'0' ) {
5303 else if ( *s ==
'(' || *s ==
'{' ) {
5304 if ( ( t = PreEval(s+1,&y) ) == 0 )
return(0);
5308 while ( *s ==
' ' || *s ==
'\t' ) s++;
5310 while ( *s ==
'^' || *s ==
'!' ) {
5312 if ( s[-1] ==
'!' ) {
5313 while ( *s ==
' ' || *s ==
'\t' ) s++;
5315 MesPrint(
"@Negative value in preprocessor factorial: %l",y);
5318 else if ( y == 0 ) y = 1;
5321 while ( z > 0 ) { y = y*z; z--; }
5325 else if ( *s ==
'%' ) {
5327 while ( *s ==
' ' || *s ==
'\t' ) s++;
5330 MesPrint(
"@Illegal value in preprocessor logarithm: %l",z);
5334 while ( z ) { y++; z >>= 1; }
5337 else if ( *s ==
'/' ) {
5340 while ( *s ==
' ' || *s ==
'\t' ) s++;
5343 MesPrint(
"@Illegal value in preprocessor square root: %l",z);
5349 while ( zz ) { yy++; zz >>= 1; }
5350 zz = z >> (yy/2); i = 10; y = 0;
5352 yy = zz/2 + z/(2*zz); i--;
5353 if ( y == yy )
break;
5355 }
while ( y != yy && i > 0 );
5356 while ( y*y < z ) y++;
5357 while ( y*y > z ) y--;
5359 else if ( z >= 4 ) y = 2;
5360 else if ( z == 0 ) y = 0;
5364 while ( *s ==
' ' || *s ==
'\t' ) s++;
5365 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5366 if ( *s ==
'-' ) expsign = -expsign;
5368 if ( *s <=
'9' && *s >=
'0' ) {
5371 else if ( *s ==
'(' || *s ==
'{' ) {
5372 if ( ( t = PreEval(s+1,&z) ) == 0 )
return(0);
5376 while ( *s ==
' ' || *s ==
'\t' ) s++;
5379 if ( tobemultiplied == 0 ) {
5380 if ( expsign < 0 ) a = 1/y;
5384 if ( tobemultiplied > 2 && expsign != 1 ) {
5385 MesPrint(
"&Incorrect use of ^ with & or |. Use brackets!");
5388 tobemultiplied *= expsign;
5389 if ( tobemultiplied == 1 ) a *= y;
5390 else if ( tobemultiplied == 3 ) a &= y;
5391 else if ( tobemultiplied == 4 ) a |= y;
5393 if ( y == 0 || tobemultiplied == -2 ) {
5394 MesPrint(
"@Division by zero in preprocessor calculator");
5397 if ( tobemultiplied == 2 ) a %= y;
5401 if ( *s ==
'%' ) tobemultiplied = 2;
5402 else if ( *s ==
'*' ) tobemultiplied = 1;
5403 else if ( *s ==
'/' ) tobemultiplied = -1;
5404 else if ( *s ==
'&' ) tobemultiplied = 3;
5405 else if ( *s ==
'|' ) tobemultiplied = 4;
5410 if ( tobeadded >= 0 ) ux += ua;
5412 *x = ULongToLong(ux);
5413 if ( *s ==
')' || *s ==
'}' )
return(s+1);
5414 else if ( *s ==
'-' || *s ==
'+' ) { tobeadded = 1;
break; }
5428void AddToPreTypes(
int type)
5430 if ( AP.NumPreTypes >= AP.MaxPreTypes ) {
5431 int i, *newlist = (
int *)Malloc1(
sizeof(
int)*(2*AP.MaxPreTypes+1)
5432 ,
"preprocessor type lists");
5433 for ( i = 0; i <= AP.MaxPreTypes; i++ ) newlist[i] = AP.PreTypes[i];
5434 M_free(AP.PreTypes,
"preprocessor type lists");
5435 AP.PreTypes = newlist;
5436 AP.MaxPreTypes = 2*AP.MaxPreTypes;
5438 AP.PreTypes[++AP.NumPreTypes] = type;
5446void MessPreNesting(
int par)
5448 MesPrint(
"@(%d)Illegal nesting of %#if, %#do, %#procedure and/or %#switch",par);
5469int DoPreAddSeparator(UBYTE *s)
5471 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5472 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5473 for(;*s !=
'\0';s++){
5474 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5481 set_set(*s,AC.separators);
5494int DoPreRmSeparator(UBYTE *s)
5496 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5497 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5498 for(;*s !=
'\0';s++){
5499 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5500 set_del(*s,AC.separators);
5511int DoExternal(UBYTE *s)
5513#ifdef WITHEXTERNALCHANNEL
5519 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5520 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5521 if ( AP.preError )
return(0);
5523#ifdef WITHEXTERNALCHANNEL
5524 while ( *s ==
' ' || *s ==
'\t' ) s++;
5528 if ( chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5530 MesPrint(
"@Can't finde closing \"");
5532 case 0:
case 1:
continue;
5537 MesPrint(
"@Illegal name of preprocessor variable to store external channel");
5541 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5545 MesPrint(
"@Illegal external command");
5551 externalD=openExternalChannel(
5559 Error1(
"Can't start external program",s);
5566 NumToStr(buf,externalD);
5567 if (
PutPreVar(prevar,buf,0,1) < 0 )
return(-1);
5570 AX.currentExternalChannel=externalD;
5572 if(AX.currentPrompt!=0){
5573 if(setTerminatorForExternalChannel( (
char *)AX.currentPrompt)){
5574 MesPrint(
"@Prompt is too long");
5578 setKillModeForExternalChannel(AX.killSignal,AX.killWholeGroup);
5582 Error0(
"External channel: not implemented on this computer/system");
5593int DoPrompt(UBYTE *s)
5595#ifndef WITHEXTERNALCHANNEL
5598 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5599 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5601#ifdef WITHEXTERNALCHANNEL
5602 while ( *s ==
' ' || *s ==
'\t' ) s++;
5603 if ( AX.currentPrompt )
5604 M_free(AX.currentPrompt,
"external channel prompt");
5606 AX.currentPrompt = (UBYTE *)strDup1((UBYTE *)
"",
"external channel prompt");
5608 AX.currentPrompt = strDup1(s,
"external channel prompt");
5609 if( setTerminatorForExternalChannel( (
char *)AX.currentPrompt) > 0 ){
5610 MesPrint(
"@Prompt is too long");
5616 Error0(
"External channel: not implemented on this computer/system");
5626int DoSetExternal(UBYTE *s)
5628#ifdef WITHEXTERNALCHANNEL
5633 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5634 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5635 if ( AP.preError )
return(0);
5637#ifdef WITHEXTERNALCHANNEL
5638 while ( *s ==
' ' || *s ==
'\t' ) s++;
5639 while ( chartype[*s] == 1 ) { n = 10*n + *s++ -
'0'; }
5640 while ( *s ==
' ' || *s ==
'\t' ) s++;
5642 MesPrint(
"@setexternal: number expected");
5645 if(selectExternalChannel(n)<0){
5646 MesPrint(
"@setexternal: invalid number");
5649 AX.currentExternalChannel=n;
5652 Error0(
"External channel: not implemented on this computer/system");
5661static FORM_INLINE UBYTE *pickupword(UBYTE *s)
5664 for(;*s>
' ';s++)
switch(*s){
5675static inline int strINCmp(UBYTE *a, UBYTE *b,
int n)
5677 for(;n>0;n--)
if(tolower(*a++)!=tolower(*b++))
5683#define KILLALL "killall"
5684#define DAEMON "daemon"
5685#define SHELL "shell"
5686#define STDERR "stderr"
5688#define TRUE_EXPR "true"
5689#define FALSE_EXPR "false"
5690#define NOSHELL "noshell"
5691#define TERMINAL "terminal"
5696int DoSetExternalAttr(UBYTE *s)
5698#ifdef WITHEXTERNALCHANNEL
5704 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5705 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5706 if ( AP.preError )
return(0);
5708#ifdef WITHEXTERNALCHANNEL
5711 while ( *s ==
' ' || *s ==
'\t' ) s++;
5712 s=pickupword(nam=s);
5714 while ( *s ==
' ' || *s ==
'\t' ) s++;
5716 MesPrint(
"@External channel:'=' expected instead of %s",s-1);
5720 while ( *s ==
' ' || *s ==
'\t' ) s++;
5727 while ( *s ==
' ' || *s ==
'\t' ) s++;
5728 if( (*s ==
',')||(*s ==
'\n')||(*s ==
';')||(*s ==
'\0') ){
5735 while ( *s ==
' ' || *s ==
'\t' ) s++;
5737 if(strINCmp((UBYTE *)SHELL,nam,lnam)==0){
5738 if(AX.shellname!=NULL)
5739 M_free(AX.shellname,
"external channel shellname");
5740 if(strINCmp((UBYTE *)NOSHELL,val,lval)==0)
5744 b=ch=AX.shellname=Malloc1(lval+1,
"external channel shellname");
5749 }
else if(strINCmp((UBYTE *)DAEMON,nam,lnam)==0){
5750 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5752 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5755 MesPrint(
"@External channel:true or false expected for %s",DAEMON);
5758 }
else if(strINCmp((UBYTE *)KILLALL,nam,lnam)==0){
5759 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5760 AX.killWholeGroup = 1;
5761 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5762 AX.killWholeGroup = 0;
5764 MesPrint(
"@External channel: true or false expected for %s",KILLALL);
5767 }
else if(strINCmp((UBYTE *)KILL,nam,lnam)==0){
5769 for(i=0;i<lval;i++) {
5770 if( *val>=
'0' && *val<=
'9' )
5771 n = 10*n + *val++ -
'0';
5773 MesPrint(
"@External channel: number expected for %s",KILL);
5778 }
else if(strINCmp((UBYTE *)STDERR,nam,lnam)==0){
5779 if( AX.stderrname != NULL ) {
5780 M_free(AX.stderrname,
"external channel stderrname");
5782 if(strINCmp((UBYTE *)TERMINAL,val,lval)==0)
5783 AX.stderrname = NULL;
5786 b=ch=AX.stderrname=Malloc1(lval+1,
"external channel stderrname");
5793 MesPrint(
"@External channel: unrecognized attribute",nam);
5796 }
while(*s++ ==
',');
5797 if( (*(s-1)>
' ')&&(*(s-1)!=
';') ){
5798 MesPrint(
"@External channel: syntax error: %s",s-1);
5803 Error0(
"External channel: not implemented on this computer/system");
5813int DoRmExternal(UBYTE *s)
5815#ifdef WITHEXTERNALCHANNEL
5820 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5821 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5822 if ( AP.preError )
return(0);
5824#ifdef WITHEXTERNALCHANNEL
5825 while ( *s ==
' ' || *s ==
'\t' ) s++;
5826 if( chartype[*s] == 1 ){
5827 for(n=0; chartype[*s] == 1 ; s++) { n = 10*n + *s -
'0'; }
5828 while ( *s ==
' ' || *s ==
'\t' ) s++;
5831 MesPrint(
"@rmexternal: invalid number");
5836 closeAllExternalChannels();
5837 AX.currentExternalChannel=0;
5841 n=AX.currentExternalChannel;
5844 closeExternalChannel(n);
5846 if (n == AX.currentExternalChannel)
5847 AX.currentExternalChannel=0;
5850 Error0(
"External channel: not implemented on this computer/system");
5878int DoFromExternal(UBYTE *s)
5880#ifdef WITHEXTERNALCHANNEL
5883 int withNoList=AC.NoShowInput;
5884 int oldpreassignflag;
5888 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5889 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5890 if ( AP.preError )
return(0);
5891#ifdef WITHEXTERNALCHANNEL
5895 while ( *s ==
' ' || *s ==
'\t' ) s++;
5897 if ( *s ==
'-' || *s ==
'+' ) {
5903 while ( *s ==
' ' || *s ==
'\t' ) s++;
5910 if ( *s==
'$' || chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5912 MesPrint(
"@Can't finde closing \"");
5914 case 0:
case 1:
continue;
5919 MesPrint(
"@Illegal name to store output of external channel");
5923 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5927 if( chartype[*s] == 1 ){
5928 for(lbuf=0; chartype[*s] == 1 ; s++) { lbuf = 10*lbuf + *s -
'0'; }
5929 while ( *s ==
' ' || *s ==
'\t' ) s++;
5931 if( (*s!=
'\0')||(lbuf<0) ){
5932 MesPrint(
"@Illegal buffer length in fromexternal");
5937 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5940 if(selectExternalChannel(AX.currentExternalChannel)){
5941 MesPrint(
"@No current external channel");
5952 buf=Malloc1( (lbuf=255)+1,
"Fromexternal");
5958 for(i=0;(cc=getcFromExtChannel())>0;i++){
5962 UBYTE *tmp=Malloc1( (lbuf*=2)+1,
"Fromexternal");
5963 for(j=0;j<i;j++)tmp[j]=buf[j];
5964 M_free(buf,
"Fromexternal");
5971 MesPrint(
"@No current external channel");
5979 buf=Malloc1(lbuf+1,
"Fromexternal");
5980 for(i=0; i<lbuf;i++){
5986 if( (cc=getcFromExtChannel())<1 )
5999 while(getcFromExtChannel()>0);
6001 MesPrint(
"@No current external channel");
6008 int oldNumPotModdollars = NumPotModdollars;
6010 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
6011 AC.RhsExprInModuleFlag = 0;
6015 UBYTE *pbuf=Malloc1(StrLen(prevar)+1+lbuf+1,
"Fromexternal to dollar");
6018 while(*b!=
'\0'){*c++ = *b++;}
6021 while( (*c++=*b++)!=
'\0' );
6022 oldpreassignflag = AP.PreAssignFlag;
6023 AP.PreAssignFlag = 1;
6024 if ( ( cc = CompileStatement(pbuf) ) || ( cc = CatchDollar(0) ) ) {
6025 Error1(
"External channel: can't asign output to dollar variable ",prevar);
6027 AP.PreAssignFlag = oldpreassignflag;
6028 NumPotModdollars = oldNumPotModdollars;
6030 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
6032 M_free(pbuf,
"Fromexternal to dollar");
6037 M_free(buf,
"Fromexternal");
6038 if ( cc )
return(-1);
6042 if ( OpenStream(s,EXTERNALCHANNELSTREAM,0,PRENOACTION) == 0 )
return(-1);
6044 AC.NoShowInput = withNoList;
6048 Error0(
"External channel: not implemented on this computer/system");
6059#ifdef WITHEXTERNALCHANNEL
6062LONG WriteToExternalChannel(
int handle, UBYTE *buffer, LONG size)
6067 if(writeBufToExtChannel((
char*)buffer,size))
6073int DoToExternal(UBYTE *s)
6075#ifdef WITHEXTERNALCHANNEL
6077 LONG (*OldWrite)(
int handle, UBYTE *buffer, LONG size) = WriteFile;
6082 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6083 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6084 if ( AP.preError )
return(0);
6085#ifdef WITHEXTERNALCHANNEL
6087 h.oldsilent=AM.silent;
6088 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
6089 h.newhandle = h.oldhandle = AC.LogHandle;
6090 h.oldprinttype = AO.PrintType;
6092 WriteFile=&WriteToExternalChannel;
6094 while ( *s ==
' ' || *s ==
'\t' ) s++;
6096 if(AX.currentExternalChannel==0){
6097 MesPrint(
"@No current external channel");
6098 goto DoToExternalReady;
6101 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
6102 selectExternalChannel(AX.currentExternalChannel);
6104 ret=writeToChannel(EXTERNALCHANNELOUT,s,&h);
6109 Error0(
"External channel: not implemented on this computer/system");
6120UBYTE *defineChannel(UBYTE *s,
HANDLERS *h)
6129 while ( *s && *s !=
'>' ) {
6130 if ( *s ==
'\\' ) s++;
6134 MesPrint(
"@Improper termination of filename");
6140 h->newhandle = GetChannel((
char *)name,0);
6143 else if ( AC.LogHandle >= 0 ) {
6144 h->newhandle = AC.LogHandle;
6155int writeToChannel(
int wtype, UBYTE *s,
HANDLERS *h)
6157 UBYTE *to, *fstring, *ss, *sss, *s1, c, c1;
6158 WORD num, number, nfac;
6159 WORD oldOptimizationLevel;
6160 UBYTE Out[MAXLINELENGTH+14], *stopper;
6167 while ( *s ==
',' || *s ==
' ' ) s++;
6169 MesPrint(
"@No format string present");
6172 s++; fstring = to = s;
6178 if ( *s ==
'\\' ) *to++ = *s++;
6180 else if ( *s ==
'"' ) *to++ = *s++;
6181 else { *to++ =
'\\'; *to++ = *s++; }
6183 else if ( *s ==
'"' )
break;
6187 MesPrint(
"@No closing \" in format string");
6191 if ( AC.LineLength > 20 && AC.LineLength <= MAXLINELENGTH ) stopper = Out + AC.LineLength;
6192 else stopper = Out + MAXLINELENGTH;
6199 AC.LogHandle = h->newhandle;
6200 AM.FileOnlyFlag = h->newlogonly;
6201 if ( h->newhandle >= 0 ) {
6202 AO.PrintType |= PRINTLFILE;
6204 while ( *fstring ) {
6205 if ( to >= stopper ) {
6206 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6210 WriteString(wtype,Out,num);
6212 if ( AC.OutputMode == FORTRANMODE
6213 || AC.OutputMode == PFORTRANMODE ) {
6215 for ( i = 0; i < number; i++ ) *to++ =
' ';
6219 if ( *fstring ==
'\\' ) {
6221 if ( *fstring ==
'n' ) {
6223 WriteString(wtype,Out,num);
6227 else if ( *fstring ==
't' ) { *to++ =
'\t'; fstring++; }
6228 else if ( *fstring ==
'b' ) { *to++ =
'\\'; fstring++; }
6229 else *to++ = *fstring++;
6231 else if ( *fstring ==
'%' ) {
6235 if ( *fstring ==
'd' ) {
6239 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6241 while ( *s ==
'+' || *s ==
'-' ) {
6242 if ( *s ==
'-' ) sign = -sign;
6245 dig = 0; ss = s;
if ( sign < 0 ) { ss--; *ss =
'-'; dig++; }
6246 while ( *s >=
'0' && *s <=
'9' ) { s++; dig++; }
6249 if ( to >= stopper ) {
6251 WriteString(wtype,Out,num);
6254 if ( *ss ==
'\\' ) ss++;
6259 if ( number < dig ) { dig = number; ss = s - dig; }
6260 while ( number > dig ) {
6261 if ( to >= stopper ) {
6263 WriteString(wtype,Out,num);
6266 *to++ =
' '; number--;
6269 if ( to >= stopper ) {
6271 WriteString(wtype,Out,num);
6274 if ( *ss ==
'\\' ) ss++;
6280 else if ( *fstring ==
'$' ) {
6282 number = AO.OutSkip;
6284 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6285 if ( AC.OutputMode == FORTRANMODE
6286 || AC.OutputMode == PFORTRANMODE ) {
6290nodollar: MesPrint(
"@$-variable expected in #write instruction");
6291 AM.FileOnlyFlag = h->oldlogonly;
6292 AC.LogHandle = h->oldhandle;
6293 AO.PrintType = h->oldprinttype;
6294 AM.silent = h->oldsilent;
6298 while ( chartype[*s] <= 1 ) s++;
6299 if ( s == ss )
goto nodollar;
6301 num = GetDollar(ss);
6303 MesPrint(
"@#write instruction: $%s has not been defined",ss);
6304 AM.FileOnlyFlag = h->oldlogonly;
6305 AC.LogHandle = h->oldhandle;
6306 AO.PrintType = h->oldprinttype;
6307 AM.silent = h->oldsilent;
6312 if ( Dollars[num].nfactors <= 0 ) {
6314 MesPrint(
"@#write instruction: $%s has not been factorized",ss);
6315 AM.FileOnlyFlag = h->oldlogonly;
6316 AC.LogHandle = h->oldhandle;
6317 AO.PrintType = h->oldprinttype;
6318 AM.silent = h->oldsilent;
6324 nfac = GetDollarNumber(&s,Dollars+num);
6326 if ( Dollars[num].nfactors == 1 && nfac == 1 )
goto writewhole;
6328 if ( ( dolalloc = WriteDollarFactorToBuffer(num,nfac,0) ) == 0 ) {
6329 AM.FileOnlyFlag = h->oldlogonly;
6330 AC.LogHandle = h->oldhandle;
6331 AO.PrintType = h->oldprinttype;
6332 AM.silent = h->oldsilent;
6337 else if ( *s && *s !=
' ' && *s !=
',' && *s !=
'\t' ) {
6338 MesPrint(
"@#write instruction: illegal characters after $-variable");
6339 AM.FileOnlyFlag = h->oldlogonly;
6340 AC.LogHandle = h->oldhandle;
6341 AO.PrintType = h->oldprinttype;
6342 AM.silent = h->oldsilent;
6347 if ( ( dolalloc = WriteDollarToBuffer(num,0) ) == 0 ) {
6348 AM.FileOnlyFlag = h->oldlogonly;
6349 AC.LogHandle = h->oldhandle;
6350 AO.PrintType = h->oldprinttype;
6351 AM.silent = h->oldsilent;
6358 if ( to >= stopper ) {
6359 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6363 WriteString(wtype,Out,num);
6365 for ( i = 0; i < number; i++ ) *to++ =
' ';
6366 if ( AC.OutputMode == FORTRANMODE
6367 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6369 if ( chartype[*ss] > 3 ) { *to++ = *ss++; }
6371 sss = ss;
while ( chartype[*ss] <= 3 ) ss++;
6372 if ( ( to + (ss-sss) ) >= stopper ) {
6373 if ( (ss-sss) >= (stopper-Out) ) {
6374 if ( ( to - stopper ) < 10 ) {
6375 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6379 WriteString(wtype,Out,num);
6381 for ( i = 0; i < number; i++ ) *to++ =
' ';
6382 if ( AC.OutputMode == FORTRANMODE
6383 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6385 while ( (ss-sss) >= (stopper-Out) ) {
6386 while ( to < stopper-1 ) {
6389 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6396 WriteString(wtype,Out,num);
6398 if ( AC.OutputMode == FORTRANMODE
6399 || AC.OutputMode == PFORTRANMODE ) {
6400 for ( i = 0; i < number; i++ ) *to++ =
' ';
6406 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6410 WriteString(wtype,Out,num);
6412 for ( i = 0; i < number; i++ ) *to++ =
' ';
6413 if ( AC.OutputMode == FORTRANMODE
6414 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6417 while ( sss < ss ) *to++ = *sss++;
6421 M_free(dolalloc,
"written dollar");
6425 else if ( *fstring ==
's' ) {
6427 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6431 if ( *s ==
'\\' ) s++;
6432 else if ( *s ==
'"' )
break;
6436 MesPrint(
"@#write instruction: Missing \" in string");
6437 AM.FileOnlyFlag = h->oldlogonly;
6438 AC.LogHandle = h->oldhandle;
6439 AO.PrintType = h->oldprinttype;
6440 AM.silent = h->oldsilent;
6444 if ( to >= stopper ) {
6446 WriteString(wtype,Out,num);
6449 if ( *ss ==
'\\' ) ss++;
6456 while ( *s && *s !=
',' ) {
6457 if ( *s ==
'\\' ) { s++; sss = s+1; }
6460 while ( s > sss+1 && ( s[-1] ==
' ' || s[-1] ==
'\t' ) ) s--;
6462 if ( to >= stopper ) {
6464 WriteString(wtype,Out,num);
6467 if ( *ss ==
'\\' ) ss++;
6472 else if ( *fstring ==
'X' ) {
6474 if ( cbuf[AM.sbufnum].numrhs > 0 ) {
6478 UBYTE *s = GetPreVar(AM.oldnumextrasymbols,0);
6480 while ( *s >=
'0' && *s <=
'9' ) x = 10*x + *s++ -
'0';
6482 PrintSubtermList(1,x);
6484 PrintSubtermList(1,cbuf[AM.sbufnum].numrhs);
6487 else if ( *fstring ==
'O' ) {
6488 number = AO.OutSkip;
6494 if ( AO.OptimizeResult.code == NULL && AO.OptimizationLevel != 0 ) {
6495 MesPrint(
"@In #write instruction: no optimization results available!");
6499 WriteString(wtype,Out,num);
6501 if ( AO.OptimizationLevel != 0 ) {
6502 WORD oldoutskip = AO.OutSkip;
6503 AO.OutSkip = number;
6505 AO.OutSkip = oldoutskip;
6508 else if ( *fstring ==
'e' || *fstring ==
'E' ) {
6509 if ( *fstring ==
'E'
6510 || AC.OutputMode == FORTRANMODE
6511 || AC.OutputMode == PFORTRANMODE ) nosemi = 1;
6514 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6515 if ( chartype[*s] != 0 && *s !=
'[' ) {
6516noexpr: MesPrint(
"@expression name expected in #write instruction");
6517 AM.FileOnlyFlag = h->oldlogonly;
6518 AC.LogHandle = h->oldhandle;
6519 AO.PrintType = h->oldprinttype;
6520 AM.silent = h->oldsilent;
6524 if ( ( s =
SkipAName(ss) ) == 0 || s[-1] ==
'_' )
goto noexpr;
6525 s1 = s; c = c1 = *s1;
6529 AO.CurBufWrt = s1+1;
6533 MesPrint(
"@Illegal () specifier in expression name in #write");
6534 AM.FileOnlyFlag = h->oldlogonly;
6535 AC.LogHandle = h->oldhandle;
6536 AO.PrintType = h->oldprinttype;
6537 AM.silent = h->oldsilent;
6541 else AO.CurBufWrt = (UBYTE *)underscore;
6544 if ( num > 0 ) WriteUnfinString(wtype,Out,num);
6546 oldOptimizationLevel = AO.OptimizationLevel;
6547 AO.OptimizationLevel = 0;
6548 if ( WriteOne(ss,(
int)num,nosemi,plus) < 0 ) {
6549 AM.FileOnlyFlag = h->oldlogonly;
6550 AC.LogHandle = h->oldhandle;
6551 AO.PrintType = h->oldprinttype;
6552 AM.silent = h->oldsilent;
6555 AO.OptimizationLevel = oldOptimizationLevel;
6557 if ( s > s1 ) *s++ = c;
6562 else if ( ( *fstring ==
'f' ) || ( *fstring ==
'F' ) ) {
6564 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6566 while ( *s && *s !=
',' ) {
6567 if ( *s ==
'\\' ) s++;
6571 s1 = LoadInputFile(ss,HEADERFILE);
6578 ss = s1;
while ( *ss ) ss++;
6580 WriteString(wtype,s1,n);
6581 M_free(s1,
"copy file");
6583 else if ( *fstring ==
'F' ) {
6585 MesPrint(
"@Error in #write: could not open file %s",ss);
6587 goto ReturnWithError;
6591 else if ( *fstring ==
'%' ) {
6594 else if ( FG.cTable[*fstring] == 1 ) {
6596 while ( FG.cTable[*fstring] == 1 ) {
6597 number = 10*number + *fstring++ -
'0';
6599 if ( *fstring ==
'O' )
goto dooptim;
6600 else if ( *fstring ==
'd' )
goto donumber;
6601 else if ( *fstring ==
'$' )
goto dodollar;
6602 else if ( *fstring ==
't' ) {
6603 if ( number < (WORD)(stopper-Out) ) {
6604 while ( (WORD)(to-Out) < number ) *to++ =
' ';
6608 else if ( *fstring ==
'X' || *fstring ==
'x' ) {
6609 if ( number > 0 && number <= cbuf[AM.sbufnum].numrhs ) {
6610 UBYTE buffer[80], *out, *old1, *old2, *old3;
6612 if ( *fstring ==
'X' ) {
6613 out = StrCopy((UBYTE *)AC.extrasym,buffer);
6614 if ( AC.extrasymbols == 0 ) {
6615 out = NumCopy(number,out);
6616 out = StrCopy((UBYTE *)
"_",out);
6618 else if ( AC.extrasymbols == 1 ) {
6619 if ( AC.OutputMode == CMODE ) {
6620 out = StrCopy((UBYTE *)
"[",out);
6621 out = NumCopy(number,out);
6622 out = StrCopy((UBYTE *)
"]",out);
6625 out = StrCopy((UBYTE *)
"(",out);
6626 out = NumCopy(number,out);
6627 out = StrCopy((UBYTE *)
")",out);
6630 out = StrCopy((UBYTE *)
"=",out);
6632 while ( ss < out ) {
6633 if ( to >= stopper ) {
6635 WriteString(wtype,Out,num);
6641 term = cbuf[AM.sbufnum].rhs[number];
6648 old2 = AO.OutputLine;
6651 AO.OutputLine = Out;
6652 AO.OutStop = Out + AC.LineLength;
6654 if ( WriteInnerTerm(term,first) ) Terminate(-1);
6658 to = Out + (AO.OutFill-AO.OutputLine);
6660 AO.OutputLine = old2;
6667 goto IllegControlSequence;
6670 else if ( *fstring ==
'+' ) {
6671 plus = 1;
goto retry;
6673 else if ( *fstring == 0 ) {
6677IllegControlSequence:
6678 MesPrint(
"@Illegal control sequence in format string in #write instruction");
6680 AM.FileOnlyFlag = h->oldlogonly;
6681 AC.LogHandle = h->oldhandle;
6682 AO.PrintType = h->oldprinttype;
6683 AM.silent = h->oldsilent;
6696 if(wtype==EXTERNALCHANNELOUT){
6698 WriteUnfinString(wtype,Out,num);
6701 WriteString(wtype,Out,num);
6705 AM.FileOnlyFlag = h->oldlogonly;
6706 AC.LogHandle = h->oldhandle;
6707 AO.PrintType = h->oldprinttype;
6708 AM.silent = h->oldsilent;
6720int DoFactDollar(UBYTE *s)
6723 WORD numdollar, *oldworkpointer;
6725 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6726 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6727 while ( *s ==
' ' || *s ==
'\t' ) s++;
6729 if ( GetName(AC.dollarnames,s+1,&numdollar,NOAUTO) != CDOLLAR ) {
6730 MesPrint(
"@%s is undefined",s);
6735 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6739 oldworkpointer = AT.WorkPointer;
6740 if ( DollarFactorize(BHEAD numdollar) )
return(-1);
6741 AT.WorkPointer = oldworkpointer;
6745 else if ( ParenthesesTest(s) )
return(-1);
6747 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6757WORD GetDollarNumber(UBYTE **inp,
DOLLARS d)
6759 UBYTE *s = *inp, c, *name;
6760 WORD number, nfac, *w;
6765 while ( FG.cTable[*s] < 2 ) s++;
6767 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6768 MesPrint(
"@dollar in #write should have been defined previously");
6772 dd = Dollars + number;
6775 nfac = GetDollarNumber(inp,dd);
6778 MesPrint(
"@Illegal factor for dollar variable");
6783 if ( dd->nfactors > d->nfactors ) {
6785 MesPrint(
"@Factor number for dollar variable too large");
6788 return(dd->nfactors);
6790 w = dd->factors[nfac-1].where;
6792 if ( dd->factors[nfac-1].value > d->nfactors ||
6793 dd->factors[nfac-1].value < 0 )
goto TooBig;
6794 return(dd->factors[nfac-1].value);
6796 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6797 && w[1] <= d->nfactors )
return(w[1]);
6798 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6800 MesPrint(
"@Illegal factor number for dollar variable");
6804 if ( dd->type == DOLZERO ) {
6807 else if ( dd->type == DOLTERMS || dd->type == DOLNUMBER ) {
6809 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6810 && w[1] <= d->nfactors )
return(w[1]);
6811 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6817 else if ( FG.cTable[*s] == 1 ) {
6818 WORD x = *s++ -
'0';
6819 while ( FG.cTable[*s] == 1 ) {
6820 x = 10*x + *s++ -
'0';
6821 if ( x > d->nfactors ) {
6822 MesPrint(
"@Factor number %d for dollar variable too large",x);
6827 MesPrint(
"@Illegal factor number for dollar variable");
6834 MesPrint(
"@Illegal factor indicator for dollar variable");
6847int DoSetRandom(UBYTE *s)
6850 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6851 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6852 while ( *s ==
' ' || *s ==
'\t' ) s++;
6854 while ( FG.cTable[*s] == 1 ) {
6855 x = 10*x + (*s++-
'0');
6857 while ( *s ==
' ' || *s ==
'\t' ) s++;
6861 int id, totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
6863 int id, totnum = AM.totalnumberofthreads;
6865 for (
id = 0;
id < totnum;
id++ ) {
6866 AB[id]->R.wranfseed = x;
6867 if ( AB[
id]->R.wranfia ) M_free(AB[
id]->R.wranfia,
"wranf");
6868 AB[id]->R.wranfia = 0;
6872 if ( AR.wranfia ) M_free(AR.wranfia,
"wranf");
6878 MesPrint(
"@proper syntax is #SetRandom number");
6890int DoOptimize(UBYTE *s)
6896 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6897 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6900 if ( *s != 0 && *s !=
';' ) {
6901 MesPrint(
"@proper syntax is #Optimize,expression");
6905 if ( GetName(AC.exprnames,exprname,&numexpr,NOAUTO) != CEXPRESSION ) {
6906 MesPrint(
"@%s is not an expression",exprname);
6909 else if ( AP.preError == 0 ) {
6913 WORD *term = AT.WorkPointer;
6915 if ( AO.OptimizationLevel == 0 )
return(0);
6916 switch ( e->status ) {
6917 case LOCALEXPRESSION:
6918 case GLOBALEXPRESSION:
6921 MesPrint(
"@Expression %s is not an active unhidden local or global expression.",exprname);
6926 if ( PF.me == MASTER )
6929 for ( i = NumExpressions-1; i >= 0; i-- ) {
6930 AS.OldOnFile[i] = Expressions[i].onfile;
6931 AS.OldNumFactors[i] = Expressions[i].numfactors;
6932 AS.Oldvflags[i] = Expressions[i].vflags;
6933 Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
6935 for ( i = 0; i < NumExpressions; i++ ) {
6936 if ( i == numexpr ) {
6938 GetPreVar((UBYTE *)
"EXTRASYMBOLS_",0),0,1);
6940 AO.OptimizeResult.nameofexpr = strDup1(exprname,
"optimize expression name");
6944 if ( PF.me == MASTER ) {
6946 e = Expressions + i;
6947 switch ( e->status ) {
6948 case LOCALEXPRESSION:
6949 case SKIPLEXPRESSION:
6950 case DROPLEXPRESSION:
6951 case DROPPEDEXPRESSION:
6952 case GLOBALEXPRESSION:
6953 case SKIPGEXPRESSION:
6954 case DROPGEXPRESSION:
6955 case HIDELEXPRESSION:
6956 case HIDEGEXPRESSION:
6957 case DROPHLEXPRESSION:
6958 case DROPHGEXPRESSION:
6959 case INTOHIDELEXPRESSION:
6960 case INTOHIDEGEXPRESSION:
6966 SetScratch(AR.infile,&(e->onfile));
6967 if ( GetTerm(BHEAD term) <= 0 ) {
6968 MesPrint(
"@Expression %d has problems reading from scratchfile",i);
6973 SeekScratch(AR.outfile,&position);
6974 e->onfile = position;
6975 *AM.S0->sBuffer = 0; firstterm = -1;
6977 WORD *oldipointer = AR.CompressPointer;
6978 WORD *comprtop = AR.ComprTop;
6979 AR.ComprTop = AM.S0->sTop;
6980 AR.CompressPointer = AM.S0->sBuffer;
6981 if ( firstterm > 0 ) {
6982 if (
PutOut(BHEAD term,&position,AR.outfile,1) < 0 )
goto DoSerr;
6984 else if ( firstterm < 0 ) {
6985 if (
PutOut(BHEAD term,&position,AR.outfile,0) < 0 )
goto DoSerr;
6989 if (
PutOut(BHEAD term,&position,AR.outfile,-1) < 0 )
goto DoSerr;
6992 AR.CompressPointer = oldipointer;
6993 AR.ComprTop = comprtop;
6994 }
while ( GetTerm(BHEAD term) );
6995 if (
FlushOut(&position,AR.outfile,1) ) {
6997 MesPrint(
"@Expression %d has problems writing to scratchfile",i);
7023int DoClearOptimize(UBYTE *s)
7025 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7026 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7043int DoSkipExtraSymbols(UBYTE *s)
7045 CBUF *C = cbuf + AM.sbufnum;
7046 WORD tt = 0, j = 0, oldval = AO.OptimizeResult.minvar;
7047 if ( AO.OptimizeResult.code == NULL )
return(0);
7048 if ( AO.OptimizationLevel == 0 )
return(0);
7049 while ( *s ==
',' ) s++;
7051 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
7054 while ( *s <=
'9' && *s >=
'0' ) j = 10*j + *s++ -
'0';
7056 MesPrint(
"@Illegal use of #SkipExtraSymbols instruction");
7059 AO.OptimizeResult.minvar += j;
7060 if ( AO.OptimizeResult.minvar > AO.OptimizeResult.maxvar )
7061 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
7063 j = AO.OptimizeResult.minvar - oldval;
7068 InsTree(AM.sbufnum,C->numrhs);
7082int DoPreReset(UBYTE *s)
7085 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7086 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7087 while ( *s ==
' ' || *s ==
'\t' ) s++;
7089 MesPrint(
"@proper syntax is #Reset variable");
7093 while ( FG.cTable[*s] == 0 ) s++;
7095 if ( ( StrICmp(ss,(UBYTE *)
"timer") == 0 )
7096 || ( StrICmp(ss,(UBYTE *)
"stopwatch") == 0 ) ) {
7098 AP.StopWatchZero = GetRunningTime();
7103 MesPrint(
"@proper syntax is #Reset variable");
7113static int DoAddPath(UBYTE *s,
int bPrepend)
7117 UBYTE *path, *path_end, *current_dir, *current_dir_end, *NewPath, *t;
7120 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7121 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7124 while ( *s ==
' ' || *s ==
'\t' ) s++;
7127 while ( *s && *s !=
'"' ) {
7128 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
7129 if ( !s[1] )
goto ImproperPath;
7134 if ( *s !=
'"' )
goto ImproperPath;
7139 while ( *s && *s !=
' ' && *s !=
'\t' ) {
7140 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
7141 if ( !s[1] )
goto ImproperPath;
7148 if ( path == path_end )
goto ImproperPath;
7149 while ( *s ==
' ' || *s ==
'\t' ) s++;
7150 if ( *s )
goto ImproperPath;
7154 if ( path[0] == SEPARATOR ) {
7158 else if ( chartype[path[0]] == 0 && path[1] ==
':' ) {
7165 if ( !AC.CurrentStream )
goto FileNameUnavailable;
7166 if ( AC.CurrentStream->type != FILESTREAM && AC.CurrentStream->type != REVERSEFILESTREAM )
goto FileNameUnavailable;
7167 if ( !AC.CurrentStream->name )
goto FileNameUnavailable;
7168 s = current_dir = current_dir_end = AC.CurrentStream->name;
7170 if ( SEPARATOR !=
'\\' && *s ==
'\\' && s[1] ) {
7174 if ( *s == SEPARATOR ) {
7175 current_dir_end = s;
7181 current_dir = current_dir_end = NULL;
7185 n = path_end - path;
7186 if ( AM.Path ) n += StrLen(AM.Path) + 1;
7187 if ( current_dir != current_dir_end ) n+= current_dir_end - current_dir + 1;
7188 s = NewPath = (UBYTE *)Malloc1(n + 1,
"add path");
7192 if ( current_dir != current_dir_end ) {
7194 while ( t != current_dir_end ) *s++ = *t++;
7198 while ( t != path_end ) *s++ = *t++;
7199 if ( AM.Path ) *s++ = PATHSEPARATOR;
7203 while ( *t ) *s++ = *t++;
7206 if ( AM.Path ) *s++ = PATHSEPARATOR;
7207 if ( current_dir != current_dir_end ) {
7209 while ( t != current_dir_end ) *s++ = *t++;
7213 while ( t != path_end ) *s++ = *t++;
7218 if ( AM.Path ) M_free(AM.Path,
"add path");
7224 MesPrint(
"@Improper syntax for %#%sPath", bPrepend ?
"Prepend" :
"Append");
7229 MesPrint(
"@Sorry, %#%sPath can't resolve the current file name from here", bPrepend ?
"Prepend" :
"Append");
7242 return DoAddPath(s, 0);
7259 return DoAddPath(s, 1);
7269int DoTimeOutAfter(UBYTE *s)
7276 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7277 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7279 while ( *s ==
' ' || *s ==
'\t' ) s++;
7281 while ( FG.cTable[*s] == 1 ) {
7282 x = 10*x + (*s++-
'0');
7284 while ( *s ==
' ' || *s ==
'\t' ) s++;
7290 MesPrint(
"@proper syntax is #TimeoutAfter number");
7294 Error0(
"#timeoutafter not implemented on this computer/system");
7321int DoNamespace(UBYTE *s)
7325 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7326 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7327 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7328 if ( FG.cTable[*s] != 0 ) {
7329 MesPrint(
"@Illegal name in #namespace instruction: %s",s);
7333 while ( FG.cTable[*s1] <= 1 ) s1++;
7335 while ( *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' ) s2++;
7337 MesPrint(
"@A #namespace instruction can only have one name with only alphanumeric characters.");
7346 namespace->name = strDup1(s,
"namespace_name");
7347 namespace->usenames = MakeNameTree();
7348 if ( AP.firstnamespace == 0 ) {
7349 namespace->previous = 0;
7350 namespace->next = 0;
7351 AP.firstnamespace =
namespace;
7352 AP.lastnamespace =
namespace;
7355 AP.lastnamespace->next =
namespace;
7356 namespace->next = 0;
7357 namespace->previous = AP.lastnamespace;
7358 AP.lastnamespace =
namespace;
7369int DoEndNamespace(UBYTE *s)
7372 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7373 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7374 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7376 MesPrint(
"@Illegal #endnamespace instruction");
7379 namespace = AP.lastnamespace;
7380 AP.lastnamespace =
namespace->previous;
7381 M_free(namespace->name,
"namespace_name");
7382 FreeNameTree(namespace->usenames);
7383 M_free(
namespace,
"namespace");
7392UBYTE *SkipName(UBYTE *s)
7394 UBYTE *t = s, *s1, c;
7395 int num = 0, block = 0;
7400 MesPrint(
"&Illegal name: '%s'",t);
7404 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) s++;
7405 if ( s1 != s )
goto witherror;
7407 else if ( *s ==
'$' ) {
7409 while ( *s ==
'_' ) { s++; num++; }
7411 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7412 if ( FG.cTable[*s] != 0 && block == 1 ) {
7414 MesPrint(
"&Illegally formed name: %s",t);
7417 if ( *s ==
'_' ) { num++; block = 1; }
7421 if ( s[-1] ==
'_' && num > 1 )
goto built;
7423 else if ( FG.cTable[*s] == 0 ) {
7425 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7426 if ( FG.cTable[*s] != 0 && block == 1 )
goto blocked;
7427 if ( *s ==
'_' ) { block = 1; num++; }
7431 if ( *s ==
'[' )
goto straight;
7432 if ( s[-1] ==
'_' && num > 1 ) {
7435 MesPrint(
"&Built in objects cannot be part of namespaces: %s",t);
7440 else if ( *s ==
'_' ) {
7441 while ( *s ==
'_' ) { s++; num++; }
7442 if ( FG.cTable[*s] == 0 ) { block = 0;
goto regular; }
7445 else if ( *s ==
'@' ) {
7447 if ( *s ==
'_' || FG.cTable[*s] == 1 ) {
7448 MesPrint(
"@Illegally formed name: %s",s-1);
7452 else if ( *s ==
'#' ) {
7454 while ( *s ==
'_' ) { s++; num++; }
7456 while ( FG.cTable[*s] <= 1 || *s ==
'_' ) {
7457 if ( FG.cTable[*s] != 0 && block == 1 )
goto blocked;
7458 if ( *s ==
'_' ) { num++; block = 1; }
7462 if ( s[-1] ==
'_' ) {
7465 MesPrint(
"&Illegally formed name: %s",t);
7470 else if ( *s ==
'<' ) {
7472 while ( *s && *s !=
'>' ) s++;
7473 if ( *s !=
'>' )
goto witherror;
7492UBYTE *ConstructName(UBYTE *s,UBYTE type)
7498 if ( AP.lastnamespace == 0 )
return(s);
7499 if ( *s ==
'@' )
return(s+1);
7500 if ( GetName(AP.lastnamespace->usenames,s,&number,NOAUTO) !=
7501 NAMENOTFOUND )
return(s);
7506 len = StrLen(s) + 1;
7507 namespace = AP.firstnamespace;
7508 while (
namespace ) {
7509 len += StrLen(namespace->name)+1;
7510 namespace = namespace->previous;
7512 if ( len > AP.fullnamesize ) {
7513 while ( len > AP.fullnamesize ) AP.fullnamesize *= 2;
7514 M_free(AP.fullname,
"AP.fullname");
7515 AP.fullname = (UBYTE *)Malloc1(AP.fullnamesize*
sizeof(UBYTE *),
"AP.fullname");
7517 namespace = AP.firstnamespace;
7522 while (
namespace ) {
7523 u =
namespace->name;
7524 while ( *u ) *t++ = *u++;
7526 namespace = namespace->previous;
7528 while ( *s ) *t++ = *s++;
7534 while (
namespace ) {
7535 u =
namespace->name;
7536 while ( *u ) *t++ = *u++;
7538 namespace = namespace->previous;
7540 if ( type ==
'$' ) s++;
7541 while ( *s ) *t++ = *s++;
7545 while (
namespace ) {
7546 u =
namespace->name;
7547 while ( *u ) *t++ = *u++;
7549 namespace = namespace->previous;
7552 while ( *s ) *t++ = *s++;
7557 MesPrint(
"&Unrecognized datatype in ConstructName");
7561 return(AP.fullname);
7589 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7590 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7591 if ( AP.lastnamespace == 0 ) {
7592 MesPrint(
"@It is not allowed to use #use outside the scope of a namespace.");
7595 namespace = AP.lastnamespace;
7596 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7599 if ( ( s = SkipName(t) ) == 0 )
return(-1);
7601 MesPrint(
"@Unrecognized object in #use instruction: %s",t);
7609 AddName(namespace->usenames,t,0,0,&number);
7611 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7632int UserFlags(UBYTE *s,
int par)
7634 int mask = 0, error = 0, i;
7635 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7636 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7637 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7640 for ( i = 0; i < NumExpressions; i++ ) {
7641 switch ( Expressions[i].status ) {
7642 case UNHIDELEXPRESSION:
7643 case UNHIDEGEXPRESSION:
7644 case INTOHIDELEXPRESSION:
7645 case INTOHIDEGEXPRESSION:
7646 case LOCALEXPRESSION:
7647 case GLOBALEXPRESSION:
7648 case SKIPLEXPRESSION:
7649 case SKIPGEXPRESSION:
7650 case HIDELEXPRESSION:
7651 case HIDEGEXPRESSION:
7652 if ( par == 1 ) Expressions[i].uflags |= ~mask;
7653 else Expressions[i].uflags &= mask;
7655 case DROPPEDEXPRESSION:
7656 case DROPLEXPRESSION:
7657 case DROPGEXPRESSION:
7658 case DROPHLEXPRESSION:
7659 case DROPHGEXPRESSION:
7660 case STOREDEXPRESSION:
7661 case HIDDENLEXPRESSION:
7662 case HIDDENGEXPRESSION:
7663 case SPECTATOREXPRESSION:
7669 else if ( FG.cTable[*s] == 1 ) {
7670 mask = (int)WORDMASK;
7671 while ( FG.cTable[*s] == 1 ) {
7673 while ( FG.cTable[*s] == 1 ) { x = 10*x + (*s++-
'0'); }
7674 if ( x < 1 || x > BITSINWORD ) {
7675 MesPrint(
"@Illegal number %d for flag in #...Flag instruction",x);
7679 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7681 if ( *s == 0 )
goto allexpr;
7684 mask = (int)WORDMASK;
7689 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
7692 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
7693 MesPrint(
"@%s is not an active expression",s1);
7697 switch ( Expressions[num1].status ) {
7698 case UNHIDELEXPRESSION:
7699 case UNHIDEGEXPRESSION:
7700 case INTOHIDELEXPRESSION:
7701 case INTOHIDEGEXPRESSION:
7702 case LOCALEXPRESSION:
7703 case GLOBALEXPRESSION:
7704 case SKIPLEXPRESSION:
7705 case SKIPGEXPRESSION:
7706 case HIDELEXPRESSION:
7707 case HIDEGEXPRESSION:
7708 if ( par == 1 ) Expressions[num1].uflags |= ~mask;
7709 else Expressions[num1].uflags &= mask;
7711 case DROPPEDEXPRESSION:
7712 case DROPLEXPRESSION:
7713 case DROPGEXPRESSION:
7714 case DROPHLEXPRESSION:
7715 case DROPHGEXPRESSION:
7716 case STOREDEXPRESSION:
7717 case HIDDENLEXPRESSION:
7718 case HIDDENGEXPRESSION:
7719 case SPECTATOREXPRESSION:
7721 MesPrint(
"@%s is not an active expression",s1);
7726 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7730 MesPrint(
"@Illegal name in #...Flag instruction.");
7739int DoClearUserFlag(UBYTE *s)
7741 return(UserFlags(s,0));
7749int DoSetUserFlag(UBYTE *s)
7751 return(UserFlags(s,1));
7765int DoStartFloat(UBYTE *s)
7771 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7772 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7773 if ( AR.PolyFun != 0 ) {
7774 MesPrint(
"@Simultaneous use of Poly(Rat)Fun and float_ is not allowed.");
7777 if ( AC.ncmod != 0 ) {
7778 MesPrint(
"@Simultaneous use of floating point and modulus arithmetic makes no sense.");
7785 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7790 if ( *s >=
'0' && *s <=
'9' ) {
7793 x = 10*x + (*s++-
'0');
7794 }
while ( *s >=
'0' && *s <=
'9' );
7799 if ( tolower(*s) ==
'd' ) { AC.tDefaultPrecision = (LONG)ceil(x*log2(10.0)); s++; }
7800 else if ( tolower(*s) ==
'b' ) { AC.tDefaultPrecision = x; s++; }
7802 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7807 if ( tolower(*s) ==
'm' && tolower(s[1]) ==
'z' && tolower(s[2]) ==
'v') {
7809 while ( *s ==
' ' || *s ==
'\t' ) s++;
7810 if ( *s !=
'=')
goto IllPar;
7812 while ( *s ==
' ' || *s ==
'\t' ) s++;
7813 if ( *s >=
'0' && *s <=
'9' ) {
7816 x = 10*x + (*s++ -
'0');
7817 }
while ( *s >=
'0' && *s <=
'9' );
7819 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7826 if ( *s )
goto IllPar;
7828 else if ( *s != 0 ) {
7830 MesPrint(
"@Illegal parameter in %#StartFloat: %s ",ss);
7834 if ( AC.tDefaultPrecision && ( AC.tDefaultPrecision != AC.DefaultPrecision
7835 || AT.aux_ == 0 ) ) {
7836 AC.DefaultPrecision = AC.tDefaultPrecision;
7837 AC.tDefaultPrecision = 0;
7839 if ( AC.tMaxWeight && ( AC.tMaxWeight != AC.MaxWeight
7840 || AT.aux_ == 0 ) ) {
7841 AC.MaxWeight = AC.tMaxWeight;
7844 SetFloatPrecision(AC.DefaultPrecision+AC.MaxWeight+1);
7846 if ( AC.MaxWeight > 0 ) SetupMZVTables();
7847 SetfFloatPrecision(AC.DefaultPrecision);
7850 AC.tDefaultPrecision = 0;
7863int DoEndFloat(UBYTE *s)
7866 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
7867 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
7868 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
7870 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)