36 static UBYTE pushbackchar = 0;
37 static int oldmode = 0;
38 static int stopdelay = 0;
39 static STREAM *oldstream = 0;
40 static UBYTE underscore[2] = {
'_',0};
41 static PREVAR *ThePreVar = 0;
43 static KEYWORD precommands[] = {
44 {
"addseparator" , DoPreAddSeparator,0,0}
45 ,{
"append" , DoPreAppend , 0, 0}
46 ,{
"assign" , DoPreAssign , 0, 0}
47 ,{
"break" , DoPreBreak , 0, 0}
48 ,{
"breakdo" , DoBreakDo , 0, 0}
49 ,{
"call" , DoCall , 0, 0}
50 ,{
"case" , DoPreCase , 0, 0}
51 ,{
"clearoptimize", DoClearOptimize, 0, 0}
52 ,{
"close" , DoPreClose , 0, 0}
53 ,{
"commentchar" , DoCommentChar , 0, 0}
54 ,{
"create" , DoPreCreate , 0, 0}
55 ,{
"debug" , DoDebug , 0, 0}
56 ,{
"default" , DoPreDefault , 0, 0}
57 ,{
"define" , DoDefine , 0, 0}
59 ,{
"else" , DoElse , 0, 0}
60 ,{
"elseif" , DoElseif , 0, 0}
61 ,{
"enddo" , DoEnddo , 0, 0}
62 ,{
"endif" , DoEndif , 0, 0}
63 ,{
"endinside" , DoEndInside , 0, 0}
64 ,{
"endprocedure" , DoEndprocedure , 0, 0}
65 ,{
"endswitch" , DoPreEndSwitch , 0, 0}
66 ,{
"exchange" , DoPreExchange , 0, 0}
67 ,{
"external" , DoExternal , 0, 0}
68 ,{
"factdollar" , DoFactDollar , 0, 0}
69 ,{
"fromexternal" , DoFromExternal , 0, 0}
71 ,{
"ifdef" , (TFUN)DoIfdef , 1, 0}
72 ,{
"ifndef" , (TFUN)DoIfdef , 2, 0}
73 ,{
"include" , DoInclude , 0, 0}
74 ,{
"inside" , DoInside , 0, 0}
75 ,{
"message" , DoMessage , 0, 0}
76 ,{
"optimize" , DoOptimize , 0, 0}
77 ,{
"pipe" , DoPipe , 0, 0}
78 ,{
"preout" , DoPreOut , 0, 0}
79 ,{
"printtimes" , DoPrePrintTimes, 0, 0}
80 ,{
"procedure" , DoProcedure , 0, 0}
81 ,{
"procedureextension" , DoPrcExtension , 0, 0}
82 ,{
"prompt" , DoPrompt , 0, 0}
83 ,{
"redefine" , DoRedefine , 0, 0}
84 ,{
"remove" , DoPreRemove , 0, 0}
85 ,{
"rmexternal" , DoRmExternal , 0, 0}
86 ,{
"rmseparator" , DoPreRmSeparator,0, 0}
87 ,{
"setexternal" , DoSetExternal , 0, 0}
88 ,{
"setexternalattr" , DoSetExternalAttr , 0, 0}
89 ,{
"setrandom" , DoSetRandom , 0, 0}
90 ,{
"show" , DoPreShow , 0, 0}
91 ,{
"switch" , DoPreSwitch , 0, 0}
92 ,{
"system" , DoSystem , 0, 0}
93 ,{
"terminate" , DoTerminate , 0, 0}
94 ,{
"toexternal" , DoToExternal , 0, 0}
95 ,{
"undefine" , DoUndefine , 0, 0}
96 ,{
"write" , DoPreWrite , 0, 0}
112 while ( AC.CurrentStream ) {
113 c = GetFromStream(AC.CurrentStream);
114 if ( c != ENDOFSTREAM ) {
117 && AC.NoShowInput <= 0
118 && AC.CurrentStream->type != PREVARSTREAM )
120 if ( AC.NoShowInput <= 0 && AC.CurrentStream->type != PREVARSTREAM )
125 AC.CurrentStream = CloseStream(AC.CurrentStream);
126 if ( stopdelay && AC.CurrentStream == oldstream ) {
127 stopdelay = 0; AP.AllowDelay = 1;
156 UBYTE GetChar(
int level)
158 UBYTE namebuf[MAXPRENAMESIZE+2], c, *s, *t;
159 static UBYTE lastchar, charinbuf = 0;
160 int i, j, raiselow, olddelay;
166 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0;
return(c); }
167 if ( charinbuf ) { c = charinbuf; charinbuf = 0;
return(c); }
171 charinbuf = GetInput();
172 if ( charinbuf != LINEFEED ) {
173 pushbackchar = charinbuf;
178 while ( ( c = GetInput() ) ==
' ' || c ==
'\t' ) {}
180 else if ( c ==
'\'' || c ==
'`' ) {
181 if ( AP.DelayPrevar == 1 && c ==
'\'' ) {
188 if ( c ==
'!' && lastchar ==
'`' ) {
189 if ( stopdelay == 0 ) oldstream = AC.CurrentStream;
194 if ( c ==
'~' && lastchar ==
'`' ) {
195 if ( AP.AllowDelay ) {
205 olddelay = AP.DelayPrevar;
209 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0; }
210 else { c = GetInput(); }
211 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
212 && lastchar !=
'\\' ) ) {
216 if ( PreCalc() == 0 ) Terminate(-1);
219 MesPrint(
"@Illegal set inside preprocessor variable name");
223 if ( c ==
'`' && lastchar !=
'\\' ) {
225 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
226 && lastchar !=
'\\' ) ) {
230 if ( lastchar ==
'\\' ) { i--; lastchar = 0; }
233 if ( i > MAXPRENAMESIZE ) {
235 Error1(
"Preprocessor variable name too long: ",namebuf);
240 Error1(
"Unmatched quotes for preprocessor variable",namebuf);
242 AP.DelayPrevar = olddelay;
243 if ( namebuf[0] ==
'$' ) {
244 raiselow = PRENOACTION;
245 if ( AP.PreproFlag && *AP.preStart) {
246 s = EndOfToken(AP.preStart);
248 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
249 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
250 && GetDollar(namebuf+1) < 0 ) {
257 s = EndOfToken(namebuf+1);
258 if ( *s ==
'[' ) {
while ( *s ) s++; }
260 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
261 raiselow = PRELOWERAFTER;
262 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
263 raiselow = PRERAISEAFTER;
265 if ( OpenStream(namebuf+1,DOLLARSTREAM,0,raiselow) == 0 ) {
267 MesPrint(
"@Undefined variable %s used as preprocessor variable",
274 raiselow = PRENOACTION;
275 if ( AP.PreproFlag && *AP.preStart) {
276 s = EndOfToken(AP.preStart);
278 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
279 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
280 && GetPreVar(namebuf,WITHOUTERROR) == 0 ) {
286 s = EndOfToken(namebuf);
287 if ( *s ==
'_' ) s++;
288 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
289 raiselow = PRELOWERAFTER;
290 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
291 raiselow = PRERAISEAFTER;
292 else if ( *s ==
'(' && namebuf[i-2] ==
')' ) {
303 *s++ = 0; namebuf[i-2] = 0;
304 if ( StrICmp(namebuf,(UBYTE *)
"random_") == 0 ) {
306 ranvalue = PreRandom(s);
307 PutPreVar(namebuf,ranvalue,(UBYTE *)
"?a",1);
308 M_free(ranvalue,
"PreRandom");
312 if ( *s ==
'\\' ) s++;
313 if ( *s ==
',' ) { *s = 0; nargs++; }
316 GetPreVar(namebuf,WITHERROR);
319 MesPrint(
"@Illegal use of arguments in preprocessor variable %s",namebuf);
323 || ( p->
wildarg > 0 && nargs < p->nargs-1 ) ) {
324 MesPrint(
"@Arguments of macro %s do not match",namebuf);
332 for ( j = 0; j < p->
wildarg; j++ ) {
336 for ( j = 0; j < nargs-p->
nargs; j++ ) {
345 while ( *s ) s++; s++;
347 for ( j = 0; j < p->
nargs; j++ ) {
348 if ( ( nargs == p->
nargs-1 ) && ( *t ==
'?' ) ) {
353 while ( *s ) s++; s++;
355 while ( *t ) t++; t++;
359 if ( ( stream = OpenStream(namebuf,PREVARSTREAM,0,raiselow) ) == 0 ) {
364 else if ( stream->inbuffer == 0 ) {
366 if ( level > 0 && c ==
'\'' )
return(c);
372 else if ( c ==
'{' ) {
373 if ( PreCalc() == 0 ) Terminate(-1);
388 VOID CharOut(UBYTE c)
390 if ( c == LINEFEED ) {
391 AM.OutBuffer[AP.InOutBuf++] = c;
392 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
396 if ( AP.InOutBuf >= AM.OutBufSize || c == LINEFEED ) {
397 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
400 AM.OutBuffer[AP.InOutBuf++] = c;
409 VOID UnsetAllowDelay()
411 if ( ThePreVar != 0 ) {
412 if ( ThePreVar->
nargs > 0 ) AP.AllowDelay = 0;
429 static UBYTE *yes = (UBYTE *)
"1";
430 static UBYTE *no = (UBYTE *)
"0";
431 static UBYTE numintopolynomial[12];
433 UBYTE *GetPreVar(UBYTE *name,
int flag)
438 UBYTE *t, c = 0, *tt = 0;
439 t = name;
while ( *t ) t++;
440 if ( t[-1] ==
'-' && t[-2] ==
'-' && t-2 > name && t[-3] !=
'_' ) {
441 t -= 2; c = *t; *t = 0; tt = t;
443 else if ( t[-1] ==
'+' && t[-2] ==
'+' && t-2 > name && t[-3] !=
'_' ) {
444 t -= 2; c = *t; *t = 0; tt = t;
446 else if ( StrICmp(name,(UBYTE *)
"time_") == 0 ) {
448 LONG millitime, timepart;
449 int timepart1, timepart2;
450 static char timestring[40];
452 millitime = GetRunningTime();
453 timepart = millitime%1000;
456 timepart1 = timepart / 10;
457 timepart2 = timepart % 10;
458 NumToStr(millibuf,millitime);
459 sprintf(timestring,
"%s.%1d%1d",millibuf,timepart1,timepart2);
460 return((UBYTE *)timestring);
463 while ( *t && *t !=
'_' ) t++;
464 for ( i = NumPre-1; i >= 0; i-- ) {
465 if ( *t ==
'_' && ( StrICmp(name,PreVar[i].name) == 0 ) ) {
467 ThePreVar = PreVar+i;
468 return(PreVar[i].value);
470 else if ( StrCmp(name,PreVar[i].name) == 0 ) {
472 ThePreVar = PreVar+i;
473 return(PreVar[i].value);
477 if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS_") == 0 )
goto extrashort;
479 if ( StrICmp(name,(UBYTE *)
"UNCHANGED") == 0 ) mode = 1;
480 else if ( StrICmp(name,(UBYTE *)
"ZERO") == 0 ) mode = 0;
481 else if ( StrICmp(name,(UBYTE *)
"SHOWINPUT") == 0 ) {
484 if ( AC.NoShowInput > 0 )
return(no);
487 else if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS") == 0 ) {
490 number = cbuf[AM.sbufnum].numrhs;
491 t = numintopolynomial;
493 return(numintopolynomial);
500 if ( GetName(AC.exprnames,t,&number,NOAUTO) == CEXPRESSION ) {
502 if ( ( Expressions[number].vflags & ( 1 << mode ) ) != 0 )
513 if ( ( AR.expflags & ( 1 << mode ) ) == 0 )
return(yes);
518 if ( ( t = (UBYTE *)(getenv((
char *)(name))) ) != 0 ) {
524 if ( flag == WITHERROR ) {
525 Error1(
"Undefined preprocessor variable",name);
549 int PutPreVar(UBYTE *name, UBYTE *value, UBYTE *args,
int mode)
551 int i, ii, num = 2, nnum = 2, numargs = 0;
552 UBYTE *s, *t, *u = 0;
554 if ( value == 0 && name[0] !=
'?' ) {
555 MesPrint(
"@Illegal empty value for preprocessor variable %s",name);
561 if ( *s !=
' ' && *s !=
'\t' ) num++;
568 if ( StrCmp(name,PreVar[i].name) == 0 ) {
575 if ( i < 0 ) { p = (
PREVAR *)FromList(&AP.PreVarList); ii = p - PreVar; }
576 else { p = &(PreVar[i]); ii = i; }
578 s = value;
while ( *s ) { s++; num++; }
584 while ( *s ) { s++; nnum++; }
591 if ( value && p->
value ) {
594 while ( *s ) *t++ = *s++; *t = 0;
600 s = name;
while ( *s ) { s++; num++; }
601 t = (UBYTE *)Malloc1(num,
"PreVariable");
603 s = name;
while ( *s ) *t++ = *s++; *t++ = 0;
606 s = value;
while ( *s ) *t++ = *s++; *t = 0;
607 if ( AM.atstartup && t[-1] ==
'\n' ) t[-1] = 0;
616 if ( *s ==
' ' || *s ==
'\t' ) { s++;
continue; }
618 s++; *t++ = 0; numargs++;
619 while ( *s ==
' ' || *s ==
'\t' ) s++;
622 Error0(
"More than one ?var in #define");
627 else if ( *s ==
'?' && first ) {
630 else { *t++ = *s++; }
641 if ( u ) M_free(u,
"replace PreVar value");
650 VOID PopPreVars(
int tonumber)
652 PREVAR *p = &(PreVar[NumPre]);
653 while ( NumPre > tonumber ) {
655 M_free(p->
name,
"popping PreVar");
665 VOID IniModule(
int type)
669 CBUF *C = cbuf+AC.cbufnum;
683 AR.StoreData.dirtyflag = 0;
684 AC.bracketindexflag = 0;
685 AT.bracketindexflag = 0;
690 AC.RhsExprInModuleFlag = 0;
693 PF.slavebuf.PObuffer=NULL;
694 for(i=0; i<NumExpressions; i++)
695 Expressions[i].vflags &= ~ISINRHS;
707 w = C->
rhs; i = C->maxrhs;
708 do { *w++ = 0; }
while ( --i > 0 );
711 w = C->
lhs; i = C->maxlhs;
712 do { *w++ = 0; }
while ( --i > 0 );
715 C->numlhs = C->numrhs = 0;
716 ClearTree(AC.cbufnum);
717 while ( AC.NumLabels > 0 ) {
719 if ( AC.LabelNames[AC.NumLabels] ) M_free(AC.LabelNames[AC.NumLabels],
"LabelName");
722 if ( type == FIRSTMODULE ) AC.iPointer = AC.iBuffer;
725 AC.Commercial[0] = 0;
727 AC.IfStack = AC.IfHeap;
735 AC.MustTestTable = 0;
740 AC.SymChangeFlag = 0;
741 AP.lhdollarerror = 0;
742 AR.PolyFun = AC.lPolyFun;
743 AR.PolyFunType = AC.lPolyFunType;
744 AC.mparallelflag = AC.parallelflag | AM.hparallelflag;
745 AC.inparallelflag = 0;
746 AC.mProcessBucketSize = AC.ProcessBucketSize;
747 NumPotModdollars = 0;
748 AC.topolynomialflag = 0;
750 if ( AM.totalnumberofthreads > 1 ) AS.MultiThreaded = 1;
751 else AS.MultiThreaded = 0;
752 for ( i = 1; i < AM.totalnumberofthreads; i++ ) {
753 AB[i]->T.S0->PolyWise = 0;
764 VOID IniSpecialModule(
int type)
776 int moduletype = FIRSTMODULE;
778 int error1 = 0, error2 = 0, retcode, numstatement, retval;
781 AP.PreContinuation = 0;
784 if ( AC.CheckpointFlag == -1 )
DoRecovery(&moduletype);
785 AC.CheckpointStamp = Timer(0);
790 IniModule(moduletype);
796 NumToStr(buf,AC.CModule);
800 if ( specialtype ) IniSpecialModule(specialtype);
805 if ( c == AP.ComChar ) {
807 if ( AC.CurrentStream->FoldName ) {
809 if ( *t && t[1] && t[2] ==
'#' && t[3] ==
']' ) {
811 while ( *t ==
' ' || *t ==
'\t' ) t++;
812 s = AC.CurrentStream->FoldName;
813 while ( *s == *t ) { s++; t++; }
814 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t' 816 while ( *t ==
' ' || *t ==
'\t' ) t++;
818 AC.CurrentStream = CloseStream(AC.CurrentStream);
826 while ( c ==
' ' || c ==
'\t' ) c = GetChar(0);
827 if ( c == LINEFEED )
continue;
828 if ( c == ENDOFINPUT ) {
830 Warning(
".end instruction generated");
831 moduletype = ENDMODULE; specialtype = 0;
835 if ( PreProInstruction() ) { error1++; error2++; AP.preError++; }
838 else if ( c ==
'.' ) {
839 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
840 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
844 if ( ModuleInstruction(&moduletype,&specialtype) ) { error2++; AP.preError++; }
845 if ( specialtype ) SetSpecialMode(moduletype,specialtype);
846 if ( AP.PreInsideLevel != 0 ) {
847 MesPrint(
"@end of module instructions may not be used inside");
848 MesPrint(
"@the scope of a %#inside %#endinside construction.");
851 if ( AC.RepLevel > 0 ) {
852 MesPrint(
"&EndRepeat statement(s) missing");
853 error2++; AP.preError++;
855 if ( AC.tablecheck == 0 ) {
857 if ( TestTables() ) { error2++; AP.preError++; }
859 if ( moduletype == GLOBALMODULE ) MakeGlobal();
861 endmodule:
if ( error2 == 0 && AM.qError == 0 ) {
862 retcode = ExecModule(moduletype);
864 if(PF.slavebuf.PObuffer!=NULL){
865 M_free(PF.slavebuf.PObuffer,
"PF inbuf");
866 PF.slavebuf.PObuffer=NULL;
870 if ( retcode < 0 ) error1++;
871 if ( retcode ) { error2++; AP.preError++; }
876 for ( j = 0, e = Expressions; j < NumExpressions; j++, e++ ) {
877 if ( e->replace == NEWLYDEFINEDEXPRESSION ) e->replace = REGULAREXPRESSION;
880 switch ( moduletype ) {
882 if ( ExecStore() ) error1++;
886 error1 = error2 = AP.preError = 0;
887 PutPreVar((UBYTE *)
"DATE_",(UBYTE *)MakeDate(),0,1);
888 if ( AM.resetTimeOnClear ) {
892 AM.SumTime += TimeCPU(1);
897 Terminate( -( error1 | error2 ) );
902 if ( AC.exprfillwarning > 0 ) {
903 AC.exprfillwarning = 0;
905 if ( AC.CheckpointFlag && error1 == 0 && error2 == 0 )
DoCheckpoint(moduletype);
909 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
910 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
916 if ( AP.PreContinuation ) {
917 retval = LoadStatement(OLDSTATEMENT);
921 AC.CurrentStream->prevline = AC.CurrentStream->linenumber;
922 retval = LoadStatement(NEWSTATEMENT);
926 if ( retval == -1 ) AP.PreContinuation = 0;
927 else AP.PreContinuation = 1;
930 else if ( retval > 0 ) AP.PreContinuation = 0;
931 else AP.PreContinuation = 1;
932 if ( error1 == 0 && !AP.PreContinuation ) {
933 if ( ( AP.PreDebug & PREPROONLY ) == 0 ) {
934 int onpmd = NumPotModdollars;
936 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
937 if ( AP.PreAssignFlag ) AC.RhsExprInModuleFlag = 0;
939 if ( AP.PreOut || ( AP.PreDebug & DUMPTOCOMPILER )
940 == DUMPTOCOMPILER ) MesPrint(
" %s",AC.iBuffer);
941 retcode = CompileStatement(AC.iBuffer);
942 if ( retcode < 0 ) error1++;
943 if ( retcode ) { error2++; AP.preError++; }
944 if ( AP.PreAssignFlag ) {
945 if ( retcode == 0 ) {
946 if ( ( retcode = CatchDollar(0) ) < 0 ) error1++;
947 else if ( retcode > 0 ) { error2++; AP.preError++; }
949 else CatchDollar(-1);
950 AP.PreAssignFlag = 0;
951 NumPotModdollars = onpmd;
953 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
958 MesPrint(
" %s",AC.iBuffer);
961 if ( !AP.PreContinuation ) AP.PreAssignFlag = 0;
972 int PreProInstruction()
982 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
984 if ( ( StrICmp(AP.preStart,(UBYTE *)
"case") == 0
985 || StrICmp(AP.preStart,(UBYTE *)
"default") == 0 )
986 && AP.PreSwitchModes[AP.PreSwitchLevel] == SEARCHINGPRECASE ) {
989 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
990 else { LoadInstruction(1); }
992 else if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
994 if ( ( StrICmp(AP.preStart,(UBYTE *)
"else") == 0
995 || StrICmp(AP.preStart,(UBYTE *)
"elseif") == 0 )
996 && AP.PreIfStack[AP.PreIfLevel] == LOOKINGFORELSE ) {
999 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
1010 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1011 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1014 else if ( *t ==
'+' ) {
1015 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1016 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1019 else if ( *t ==
':' ) {}
1022 key = FindKeyWord(t,precommands,
sizeof(precommands)/
sizeof(
KEYWORD));
1030 MesPrint(
"@Unrecognized preprocessor instruction: %s",t);
1034 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
1037 while ( ( t[-1] ==
';' ) && ( t[-2] !=
'\\' ) ) {
1040 if ( key->type )
return(((TFUN1)key->func)(s,key->type));
1041 else return((key->func)(s));
1061 int LoadInstruction(
int mode)
1063 UBYTE *s, *sstart, *t, c, cp;
1064 LONG position, fillpos = 0;
1065 int bralevel = 0, parlevel = 0, first = 1;
1070 if ( s[1] != LINEFEED && s[1] != ENDOFINPUT ) {
1073 else { oldmode = mode;
return(0); }
1075 else { s = AP.preStart; }
1078 if ( ( mode & 1 ) == 1 ) {
1079 if ( pushbackchar && ( mode == 3 || mode == 5 ) ) {
1080 c = pushbackchar; pushbackchar = 0;
1082 else c = GetInput();
1088 if ( mode == 2 && c ==
';' )
break;
1089 if ( ( mode == 1 || mode == 5 ) && c == LINEFEED )
break;
1090 if ( mode == 3 && FG.cTable[c] != 0 ) {
1093 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1094 *s++ =
'g'; *s++ =
'n'; *s++ =
' '; *s = 0;
1096 AP.preFill = s; *s++ = 0; *s = c;
1100 if ( mode == 0 && first ) {
1102 dodollar: s = sstart;
1103 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1104 *s++ =
'g'; *s++ =
'n'; *s = 0;
1109 if ( c ==
' ' || c ==
'\t' || c ==
',' ) {}
1112 else if ( mode == 1 && first && c ==
'$' && oldmode == 3 )
goto dodollar;
1113 if ( c == ENDOFINPUT || ( c == LINEFEED
1115 && quotelevel == 0 ) ) {
1116 if ( mode == 2 && c == ENDOFINPUT ) {
1117 MesPrint(
"@Unexpected end of instruction");
1128 if ( mode != 2 )
break;
1132 if ( ( mode == 1 ) || ( mode == 5 ) ) c = GetInput();
1136 if ( c == ENDOFINPUT ) {
1137 MesPrint(
"@Unmatched \"");
1138 if ( mode == 2 && c == ENDOFINPUT ) {
1139 MesPrint(
"@Unexpected end of instruction");
1149 else if ( c == LINEFEED ) {}
1150 else if ( c ==
'"' ) { *s++ =
'\\'; }
1155 else if ( c ==
'"' ) {
1160 else if ( c ==
'\\' ) {
1161 if ( ( mode == 1 ) || ( mode == 5 ) ) cp = GetInput();
1165 if ( cp == LINEFEED )
continue;
1166 if ( mode != 2 || cp !=
';' ) *s++ = c;
1169 else if ( c ==
'"' ) {
1175 while ( FG.cTable[*t] <= 1 ) t++;
1177 if ( ( StrICmp(AP.preStart,(UBYTE *)
"define") == 0 )
1178 || ( StrICmp(AP.preStart,(UBYTE *)
"redefine") == 0 ) ) {
1180 oldstream = AC.CurrentStream;
1185 else if ( quotelevel == 0 && bralevel == 0 && c ==
'(' ) {
1187 while ( FG.cTable[*t] <= 1 ) t++;
1189 if ( ( parlevel == 0 )
1190 && ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 ) ) {
1192 oldstream = AC.CurrentStream;
1197 else if ( quotelevel == 0 && bralevel == 0 && c ==
')' ) {
1200 else if ( quotelevel == 0 && parlevel == 0 && c ==
'{' ) {
1202 while ( FG.cTable[*t] <= 1 ) t++;
1204 if ( ( bralevel == 0 )
1205 && ( ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 )
1206 || ( StrICmp(AP.preStart,(UBYTE *)
"do") == 0 ) ) ) {
1208 oldstream = AC.CurrentStream;
1213 else if ( quotelevel == 0 && parlevel == 0 && c ==
'}' ) {
1215 if ( bralevel < 0 ) {
1217 MesPrint(
"@Unmatched brackets");
1224 if ( s >= (AP.preStop-1) ) {
1226 position = s - AP.preStart;
1227 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1228 ppp = &(AP.preStart);
1229 if ( DoubleLList((VOID ***)ppp,&AP.pSize,
sizeof(UBYTE),
1230 "instruction buffer") ) { *s = 0; oldmode = mode;
return(-1); }
1231 AP.preStop = AP.preStart + AP.pSize-3;
1232 s = AP.preStart + position;
1233 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1240 if ( ExpandTripleDots(1) < 0 )
return(-1);
1259 int LoadStatement(
int type)
1262 int retval = 0, stringlevel = 0, newstatement = 0;
1263 if ( type == NEWSTATEMENT ) { AP.eat = 1; s = AC.iBuffer; newstatement = 1; }
1264 else { s = AC.iPointer; *s = 0; c =
' ';
goto blank; }
1268 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1269 if ( stringlevel == 0 ) {
1270 if ( c == LINEFEED ) { retval = 0;
break; }
1272 if ( AP.eat < 0 ) s--;
1273 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1274 if ( c != LINEFEED ) UngetChar(c);
1281 if ( cp == LINEFEED )
continue;
1286 if ( stringlevel == 0 ) stringlevel = 1;
1287 else stringlevel = 0;
1290 else if ( stringlevel == 0 ) {
1291 if ( c ==
'\t' ) c =
' ';
1293 blank:
if ( newstatement < 0 ) newstatement = 0;
1294 if ( AP.eat && ( newstatement == 0 ) )
continue;
1297 if ( newstatement > 0 ) newstatement = -1;
1299 else if ( chartype[c] <= 3 ) {
1301 if ( newstatement < 0 ) newstatement = 0;
1303 else if ( c ==
',' ) {
1304 if ( newstatement > 0 ) {
1309 else if ( AP.eat == -2 ) { AP.eat = 1;
continue; }
1310 else {
goto doall; }
1313 doall:;
if ( AP.eat < 0 ) {
1314 if ( newstatement == 0 ) s--;
1315 else { newstatement = 0; }
1317 else if ( newstatement == 1 ) newstatement = 0;
1319 if ( c ==
'*' && s > AC.iBuffer && s[-1] ==
'*' ) {
1325 if ( s >= AC.iStop ) {
1326 if ( !AP.iBufError ) {
1327 LONG position = s - AC.iBuffer;
1328 UBYTE **ppp = &(AC.iBuffer);
1329 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1330 ,
sizeof(UBYTE),
"statement buffer") ) {
1331 *s = 0; retval = -1; AP.iBufError = 1;
1333 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1334 s = AC.iBuffer + position;
1336 if ( AP.iBufError ) {
1339 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1341 if ( stringlevel > 0 ) stringlevel = 0;
1342 else stringlevel = 1;
1344 else if ( c == LINEFEED && !stringlevel ) { retval = -2;
break; }
1345 else if ( c ==
';' && !stringlevel ) {
1346 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1347 if ( c != LINEFEED ) UngetChar(c);
1351 else if ( c ==
'\\' ) c = GetChar(0);
1360 if ( stringlevel > 0 ) {
1361 MesPrint(
"@Unbalanced \". Runaway string");
1364 if ( retval == 1 ) {
1365 if ( ExpandTripleDots(0) < 0 ) retval = -1;
1375 static inline int IsSignChar(UBYTE c)
1377 return c ==
'+' || c ==
'-';
1380 static inline int IsAlphanumericChar(UBYTE c)
1382 return FG.cTable[c] == 0 || FG.cTable[c] == 1;
1385 static inline int CanParseSignedNumber(
const UBYTE *s)
1387 while ( IsSignChar(*s) ) s++;
1388 return FG.cTable[*s] == 1;
1391 int ExpandTripleDots(
int par)
1393 UBYTE *s, *s1, *s2, *n1, *n2, *t1, *t2, *startp, operator1, operator2, c, cc;
1394 UBYTE *nBuffer, *strngs, *Buffer, *Stop;
1395 LONG withquestion, x1, x2, y1, y2, number, inc, newsize, pow, fullsize;
1396 int i, error = 0, i1 ,i2, ii, *nums = 0;
1399 Buffer = AC.iBuffer; Stop = AC.iStop;
1402 Buffer = AP.preStart; Stop = AP.preStop;
1404 s = Buffer;
while ( *s ) s++;
1405 fullsize = s - Buffer;
1406 if ( fullsize < 7 )
return(error);
1410 if ( *s !=
'.' || ( s[-1] !=
',' && FG.cTable[s[-1]] != 5 ) )
1412 if ( s[-1] ==
'%' || s[-1] ==
'^' || s[1] !=
'.' || s[2] !=
'.' )
1416 if ( *s != s[-4] && ( *s !=
'+' || s[-4] !=
'-' )
1417 && ( *s !=
'-' || s[-4] !=
'+' ) ) {
1418 MesPrint(
"&Improper operators for ...");
1423 if ( operator1 ==
':' ) operator1 =
'.';
1424 if ( operator2 ==
':' ) operator2 =
'.';
1434 if ( *s2 !=
'<' || *s1 !=
'>' ) {
1436 withquestion = ( *s1 ==
'?' ); s1--;
1437 while ( FG.cTable[*s1] == 1 && s1 >= Buffer ) s1--;
1439 if ( FG.cTable[*n1] != 1 ) {
1440 MesPrint(
"&No first number in ... operator");
1443 while ( FG.cTable[*s1] <= 1 && s1 >= Buffer ) s1--;
1449 while ( t1 < n1 && *t1 == *t2 ) { t1++; t2++; }
1451 if ( FG.cTable[*t2] != 1 ) {
1452 MesPrint(
"&No second number in ... operator");
1456 while ( FG.cTable[*t2] == 1 ) x2 = 10*x2 + *t2++ -
'0';
1458 while ( FG.cTable[*t1] == 1 ) x1 = 10*x1 + *t1++ -
'0';
1459 if ( withquestion != ( *t2 ==
'?' ) ) {
1460 MesPrint(
"&Improper use of ? in ... operator");
1461 if ( *t2 ==
'?' ) t2++;
1464 else if ( withquestion ) t2++;
1465 if ( FG.cTable[*t2] <= 2 ) {
1466 MesPrint(
"&Illegal object after ... construction");
1469 c = *n1; *n1 = 0; s = t2;
1470 if ( error )
continue;
1479 if ( x2 < x1 ) { number = x1-x2; inc = -1; y1 = x2; y2 = x1; }
1480 else { number = x2-x1; inc = 1; y1 = x1; y2 = x2; }
1481 newsize = (number+1)*(n1-s1)
1483 +(number+1)*(withquestion?1:0)
1486 for ( i = 1; i < 10; i++, pow *= 10 ) {
1487 if ( y1 >= pow ) newsize += number+1;
1488 else if ( y2 >= pow ) newsize += y2-pow+1;
1491 while ( Buffer+(fullsize+newsize-(s-s1)) >= Stop ) {
1492 LONG strpos = s1-Buffer;
1493 LONG endstr = n1-Buffer;
1494 LONG startq = startp - Buffer;
1495 LONG position = s - Buffer;
1498 ppp = &(AC.iBuffer);
1499 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1500 ,
sizeof(UBYTE),
"statement buffer") ) {
1503 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1504 Buffer = AC.iBuffer; Stop = AC.iStop;
1508 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1509 ppp = &(AP.preStart);
1510 if ( DoubleLList((VOID ***)ppp,&AP.pSize,
sizeof(UBYTE),
1511 "instruction buffer") ) {
1514 AP.preStop = AP.preStart + AP.pSize-3;
1515 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1516 Buffer = AP.preStart; Stop = AP.preStop;
1518 s = Buffer + position;
1519 n1 = Buffer + endstr;
1520 s1 = Buffer + strpos;
1521 startp = Buffer + startq;
1529 if ( newsize > (s-s1) ) {
1530 t2 = Buffer + fullsize;
1531 t1 = t2 + (newsize - (s-s1));
1533 while ( t2 > s ) { *--t1 = *--t2; }
1535 else if ( newsize < (s-s1) ) {
1536 t1 = s1 + newsize; t2 = s; s = t1;
1537 while ( *t2 ) *t1++ = *t2++;
1540 for ( x1 += inc, t1 = startp; number > 0; number--, x1 += inc ) {
1542 cc = operator1; operator1 = operator2; operator2 = cc;
1543 t2 = s1;
while ( *t2 ) *t1++ = *t2++;
1546 *t1++ =
'0' + x2 % 10;
1550 while ( s2 > n2 ) { cc = *s2; *s2 = *n2; *n2++ = cc; s2--; }
1551 if ( withquestion ) *t1++ =
'?';
1553 fullsize += newsize - ( s - s1 );
1558 while ( s1 > Buffer ) {
1559 if ( *s1 ==
'<' )
break;
1564 if ( *t2 ==
'>' )
break;
1567 if ( *s1 !=
'<' || *t2 !=
'>' ) {
1568 MesPrint(
"&Illegal attempt to use ... operator");
1572 nums = (
int *)Malloc1((t1-s1)*2*(
sizeof(int)+
sizeof(UBYTE))
1574 strngs = (UBYTE *)(nums + 2*(t1-s1));
1575 n1 = s1; n2 = s2; ii = -1; i = 0;
1577 while ( n1 < t1 || n2 < t2 ) {
1579 if ( CanParseSignedNumber(n1) && CanParseSignedNumber(n2) ) {
1588 int sign1 = IsSignChar(*n1);
1589 int sign2 = IsSignChar(*n2);
1590 int inword1 = s1 < n1 && IsAlphanumericChar(n1[-1]);
1591 int inword2 = s2 < n2 && IsAlphanumericChar(n2[-1]);
1592 if ( ( sign1 ^ sign2 ) && ( inword1 || inword2 ) )
break;
1593 if ( sign1 || sign2 ) {
1598 if ( *n1 == *n2 ) { *s++ = *n1++; n2++;
continue; }
1601 ParseSignedNumber(x1,n1)
1602 ParseSignedNumber(x2,n2)
1604 if ( s != strngs && ( s[-1] ==
'+' || s[-1] ==
'-' ) ) {
1614 nums[2*i] = x1; nums[2*i+1] = x2;
1618 if ( n1 < t1 || n2 < t2 ) {
1619 MesPrint(
"&Improper use of ... operator.");
1620 theend: M_free(nums,
"Expand ...");
1624 if ( i == 0 ) ii = 0;
1626 ii = nums[0] - nums[1];
1627 if ( ii < 0 ) ii = -ii;
1628 for ( x1 = 1; x1 < i; x1++ ) {
1629 x2 = nums[2*x1]-nums[2*x1+1];
1630 if ( x2 < 0 ) x2 = -x2;
1632 MesPrint(
"&Improper synchronization of numbers in ... operator");
1647 x2 = s - strngs - i;
1648 for ( i1 = 0; i1 < i; i1++ ) {
1651 if ( i2 < 0 ) i2 = -i2;
1652 if ( x1 < 0 ) x1 = -x1;
1653 if ( x1 > i2 ) i2 = x1;
1655 while ( i2 > 0 ) { i2 /= 10; x1++; }
1661 x2 +=
sizeof(UBYTE *);
1662 x2 = x2 - (x2 & (
sizeof(UBYTE *)-1));
1664 nBuffer = (UBYTE *)Malloc1(x2,
"input buffer");
1665 n1 = nBuffer; s = Buffer; s1--;
1666 while ( s < s1 ) *n1++ = *s++;
1674 if ( ( ( n1 > nBuffer ) && ( ( FG.cTable[n1[-1]] <= 1 )
1675 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1676 ( ( FG.cTable[strngs[0]] <= 1 ) || ( strngs[0] ==
'[' )
1677 || ( strngs[0] ==
'_' ) ) ) *n1++ =
',';
1679 for ( i1 = 0; i1 < ii; i1++ ) {
1680 s = strngs;
while ( *s ) *n1++ = *s++;
1681 for ( i2 = 0; i2 < i; i2++ ) {
1682 if ( n1 > nBuffer && IsSignChar(n1[-1]) ) {
1685 if ( nums[2*i2] >= 0 ) {
1689 n1 = NumCopy((WORD)(nums[2*i2]),n1);
1690 if ( nums[2*i2] > nums[2*i2+1] ) nums[2*i2]--;
1692 s++;
while ( *s ) *n1++ = *s++;
1694 if ( ( i1 & 1 ) == 0 ) *n1++ = operator1;
1695 else *n1++ = operator2;
1698 s = t2 + 1; n2 = n1;
1702 if ( ( ( ( FG.cTable[n1[-1]] <= 1 )
1703 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1704 ( ( FG.cTable[s[0]] <= 1 ) || ( s[0] ==
'[' )
1705 || ( s[0] ==
'_' ) ) ) *n1++ =
',';
1707 while ( *s ) *n1++ = *s++;
1710 AC.iStop = nBuffer + x2 - 2;
1711 AC.iBufferSize = x2;
1712 M_free(AC.iBuffer,
"input buffer");
1713 M_free(nums,
"Expand ...");
1714 AC.iBuffer = nBuffer;
1715 Buffer = AC.iBuffer; Stop = AC.iStop;
1718 AP.preStop = nBuffer + x2 - 2;
1720 M_free(AP.preStart,
"input buffer");
1721 M_free(nums,
"Expand ...");
1722 AP.preStart = nBuffer;
1723 Buffer = AP.preStart; Stop = AP.preStop;
1725 fullsize = n1 - Buffer;
1743 while ( hi >= low ) {
1745 s1 = (UBYTE *)(table[med].name);
1747 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1753 FG.cTable[*s2] != 0 && FG.cTable[*s2] != 1
1757 if ( tolower(*s2) > tolower(*s1) ) low = med+1;
1772 for ( i = 0; i < size; i++ ) {
1773 s1 = (UBYTE *)(table[i].name);
1775 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1776 if ( *s2 == 0 || *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' )
1800 UBYTE *name, *value, *valpoin, *args = 0, c;
1801 if ( ( mode & 2 ) == 0 ) {
1802 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
1803 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
1805 else { mode &= ~2; }
1807 if ( chartype[*s] != 0 )
goto illname;
1809 while ( chartype[*s] <= 1 ) s++;
1811 while ( *s ==
' ' || *s ==
'\t' ) s++;
1814 if (
PutPreVar(name,(UBYTE *)
"1",0,mode) < 0 )
return(-1);
1820 if ( chartype[*s] != 0 )
goto illarg;
1822 while ( chartype[*s] <= 1 ) s++;
1823 while ( *s ==
' ' || *s ==
'\t' ) s++;
1824 if ( *s ==
')' )
break;
1825 if ( *s !=
',' )
goto illargs;
1827 while ( *s ==
' ' || *s ==
'\t' ) s++;
1830 while ( *s ==
' ' || *s ==
'\t' ) s++;
1834 s++; valpoin = value = s;
1835 while ( *s !=
'"' ) {
1837 if ( s[1] ==
'n' ) { *valpoin++ = LINEFEED; s += 2; }
1838 else if ( s[1] ==
'"' ) { *valpoin++ =
'"'; s += 2; }
1839 else if ( s[1] == 0 )
goto illval;
1840 else { *valpoin++ = *s++; *valpoin++ = *s++; }
1842 else *valpoin++ = *s++;
1845 if (
PutPreVar(name,value,args,mode) < 0 )
return(-1);
1848 MesPrint(
"@Illegal string for preprocessor variable %s. Forgotten double quotes (\") ?",name);
1853 MesPrint(
"@Illegally formed name of preprocessor variable");
1856 MesPrint(
"@Illegally formed name of argument of preprocessor definition");
1859 MesPrint(
"@Illegally formed arguments of preprocessor definition");
1862 MesPrint(
"@Illegal valpoin for preprocessor variable %s",name);
1871 int DoCommentChar(UBYTE *s)
1874 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
1875 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
1876 while ( *s ==
' ' || *s ==
'\t' ) s++;
1877 if ( *s == 0 || *s ==
'\n' ) {
1878 MesPrint(
"@No valid comment character specified");
1882 while ( *s ==
' ' || *s ==
'\t' ) s++;
1883 if ( *s != 0 && *s !=
'\n' ) {
1884 MesPrint(
"@Comment character should be a single valid character");
1902 int DoPreAssign(UBYTE *s)
1905 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
1908 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
1912 MesPrint(
"@Illegal characters in %#assign instruction");
1915 AP.PreAssignFlag = 1;
1916 if ( AP.PreContinuation ) {
1917 MesPrint(
"@Assign instructions cannot occur inside statements");
1918 MesPrint(
"@Missing ; ?");
1919 AP.PreContinuation = 0;
1930 int DoDefine(UBYTE *s)
1940 int DoRedefine(UBYTE *s)
1952 int ClearMacro(UBYTE *name)
1957 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
1958 if ( StrCmp(name,p->
name) == 0 )
break;
1960 if ( i < 0 )
return(-1);
1961 if ( p->
nargs <= 0 )
return(0);
1963 for ( i = 0; i < p->
nargs; i++ ) {
1980 int TheUndefine(UBYTE *name)
1982 int i, inum, error = 0;
1984 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
1985 if ( StrCmp(name,p->
name) == 0 ) {
1986 M_free(p->
name,
"undefining PreVar");
1989 while ( i < NumPre ) {
1996 CBUF *CC = cbuf + AC.cbufnum;
1998 for ( j = 1; j <= CC->numlhs; j++ ) {
1999 if ( CC->
lhs[j][0] == TYPEREDEFPRE ) {
2000 if ( CC->
lhs[j][2] > inum ) CC->
lhs[j][2]--;
2001 else if ( CC->
lhs[j][2] == inum ) {
2002 for ( k = inum - 1; k >= 0; k-- )
2003 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2004 if ( k >= 0 ) CC->
lhs[j][2] = k;
2006 MesPrint(
"@Conflict between undefining a preprocessor variable and a redefine statement");
2013 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2014 if ( AC.pfirstnum[j] > inum ) AC.pfirstnum[j]--;
2015 else if ( AC.pfirstnum[j] == inum ) {
2016 for ( k = inum - 1; k >= 0; k-- )
2017 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2018 if ( k >= 0 ) AC.pfirstnum[j] = k;
2034 int DoUndefine(UBYTE *s)
2037 int error = 0, retval;
2042 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2043 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2045 if ( chartype[*s] != 0 )
goto illname;
2047 while ( chartype[*s] <= 1 ) s++;
2049 if ( *s && *s !=
' ' && *s !=
'\t' )
goto illname;
2050 while ( *s ==
' ' || *s ==
'\t' ) s++;
2052 MesPrint(
"@Undefine should just have a variable name");
2056 if ( ( retval = TheUndefine(name) ) != 0 ) {
2057 if ( error == 0 )
return(retval);
2058 if ( error > 0 ) error = retval;
2077 MesPrint(
"@Illegally formed name of preprocessor variable");
2086 int DoInclude(UBYTE *s)
2088 UBYTE *name = s, *fold, *t, c, c1 = 0, c2 = 0, c3 = 0;
2089 int str1offset, withnolist = AC.NoShowInput;
2090 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2091 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2092 if ( *s ==
'-' || *s ==
'+' ) {
2093 if ( *s ==
'-' ) withnolist = 1;
2094 else withnolist = 0;
2096 while ( *s ==
' ' || *s ==
'\t' ) s++;
2100 while ( *s && *s !=
'"' ) {
2101 if ( *s ==
'\\' ) s++;
2107 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2108 if ( *s ==
'\\' ) s++;
2113 while ( *s ==
' ' || *s ==
'\t' ) s++;
2117 while ( *s ==
' ' || *s ==
'\t' ) s++;
2120 MesPrint(
"@Empty fold name");
2123 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2124 if ( *s ==
'\\' ) s++;
2128 while ( *s ==
' ' || *s ==
'\t' ) s++;
2130 MesPrint(
"@Improper fold name");
2134 else if ( *s == 0 ) {
2138 MesPrint(
"@Improper syntax for file name");
2143 fold = strDup1(fold,
"foldname");
2148 if ( OpenStream(name,FILESTREAM,0,PRENOACTION) == 0 ) {
2149 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2155 LONG linenum = 0, prevline = 0;
2156 name = strDup1(name,
"name of include file");
2157 AC.CurrentStream->FoldName = strDup1(fold,
"name of fold");
2160 c = GetFromStream(AC.CurrentStream);
2161 if ( c == ENDOFSTREAM ) {
2162 AC.CurrentStream = CloseStream(AC.CurrentStream);
2165 if ( c == AP.ComChar ) {
2166 str1offset = AC.CurrentStream-AC.Streams;
2168 if ( AC.CurrentStream != str1offset+AC.Streams ) {
2173 if ( t[2] ==
'#' && ( ( t[3] ==
'[' && !foldopen )
2174 || ( t[3] ==
']' && foldopen ) ) ) {
2176 while ( *t ==
' ' || *t ==
'\t' ) t++;
2177 s = AC.CurrentStream->FoldName;
2178 while ( *s == *t ) { s++; t++; }
2179 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t' 2181 while ( *t ==
' ' || *t ==
'\t' ) t++;
2183 if ( foldopen == 0 ) {
2185 position = GetStreamPosition(AC.CurrentStream);
2186 linenum = AC.CurrentStream->linenumber;
2187 prevline = AC.CurrentStream->prevline;
2188 c3 = AC.CurrentStream->isnextchar;
2189 c1 = AC.CurrentStream->nextchar[0];
2190 c2 = AC.CurrentStream->nextchar[1];
2194 PositionStream(AC.CurrentStream,position);
2195 AC.CurrentStream->linenumber = linenum;
2196 AC.CurrentStream->prevline = prevline;
2197 AC.CurrentStream->eqnum = 1;
2199 AC.CurrentStream->isnextchar = c3;
2200 AC.CurrentStream->nextchar[0] = c1;
2201 AC.CurrentStream->nextchar[1] = c2;
2210 while ( c != LINEFEED && c != ENDOFSTREAM ) {
2211 c = GetFromStream(AC.CurrentStream);
2212 if ( c == ENDOFSTREAM ) {
2213 AC.CurrentStream = CloseStream(AC.CurrentStream);
2218 if ( c == ENDOFSTREAM ) {
2220 MesPrint(
"@Cannot find fold %s in file %s",fold,name);
2223 M_free(name,
"name of include file");
2227 M_free(name,
"name of include file");
2229 AC.NoShowInput = withnolist;
2230 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2244 int DoPreExchange(UBYTE *s)
2249 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2250 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2251 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2253 s++; s1 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2254 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2256 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2257 if ( *s !=
'$' )
goto syntax;
2258 s++; s2 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2259 if ( *s != 0 && *s !=
';' )
goto syntax;
2261 if ( ( num1 = GetDollar(s1) ) <= 0 ) {
2262 MesPrint(
"@$%s has not been defined (yet)",s1);
2265 if ( ( num2 = GetDollar(s2) ) <= 0 ) {
2266 MesPrint(
"@$%s has not been defined (yet)",s2);
2270 ExchangeDollars((
int)num1,(
int)num2);
2274 s1 = s; s = SkipAName(s);
2275 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2277 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2278 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
2279 s2 = s; s = SkipAName(s);
2280 if ( *s != 0 && *s !=
';' )
goto syntax;
2282 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
2283 MesPrint(
"@%s is not an expression",s1);
2286 if ( GetName(AC.exprnames,s2,&num2,NOAUTO) != CEXPRESSION ) {
2287 MesPrint(
"@%s is not an expression",s2);
2291 ExchangeExpressions((
int)num1,(
int)num2);
2296 MesPrint(
"@Proper syntax: %#exchange expr1,expr2 or %#exchange $var1,$var2");
2305 int DoCall(UBYTE *s)
2307 UBYTE *t, *u, *v, *name, c, cp, *args1, *args2, *t1, *t2, *wild = 0;
2308 int bratype = 0, wildargs = 0, inwildargs = 0, nwildargs = 0;
2311 int i, namesize, narg1, narg2, bralevel, numpre;
2313 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2314 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2319 name = s; s = EndOfToken(s); c = *s; *s = 0;
2320 for ( i = NumProcedures-1; i >= 0; i-- ) {
2321 if ( StrCmp(Procedures[i].name,name) == 0 )
break;
2323 p = (
PROCEDURE *)FromList(&AP.ProcList);
2327 while ( *t ) { t++; namesize++; }
2328 t = AP.procedureExtension;
2329 while ( *t ) { t++; namesize++; }
2330 t = p->name = (UBYTE *)Malloc1(namesize+2,
"procedure");
2332 while ( *u ) *t++ = *u++;
2334 v = AP.procedureExtension;
2335 while ( *v ) *t++ = *v++;
2338 p->p.buffer = LoadInputFile(p->name,PROCEDUREFILE);
2339 if ( p->p.buffer == 0 )
return(-1);
2343 p->p.buffer = Procedures[i].p.buffer;
2344 p->name = Procedures[i].name;
2349 if ( *t++ !=
'#' )
goto wrongfile;
2355 if ( StrCmp(t,name) != 0 )
goto wrongfile;
2363 bralevel = narg1 = narg2 = 0; args2 = u;
2368 while ( *u !=
')' ) {
2369 if ( *u ==
'?' ) { wildargs++; u++; nwildargs = narg2+1; }
2370 narg2++; u = EndOfToken(u); SKIPBLANKS(u)
2371 if ( *u ==
',' ) { u++; SKIPBLANKS(u) }
2372 else if ( *u !=
')' || ( wildargs > 1 ) ) {
2373 MesPrint(
"@Illegal argument field in procedure %s",p->name);
2378 while ( *u != LINEFEED ) u++;
2381 if ( *s ==
'(' ) bratype = 1;
2383 if ( *s ==
'{' && bratype == 0 ) bralevel++;
2384 else if ( *s ==
'(' && bratype == 1 ) bralevel++;
2385 else if ( *s ==
'}' && bratype == 0 ) {
2387 if ( bralevel == 0 ) {
2389 if ( wildargs && narg1 == nwildargs ) wild = s;
2392 else if ( *s ==
')' && bratype == 1 ) {
2394 if ( bralevel == 0 ) {
2396 if ( wildargs && narg1 == nwildargs ) wild = s;
2401 else if (set_in(*s,AC.separators)) {
2405 if ( wildargs && narg1 == nwildargs ) wild = s;
2407 else if ( *s ==
'\\' ) s++;
2409 }
while ( bralevel > 0 );
2410 if ( wildargs && narg1 >= narg2-1 ) {
2411 inwildargs = narg1-narg2+1;
2412 if ( inwildargs == 0 ) nwildargs = 0;
2414 while ( inwildargs > 1 ) {
2416 while ( *wild ) wild++;
2421 else if ( narg1 != narg2 && ( narg2 != 0 || narg1 != 1 || *args1 != 0 ) ) {
2422 MesPrint(
"@Arguments of procedure %s are not matching",p->name);
2426 for ( i = 0; i < narg2; i++ ) {
2431 if ( *t ==
'?' && inwildargs == 0 ) {
2432 args2 = EndOfToken(args2); c = *args2; *args2 = 0;
2433 if (
PutPreVar(t,(UBYTE *)
"",0,0) < 0 )
return(-1);
2436 args2 = EndOfToken(args2); c = *args2; *args2 = 0;
2439 if ( *t1 ==
'\\' ) t1++;
2440 if ( t1 != t2 ) *t2 = *t1;
2444 if (
PutPreVar(t,args1,0,0) < 0 )
return(-1);
2447 *args2 = c; SKIPBLANKS(args2)
2448 args2++; SKIPBLANKS(args2)
2450 streamoffset = AC.CurrentStream - AC.Streams;
2451 args1 = AC.CurrentStream->name;
2452 AC.CurrentStream->name = p->name;
2453 i1 = AC.CurrentStream->linenumber;
2454 i2 = AC.CurrentStream->prevline;
2455 AC.CurrentStream->prevline =
2456 AC.CurrentStream->linenumber = 2;
2457 OpenStream(u+1,PREREADSTREAM3,numpre,PRENOACTION);
2458 AC.Streams[streamoffset].name = args1;
2459 AC.Streams[streamoffset].linenumber = i1;
2460 AC.Streams[streamoffset].prevline = i2;
2461 AddToPreTypes(PRETYPEPROCEDURE);
2464 if ( i < 0 ) MesPrint(
"@File %s is not a proper procedure",p->name);
2465 else MesPrint(
"!!!Internal error with procedure names: %s",name);
2474 int DoDebug(UBYTE *s)
2477 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2478 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2479 NeedNumber(x,s,nonumber)
2480 if ( x < 0 || x >(PREPROONLY
2491 if ( ( x & PREPROONLY ) != 0 ) AP.PreDebug |= PREPROONLY;
2492 if ( ( x & DUMPTOCOMPILER ) != 0 ) AP.PreDebug |= DUMPTOCOMPILER;
2493 if ( ( x & DUMPOUTTERMS ) != 0 ) AP.PreDebug |= DUMPOUTTERMS;
2494 if ( ( x & DUMPINTERMS ) != 0 ) AP.PreDebug |= DUMPINTERMS;
2495 if ( ( x & DUMPTOSORT ) != 0 ) AP.PreDebug |= DUMPTOSORT;
2496 if ( ( x & DUMPTOPARALLEL ) != 0 ) AP.PreDebug |= DUMPTOPARALLEL;
2498 if ( ( x & THREADSDEBUG ) != 0 ) AP.PreDebug |= THREADSDEBUG;
2502 MesPrint(
"@Illegal argument for debug instruction");
2511 int DoTerminate(UBYTE *s)
2514 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2515 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2517 NeedNumber(x,s,nonumber)
2525 MesPrint(
"@Illegal argument for terminate instruction");
2543 UBYTE *t, c, *u, *uu;
2546 LONG linenum = AC.CurrentStream->linenumber;
2547 int oldNoShowInput = AC.NoShowInput, i;
2549 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
2550 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
2551 if ( PreSkip((UBYTE *)
"do",(UBYTE *)
"enddo",1) )
return(-1);
2559 AddToPreTypes(PRETYPEDO);
2561 loop = (
DOLOOP *)FromList(&AP.LoopList);
2562 loop->firstdollar = loop->lastdollar = loop->incdollar = -1;
2563 loop->NumPreTypes = AP.NumPreTypes-1;
2564 loop->PreIfLevel = AP.PreIfLevel;
2565 loop->PreSwitchLevel = AP.PreSwitchLevel;
2567 if ( PreLoad(&(loop->
p),(UBYTE *)
"do",(UBYTE *)
"enddo",1,
"doloop") )
return(-1);
2568 AC.NoShowInput = oldNoShowInput;
2569 loop->NoShowInput = AC.NoShowInput;
2573 s = loop->
p.buffer + (s - AP.preStart);
2576 if ( chartype[*s] != 0 )
goto illname;
2578 while ( chartype[*s] <= 1 ) s++;
2580 while ( *s ==
' ' || *s ==
'\t' ) s++;
2581 if ( *s !=
'=' )
goto illdo;
2583 while ( *s ==
' ' || *s ==
'\t' ) s++;
2587 loop->type = LISTEDLOOP;
2588 s++; loop->vars = s;
2590 while ( *s !=
'}' && *s != 0 ) {
2591 if ( set_in(*s,AC.separators) ) { *s = 0; loop->lastnum++; }
2592 else if ( *s ==
'\\' ) s++;
2595 if ( *s == 0 )
goto illdo;
2601 else if ( *s ==
'-' || *s ==
'+' || chartype[*s] == 1 || *s ==
'$' ) {
2602 loop->type = NUMERICALLOOP;
2604 while ( *s && *s !=
',' ) s++;
2605 if ( *s == 0 )
goto illdo;
2608 if ( GetName(AC.dollarnames,t+1,&loop->firstdollar,NOAUTO) != CDOLLAR ) {
2609 MesPrint(
"@%s is undefined in first parameter in %#do instruction",t);
2612 loop->firstnum = DolToLong(BHEAD loop->firstdollar);
2613 if ( AN.ErrorInDollar ) {
2614 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2621 if ( PreEval(t,&loop->firstnum) == 0 )
goto illdo;
2625 while ( *s && *s !=
',' && *s !=
';' && *s != LINEFEED ) s++;
2629 if ( GetName(AC.dollarnames,t+1,&loop->lastdollar,NOAUTO) != CDOLLAR ) {
2630 MesPrint(
"@%s is undefined in second parameter in %#do instruction",t);
2633 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
2634 if ( AN.ErrorInDollar ) {
2635 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2642 if ( PreEval(t,&loop->lastnum) == 0 )
goto illdo;
2647 while ( *s && *s !=
';' && *s != LINEFEED ) s++;
2650 if ( GetName(AC.dollarnames,t+1,&loop->incdollar,NOAUTO) != CDOLLAR ) {
2651 MesPrint(
"@%s is undefined in third parameter in %#do instruction",t);
2654 loop->incnum = DolToLong(BHEAD loop->incdollar);
2655 if ( AN.ErrorInDollar ) {
2656 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2663 if ( PreEval(t,&loop->incnum) == 0 )
goto illdo;
2667 else loop->incnum = 1;
2670 else if ( ( chartype[*s] == 0 ) || ( *s ==
'[' ) ) {
2671 int oldNumPotModdollars = NumPotModdollars;
2673 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
2674 AC.RhsExprInModuleFlag = 0;
2677 if ( ( s = SkipAName(s) ) == 0 )
goto illdo;
2679 if ( GetName(AC.exprnames,t,&expnum,NOAUTO) == CEXPRESSION ) {
2680 loop->type = ONEEXPRESSION;
2689 if ( c ==
',' || c ==
'\t' || c ==
';' ) { s++; }
2690 else if ( c != 0 && c !=
'\n' )
goto illdo;
2691 while ( *s ==
',' || *s ==
'\t' || *s ==
';' ) s++;
2692 if ( *s != 0 && *s !=
'\n' )
goto illdo;
2703 while ( *t ) { t++; i++; }
2705 loop->
dollarname = Malloc1((LONG)i,
"do-loop instruction");
2710 *u++ =
'$'; t = loop->
name;
while ( *t ) *u++ = *t++;
2711 *u++ =
'_'; uu = u; *u++ =
'='; t = loop->vars;
2712 while ( *t ) *u++ = *t++; *t = 0; *u = 0;
2717 AP.PreAssignFlag = 2;
2719 if ( CatchDollar(0) ) {
2720 MesPrint(
"@Cannot load expression in do loop");
2723 AP.PreAssignFlag = 0;
2724 NumPotModdollars = oldNumPotModdollars;
2726 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
2731 loop->errorsinloop = 0;
2733 loop->startlinenumber = linenum;
2735 loop->firstloopcall = 1;
2738 MesPrint(
"@Improper name for do loop variable");
2741 MesPrint(
"@Improper syntax in do loop instruction");
2753 int DoBreakDo(UBYTE *s)
2758 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2759 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2761 if ( NumDoLoops <= 0 ) {
2762 MesPrint(
"@%#dobreak without %#do");
2768 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
2772 else if ( FG.cTable[*s] == 1 ) {
2774 while ( *s >=
'0' && *s <=
'9' ) { levels = 10*levels + *s++ -
'0'; }
2775 if ( *s != 0 )
goto improper;
2779 MesPrint(
"@Improper syntax of %#dobreak instruction");
2782 if ( levels > NumDoLoops ) {
2783 MesPrint(
"@Too many loop levels requested in %#breakdo instruction");
2786 while ( levels > 0 ) {
2787 while ( AC.CurrentStream->type != PREREADSTREAM
2788 && AC.CurrentStream->type != PREREADSTREAM2
2789 && AC.CurrentStream->type != PREREADSTREAM3 ) {
2790 AC.CurrentStream = CloseStream(AC.CurrentStream);
2792 while ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO
2793 && AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) AP.NumPreTypes--;
2794 if ( AC.CurrentStream->type == PREREADSTREAM3
2795 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
2796 MesPrint(
"@Trying to jump out of a procedure with a %#breakdo instruction");
2799 loop = &(DoLoops[NumDoLoops-1]);
2800 AP.NumPreTypes = loop->NumPreTypes;
2801 AP.PreIfLevel = loop->PreIfLevel;
2802 AP.PreSwitchLevel = loop->PreSwitchLevel;
2807 DoUndefine(loop->
name);
2808 M_free(loop->
p.buffer,
"loop->p.buffer");
2809 loop->firstloopcall = 0;
2811 AC.CurrentStream = CloseStream(AC.CurrentStream);
2822 int DoElse(UBYTE *s)
2824 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
2825 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#else without corresponding %#if");
2826 else MessPreNesting(1);
2829 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2830 while ( *s ==
' ' ) s++;
2831 if ( tolower(*s) ==
'i' && tolower(s[1]) ==
'f' && s[2]
2832 && FG.cTable[s[2]] > 1 && s[2] !=
'_' ) {
2834 while ( *s ==
' ' ) s++;
2835 return(DoElseif(s));
2837 if ( AP.PreIfLevel <= 0 ) {
2838 MesPrint(
"@%#else without corresponding %#if");
2841 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
2843 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
2845 case LOOKINGFORELSE:
2846 AP.PreIfStack[AP.PreIfLevel] = EXECUTINGIF;
2848 case LOOKINGFORENDIF:
2859 int DoElseif(UBYTE *s)
2862 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
2863 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#elseif without corresponding %#if");
2864 else MessPreNesting(2);
2867 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2868 if ( AP.PreIfLevel <= 0 ) {
2869 MesPrint(
"@%#elseif without corresponding %#if");
2872 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
2874 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
2876 case LOOKINGFORELSE:
2877 if ( ( condition = EvalPreIf(s) ) < 0 )
return(-1);
2878 AP.PreIfStack[AP.PreIfLevel] = condition;
2880 case LOOKINGFORENDIF:
2894 int DoEnddo(UBYTE *s)
2898 UBYTE *t, *tt, *value, numstr[16];
2902 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2903 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2912 if ( NumDoLoops <= 0 ) {
2913 MesPrint(
"@%#enddo without %#do");
2916 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO ) { MessPreNesting(4);
return(-1); }
2917 loop = &(DoLoops[NumDoLoops-1]);
2918 if ( !loop->firstloopcall ) AC.CurrentStream = CloseStream(AC.CurrentStream);
2920 if ( loop->errorsinloop ) {
2921 MesPrint(
"++++Errors in Loop");
2924 if ( loop->type == LISTEDLOOP ) {
2925 if ( loop->firstnum >= loop->lastnum )
goto finish;
2927 t = value = loop->vars;
2928 while ( *value ) value++;
2933 if ( *value ==
'\\' ) value++;
2939 else if ( loop->type == NUMERICALLOOP ) {
2941 if ( !loop->firstloopcall ) {
2946 t = GetPreVar(loop->name,WITHOUTERROR);
2950 while ( *value && ( *value ==
' ' 2951 || *value ==
'-' || *value ==
'+' ) ) {
2952 if ( *value ==
'-' ) xsign = -xsign;
2955 t = value; xval = 0;
2956 while ( *value >=
'0' && *value <=
'9' ) xval = 10*xval + *value++ -
'0';
2957 while ( *value && *value ==
' ' ) value++;
2958 if ( *value == 0 ) {
2962 if ( xsign < 0 ) xval = -xval;
2963 if ( loop->incdollar >= 0 ) {
2964 loop->incnum = DolToLong(BHEAD loop->incdollar);
2965 if ( AN.ErrorInDollar ) {
2966 MesPrint(
"@%s does not evaluate into a valid third loop parameter",DOLLARNAME(Dollars,loop->incdollar));
2970 loop->firstnum = xval + loop->incnum;
2973 if ( loop->lastdollar >= 0 ) {
2974 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
2975 if ( AN.ErrorInDollar ) {
2976 MesPrint(
"@%s does not evaluate into a valid second loop parameter",DOLLARNAME(Dollars,loop->lastdollar));
2981 if ( ( loop->incnum > 0 && loop->firstnum > loop->lastnum )
2982 || ( loop->incnum < 0 && loop->firstnum < loop->lastnum ) )
goto finish;
2983 NumToStr(numstr,loop->firstnum);
2985 loop->firstnum += loop->incnum;
2988 else if ( loop->type == ONEEXPRESSION ) {
2992 WORD numdollar = GetDollar(loop->dollarname+1);
2993 DOLLARS d = Dollars + numdollar;
2994 WORD *w, *dw, v, *ww;
2995 if ( (d->where) == 0 ) {
2996 d->type = DOLUNDEFINED;
2997 M_free(loop->dollarname,
"do-loop instruction");
3000 w = d->where + loop->incnum;
3002 M_free(d->where,
"dollar");
3004 d->type = DOLUNDEFINED;
3005 M_free(loop->dollarname,
"do-loop instruction");
3012 ww = w + *w; v = *ww; *ww = 0;
3013 dw = d->where; d->where = w;
3014 t = WriteDollarToBuffer(numdollar,1);
3015 d->where = dw; *ww = v;
3019 if ( loop->firstloopcall ) OpenStream(loop->contents,PREREADSTREAM2,0,PRENOACTION);
3020 else OpenStream(loop->contents,PREREADSTREAM,0,PRENOACTION);
3021 AC.CurrentStream->prevline =
3022 AC.CurrentStream->linenumber = loop->startlinenumber;
3023 AC.CurrentStream->eqnum = 0;
3024 loop->firstloopcall = 0;
3028 retval = DoUndefine(loop->name);
3029 M_free(loop->p.buffer,
"loop->p.buffer");
3030 loop->firstloopcall = 0;
3040 int DoEndif(UBYTE *s)
3043 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3044 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#endif without corresponding %#if");
3045 else MessPreNesting(5);
3049 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3050 if ( AP.PreIfLevel <= 0 ) {
3051 MesPrint(
"@%#endif without corresponding %#if");
3068 int DoEndprocedure(UBYTE *s)
3071 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) {
3076 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3077 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3078 AC.CurrentStream = CloseStream(AC.CurrentStream);
3081 if ( Procedures[NumProcedures].loadmode == 0 ) {
3082 M_free(Procedures[NumProcedures].p.buffer,
"procedures buffer");
3083 M_free(Procedures[NumProcedures].name,
"procedures name");
3085 }
while ( Procedures[NumProcedures].loadmode > 1 );
3097 AddToPreTypes(PRETYPEIF);
3098 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3099 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3100 condition = EvalPreIf(s);
3101 if ( condition < 0 )
return(-1);
3103 else condition = LOOKINGFORENDIF;
3104 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3105 int **ppp = &AP.PreIfStack;
3106 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3107 "PreIfLevels") )
return(-1);
3109 AP.PreIfStack[++AP.PreIfLevel] = condition;
3118 int DoIfdef(UBYTE *s,
int par)
3121 AddToPreTypes(PRETYPEIF);
3122 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3123 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3124 while ( *s ==
' ' || *s ==
'\t' ) s++;
3125 if ( ( *s == 0 ) == ( par == 1 ) ) condition = LOOKINGFORELSE;
3126 else condition = EXECUTINGIF;
3128 else condition = LOOKINGFORENDIF;
3129 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3130 int **ppp = &AP.PreIfStack;
3131 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3132 "PreIfLevels") )
return(-1);
3134 AP.PreIfStack[++AP.PreIfLevel] = condition;
3158 int DoInside(UBYTE *s)
3160 int numdol, error = 0;
3161 WORD *nb, newsize, i;
3163 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3164 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3165 if ( AP.PreInsideLevel != 0 ) {
3166 MesPrint(
"@Illegal nesting of %#inside/%#endinside instructions");
3169 if ( AP.PreContinuation ) {
3171 MesPrint(
"@%#inside cannot be inside a regular statement");
3176 AP.inside.numdollars = 0;
3178 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
3179 if ( *s == 0 )
break;
3181 MesPrint(
"@%#inside instruction can have only $ variables for parameters");
3186 while (chartype[*s] <= 1 ) s++;
3188 if ( ( numdol = GetDollar(name) ) < 0 ) {
3189 MesPrint(
"@%#inside: $%s has not (yet) been defined",name);
3195 if ( AP.inside.numdollars >= AP.inside.size ) {
3196 if ( AP.inside.buffer == 0 ) newsize = 20;
3197 else newsize = 2*AP.inside.size;
3198 nb = (WORD *)Malloc1(newsize*
sizeof(WORD),
"insidebuffer");
3199 if ( AP.inside.buffer ) {
3200 for ( i = 0; i < AP.inside.size; i++ ) nb[i] = AP.inside.buffer[i];
3201 M_free(AP.inside.buffer,
"insidebuffer");
3203 AP.inside.buffer = nb;
3204 AP.inside.size = newsize;
3206 AP.inside.buffer[AP.inside.numdollars++] = numdol;
3213 AP.inside.oldcompiletype = AC.compiletype;
3214 AP.inside.oldparallelflag = AC.mparallelflag;
3215 AP.inside.oldnumpotmoddollars = NumPotModdollars;
3216 AP.inside.oldcbuf = AC.cbufnum;
3217 AP.inside.oldrbuf = AM.rbufnum;
3218 AddToPreTypes(PRETYPEINSIDE);
3219 AP.PreInsideLevel = 1;
3220 AC.cbufnum = AP.inside.inscbuf;
3221 AM.rbufnum = AP.inside.inscbuf;
3222 clearcbuf(AC.cbufnum);
3224 AC.mparallelflag = PARALLELFLAG;
3233 PF_StoreInsideInfo();
3234 AC.RhsExprInModuleFlag = 0;
3235 NumPotModdollars = 0;
3236 AC.numpfirstnum = 0;
3246 int DoEndInside(UBYTE *s)
3249 WORD numdol, *oldworkpointer = AT.WorkPointer, *term, *t, j, i;
3251 WORD oldcnumlhs = AR.Cnumlhs, oldbracketon = AR.BracketOn;
3252 WORD *oldcompresspointer = AR.CompressPointer;
3253 int oldmultithreaded = AS.MultiThreaded;
3260 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3261 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3262 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEINSIDE ) {
3263 if ( AP.PreInsideLevel != 1 ) MesPrint(
"@%#endinside without corresponding %#inside");
3264 else MessPreNesting(11);
3268 if ( AP.PreInsideLevel != 1 ) {
3269 MesPrint(
"@%#endinside without corresponding %#inside");
3272 if ( AP.PreContinuation ) {
3273 MesPrint(
"@%#endinside: previous statement not terminated.");
3276 AC.compiletype = AP.inside.oldcompiletype;
3277 AR.Cnumlhs = cbuf[AM.rbufnum].numlhs;
3284 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
3287 AS.MultiThreaded = 0;
3289 if ( AR.CompressPointer == 0 ) AR.CompressPointer = AR.CompressBuffer;
3290 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3294 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3295 numdol = AP.inside.buffer[i];
3296 nd = d = Dollars + numdol;
3297 if ( d->type != DOLZERO ) {
3298 if ( d->type != DOLTERMS ) nd = DolToTerms(BHEAD numdol);
3302 AR.MaxDum = AM.IndDum;
3304 t = oldworkpointer; j = *term;
3307 AN.IndDum = AM.IndDum;
3308 AR.CurDum = ReNumber(BHEAD term);
3309 if (
Generator(BHEAD oldworkpointer,0) ) {
3310 MesPrint(
"@Called from %#endinside");
3311 MesPrint(
"@Evaluating variable $%s",DOLLARNAME(Dollars,numdol));
3315 AT.WorkPointer = oldworkpointer;
3316 CleanDollarFactors(d);
3317 if ( d->where ) { M_free(d->where,
"dollar contents"); d->where = 0; }
3318 EndSort(BHEAD (WORD *)((VOID *)(&(d->where))),2);
3320 term = d->where;
while ( *term ) term += *term;
3321 d->size = term - d->where;
3322 if ( nd != d ) M_free(nd,
"Copy of dollar variable");
3323 if ( d->where[0] == 0 ) {
3324 M_free(d->where,
"dollar contents"); d->where = 0;
3331 if ( AC.RhsExprInModuleFlag ) {
3336 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3344 if ( NumPotModdollars > 0 ) {
3346 if ( error )
goto cleanup;
3348 if ( AC.numpfirstnum > 0 ) {
3350 if ( error )
goto cleanup;
3355 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3356 AC.cbufnum = AP.inside.oldcbuf;
3357 AM.rbufnum = AP.inside.oldrbuf;
3358 AR.Cnumlhs = oldcnumlhs;
3359 AR.BracketOn = oldbracketon;
3360 AP.PreInsideLevel = 0;
3361 AR.CompressPointer = oldcompresspointer;
3362 AS.MultiThreaded = oldmultithreaded;
3363 AC.mparallelflag = AP.inside.oldparallelflag;
3364 NumPotModdollars = AP.inside.oldnumpotmoddollars;
3366 PF_RestoreInsideInfo();
3367 if ( error )
return error;
3377 int DoMessage(UBYTE *s)
3379 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3380 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3381 while ( *s ==
' ' || *s ==
'\t' ) s++;
3382 MesPrint(
"~~~%s",s);
3391 int DoPipe(UBYTE *s)
3396 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3397 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3400 while ( *s ==
' ' || *s ==
'\t' ) s++;
3401 if ( OpenStream(s,PIPESTREAM,0,PRENOACTION) == 0 )
return(-1);
3404 Error0(
"Pipes not implemented on this computer/system");
3414 int DoPrcExtension(UBYTE *s)
3417 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3418 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3419 while ( *s ==
' ' || *s ==
'\t' ) s++;
3420 if ( *s == 0 || *s ==
'\n' ) {
3421 MesPrint(
"@No valid procedure extension specified");
3424 if ( FG.cTable[*s] != 0 ) {
3425 MesPrint(
"@Procedure extension should be a string starting with an alphabetic character. No whitespace.");
3429 while ( *s && *s !=
'\n' && *s !=
' ' && *s !=
'\t' ) s++;
3431 while ( *s ==
' ' || *s ==
'\t' ) s++;
3432 if ( *s != 0 && *s !=
'\n' ) {
3433 MesPrint(
"@Too many parameters in ProcedureExtension instruction");
3437 if ( AP.procedureExtension ) M_free(AP.procedureExtension,
"ProcedureExtension");
3438 AP.procedureExtension = strDup1(t,
"ProcedureExtension");
3448 int DoPreOut(UBYTE *s)
3450 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3451 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3452 if ( tolower(*s) ==
'o' ) {
3453 if ( tolower(s[1]) ==
'n' && s[2] == 0 ) {
3457 if ( tolower(s[1]) ==
'f' && tolower(s[2]) ==
'f' && s[3] == 0 ) {
3462 MesPrint(
"@Illegal option in PreOut instruction");
3471 int DoPrePrintTimes(UBYTE *s)
3474 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3475 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3488 int DoPreAppend(UBYTE *s)
3492 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3493 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3494 while ( *s ==
' ' || *s ==
'\t' ) s++;
3501 while ( *s && *s !=
'>' ) {
3502 if ( *s ==
'\\' ) s++;
3506 MesPrint(
"@Improper termination of filename");
3511 if ( *name ) { GetAppendChannel((
char *)name); }
3516 MesPrint(
"@Proper syntax is: %#append <filename>");
3530 int DoPreCreate(UBYTE *s)
3534 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3535 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3536 while ( *s ==
' ' || *s ==
'\t' ) s++;
3543 while ( *s && *s !=
'>' ) {
3544 if ( *s ==
'\\' ) s++;
3548 MesPrint(
"@Improper termination of filename");
3553 if ( *name ) { GetChannel((
char *)name); }
3558 MesPrint(
"@Proper syntax is: %#create <filename>");
3569 int DoPreRemove(UBYTE *s)
3572 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3573 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3574 while ( *s ==
' ' || *s ==
'\t' ) s++;
3575 if ( *s ==
'<' ) { s++; }
3577 MesPrint(
"@Proper syntax is: %#remove <filename>");
3581 while ( *s && *s !=
'>' ) {
3582 if ( *s ==
'\\' ) s++;
3586 MesPrint(
"@Improper filename");
3591 CloseChannel((
char *)name);
3592 remove((
char *)name);
3601 int DoPreClose(UBYTE *s)
3604 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3605 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3606 while ( *s ==
' ' || *s ==
'\t' ) s++;
3607 if ( *s ==
'<' ) { s++; }
3609 MesPrint(
"@Proper syntax is: %#close <filename>");
3613 while ( *s && *s !=
'>' ) {
3614 if ( *s ==
'\\' ) s++;
3618 MesPrint(
"@Improper filename");
3623 return(CloseChannel((
char *)name));
3644 int DoPreWrite(UBYTE *s)
3648 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3649 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3652 if ( PF.me != MASTER )
return 0;
3655 h.oldsilent = AM.silent;
3656 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
3657 h.newhandle = h.oldhandle = AC.LogHandle;
3658 h.oldprinttype = AO.PrintType;
3660 while ( *s ==
' ' || *s ==
'\t' ) s++;
3664 if( (s=defineChannel(s,&h))==0 )
return(-1);
3666 return(writeToChannel(WRITEOUT,s,&h));
3684 int DoProcedure(UBYTE *s)
3689 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
3690 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
3691 if ( PreSkip((UBYTE *)
"procedure",(UBYTE *)
"endprocedure",1) )
return(-1);
3694 p = (
PROCEDURE *)FromList(&AP.ProcList);
3695 if ( PreLoad(&(p->p),(UBYTE *)
"procedure",(UBYTE *)
"endprocedure" 3696 ,1,(
char *)
"procedure") )
return(-1);
3699 s = p->p.buffer + 10;
3700 while ( *s ==
' ' || *s == LINEFEED ) s++;
3701 if ( chartype[*s] ) {
3702 MesPrint(
"@Illegal name for procedure");
3706 while ( chartype[*s] == 0 || chartype[*s] == 1 ) s++;
3708 p->name = strDup1(p->name,
"procedure");
3713 for ( i = NumProcedures-2; i >= 0; i-- ) {
3714 if ( StrCmp(Procedures[i].name,p->name) == 0 ) {
3715 Error1(
"Multiple occurrence of procedure name ",p->name);
3726 int DoPreBreak(UBYTE *s)
3729 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3730 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3731 if ( AP.PreSwitchLevel <= 0 )
3732 MesPrint(
"@Break without corresponding Switch");
3733 else MessPreNesting(7);
3736 if ( AP.PreSwitchLevel <= 0 ) {
3737 MesPrint(
"@Break without corresponding Switch");
3740 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH )
3741 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
3750 int DoPreCase(UBYTE *s)
3753 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3754 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3755 if ( AP.PreSwitchLevel <= 0 )
3756 MesPrint(
"@Case without corresponding Switch");
3757 else MessPreNesting(8);
3760 if ( AP.PreSwitchLevel <= 0 ) {
3761 MesPrint(
"@Case without corresponding Switch");
3764 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
3768 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
3769 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
3770 if ( s[-2] ==
'\\' ) s--;
3773 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
3777 s = AP.PreSwitchStrings[AP.PreSwitchLevel];
3778 while ( *t == *s && *t ) { s++; t++; }
3779 if ( *t || *s )
return(0);
3780 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
3789 int DoPreDefault(UBYTE *s)
3792 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3793 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3794 if ( AP.PreSwitchLevel <= 0 )
3795 MesPrint(
"@Default without corresponding Switch");
3796 else MessPreNesting(9);
3799 if ( AP.PreSwitchLevel <= 0 ) {
3800 MesPrint(
"@Default without corresponding Switch");
3803 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
3804 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
3813 int DoPreEndSwitch(UBYTE *s)
3816 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3817 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3818 if ( AP.PreSwitchLevel <= 0 )
3819 MesPrint(
"@EndSwitch without corresponding Switch");
3820 else MessPreNesting(10);
3824 if ( AP.PreSwitchLevel <= 0 ) {
3825 MesPrint(
"@EndSwitch without corresponding Switch");
3828 M_free(AP.PreSwitchStrings[AP.PreSwitchLevel--],
"pre switch string");
3840 int DoPreSwitch(UBYTE *s)
3842 UBYTE *t, *switchstring, **newstrings;
3843 int newnum, i, *newmodes;
3844 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3847 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
3848 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
3849 if ( s[-2] ==
'\\' ) s--;
3852 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
3856 switchstring = (UBYTE *)Malloc1((s-t)+1,
"case string");
3859 if ( *t ==
'\\' ) t++;
3863 if ( AP.PreSwitchLevel >= AP.NumPreSwitchStrings ) {
3864 newnum = 2*AP.NumPreSwitchStrings;
3865 newstrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*(newnum+1),
"case strings");
3866 newmodes = (
int *)Malloc1(
sizeof(
int)*(newnum+1),
"case strings");
3867 for ( i = 0; i < AP.NumPreSwitchStrings; i++ )
3868 newstrings[i] = AP.PreSwitchStrings[i];
3869 M_free(AP.PreSwitchStrings,
"AP.PreSwitchStrings");
3870 for ( i = 0; i <= AP.NumPreSwitchStrings; i++ )
3871 newmodes[i] = AP.PreSwitchModes[i];
3872 M_free(AP.PreSwitchModes,
"AP.PreSwitchModes");
3873 AP.PreSwitchStrings = newstrings;
3874 AP.PreSwitchModes = newmodes;
3875 AP.NumPreSwitchStrings = newnum;
3877 AP.PreSwitchStrings[++AP.PreSwitchLevel] = switchstring;
3878 if ( ( AP.PreSwitchLevel > 1 )
3879 && ( AP.PreSwitchModes[AP.PreSwitchLevel-1] != EXECUTINGPRESWITCH ) )
3880 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
3882 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPRECASE;
3883 AddToPreTypes(PRETYPESWITCH);
3894 int DoPreShow(UBYTE *s)
3898 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3899 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3900 while ( *s ==
' ' || *s ==
'\t' ) s++;
3902 MesPrint(
"%#The preprocessor variables:");
3903 for ( i = 0; i < NumPre; i++ ) {
3904 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
3909 name = s;
while ( *s && *s !=
' ' && *s !=
'\t' && *s !=
',' ) s++;
3911 for ( i = 0; i < NumPre; i++ ) {
3912 if ( StrCmp(PreVar[i].name,name) == 0 )
3913 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
3916 while ( *s ==
' ' || *s ==
'\t' ) s++;
3927 int DoSystem(UBYTE *s)
3929 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3930 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3933 while ( *s ==
' ' || *s ==
'\t' ) s++;
3934 if ( system((
char *)s) ) {
3935 MesPrint(
"@System call returned with error condition");
3940 Error0(
"External programs not implemented on this computer/system");
3953 int PreLoad(
PRELOAD *p, UBYTE *start, UBYTE *stop,
int mode,
char *message)
3955 UBYTE *s, *t, *top, *newbuffer, c;
3956 LONG i, ppsize, linenum = AC.CurrentStream->linenumber;
3957 int size1, size2, level, com=0, last=1, strng = 0;
3959 p->buffer = (UBYTE *)Malloc1(p->size+1,message);
3960 top = p->buffer + p->size - 2;
3961 t = p->buffer; *t++ =
'#';
3962 s = start; size1 = size2 = 0;
3963 while ( *s ) { s++; size1++; }
3964 s = stop;
while ( *s ) { s++; size2++; }
3965 s = AP.preStart;
while ( *s ) *t++ = *s++; *t++ = LINEFEED;
3970 if ( c == ENDOFINPUT ) {
3971 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
3974 if ( c == AP.ComChar && last == 1 ) com = 1;
3975 if ( c == LINEFEED ) { last = 1; com = 0; }
3978 if ( ( c ==
'"' ) && ( com == 0 ) ) { strng ^= 1; }
3980 if ( ( c ==
'#' ) && ( com == 0 ) ) i = 0;
3984 ppsize = t - p->buffer;
3986 newbuffer = (UBYTE *)Malloc1(p->size,message);
3987 t = newbuffer; s = p->buffer;
3988 while ( --ppsize >= 0 ) *t++ = *s++;
3989 M_free(p->buffer,
"loading do loop");
3990 p->buffer = newbuffer;
3991 top = p->buffer + p->size - 2;
3995 if ( ( i == size2 ) && ( com == 0 ) ) {
3997 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
3998 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4000 if ( level <= 0 )
break;
4001 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4002 *t++ = LINEFEED; *t = 0;
4005 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4007 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4015 if ( i == 1 && t[-2] == LINEFEED ) {
4016 if ( c ==
'-' ) AC.NoShowInput = 1;
4017 else if ( c ==
'+' ) AC.NoShowInput = 0;
4034 #define SKIPBUFSIZE 20 4036 int PreSkip(UBYTE *start, UBYTE *stop,
int mode)
4038 UBYTE *s, *t, buffer[SKIPBUFSIZE+2], c;
4039 LONG i, linenum = AC.CurrentStream->linenumber;
4040 int size1, size2, level, com=0, last=1;
4042 t = buffer; *t++ =
'#';
4043 s = start; size1 = size2 = 0;
4044 while ( *s ) { s++; size1++; }
4045 s = stop;
while ( *s ) { s++; size2++; }
4050 if ( c == ENDOFINPUT ) {
4051 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4054 if ( c == AP.ComChar && last == 1 ) com = 1;
4055 if ( c == LINEFEED ) { last = 1; com = 0; i = 0; t = buffer; }
4057 if ( ( c ==
'#' ) && ( com == 0 ) ) { i = 0; t = buffer; }
4060 if ( i < SKIPBUFSIZE ) *t++ = c;
4061 if ( ( i == size2 ) && ( com == 0 ) ) {
4063 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4064 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4067 pushbackchar = LINEFEED;
4070 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4074 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4076 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4077 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4094 AP.MaxPreIfLevel = 2;
4095 ppp = &AP.PreIfStack;
4096 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
4097 "PreIfLevels") ) Terminate(-1);
4098 AP.PreIfLevel = 0; AP.PreIfStack[0] = EXECUTINGIF;
4100 AP.NumPreSwitchStrings = 10;
4101 AP.PreSwitchStrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*
4102 (AP.NumPreSwitchStrings+1),
"case strings");
4103 AP.PreSwitchModes = (
int *)Malloc1(
sizeof(
int)*
4104 (AP.NumPreSwitchStrings+1),
"case strings");
4105 AP.PreSwitchModes[0] = EXECUTINGPRESWITCH;
4106 AP.PreSwitchLevel = 0;
4119 int EvalPreIf(UBYTE *s)
4127 if ( ( u = PreIfEval(s,&val) ) == 0 )
return(-1);
4129 MesPrint(
"@Unmatched parentheses in condition");
4132 if ( val )
return(EXECUTINGIF);
4133 else return(LOOKINGFORELSE);
4154 UBYTE *PreIfEval(UBYTE *s,
int *value)
4156 int orlevel = 0, andlevel = 0, eqlevel = 0, cmplevel = 0;
4159 int ortype, orval, cmptype, cmpval, eqtype, eqval, andtype, andval;
4160 UBYTE *t, *eqt, *cmpt, c;
4162 ortype = orval = cmptype = cmpval = eqtype = eqval = andtype = andval = 0;
4166 while ( *s !=
')' ) {
4167 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4169 s = pParseObject(s,&type,&val2);
4170 if ( s == 0 )
return(0);
4174 while ( c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' ) {
4177 if ( *t ==
'"' ) t++;
4180 if ( *s !=
'|' )
goto illoper;
4184 if ( type == 0 || cmptype == 0 )
goto illobject;
4185 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4190 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4195 if ( andtype != 0 || type != 0 )
goto illobject;
4200 if ( ortype != 0 || type != 0 )
goto illobject;
4212 if ( *s !=
'&' )
goto illoper;
4215 if ( type == 0 || cmptype == 0 )
goto illobject;
4216 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4221 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4226 if ( andtype != 0 || type != 0 )
goto illobject;
4235 if ( eqlevel )
goto illorder;
4237 if ( type == 0 || cmptype == 0 )
goto illobject;
4238 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4242 if ( c ==
'!' && *s !=
'=' )
goto illoper;
4243 if ( *s ==
'=' ) s++;
4244 if ( c ==
'!' ) eqop = 1;
4246 eqlevel = 1; eqt = t; eqval = val; eqtype = type;
4250 if ( cmplevel )
goto illorder;
4251 if ( c ==
'<' ) cmpop = -1;
4253 cmplevel = 1; cmpt = t; cmpval = val; cmptype = type;
4256 if ( *s ==
'~' ) { s++; cmpop *= 4; }
4259 else if ( *s ==
'~' ) { s++; cmpop *= 3; }
4267 MesPrint(
"@illegal order of operators");
4270 MesPrint(
"@illegal object for this operator");
4273 MesPrint(
"@illegal operator");
4282 int PreCmp(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int cmpop)
4284 if ( type == 2 || type2 == 2 || cmpop < -2 || cmpop > 2 ) {
4285 if ( cmpop < 0 && cmpop > -3 ) cmpop -= 2;
4286 if ( cmpop > 0 && cmpop < 3 ) cmpop += 2;
4287 if ( cmpop == 3 ) val = StrCmp(t2,t) > 0;
4288 else if ( cmpop == 4 ) val = StrCmp(t2,t) >= 0;
4289 else if ( cmpop == -3 ) val = StrCmp(t2,t) < 0;
4290 else if ( cmpop == -4 ) val = StrCmp(t2,t) <= 0;
4293 if ( cmpop == 1 ) val = ( val2 > val );
4294 else if ( cmpop == 2 ) val = ( val2 >= val );
4295 else if ( cmpop == -1 ) val = ( val2 < val );
4296 else if ( cmpop == -2 ) val = ( val2 <= val );
4306 int PreEq(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int eqop)
4309 if ( type == 2 || type2 == 2 ) {
4310 if ( type != 2 ) { NumToStr(str,val ); t = str; }
4311 if ( type2 != 2 ) { NumToStr(str,val2); t2 = str; }
4312 if ( eqop == 1 ) val = StrCmp(t,t2) != 0;
4313 else val = StrCmp(t,t2) == 0;
4316 if ( eqop ) val = val != val2;
4317 else val = val == val2;
4335 UBYTE *pParseObject(UBYTE *s,
int *type, LONG *val2)
4340 while ( *s ==
' ' || *s ==
'\t' ) s++;
4343 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4344 s = PreIfEval(s,&val);
4349 else if ( *s ==
'$' && s[1] ==
'(' ) {
4351 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4352 s = PreIfDollarEval(s,&val);
4353 *type = 0; *val2 = val;
4358 MesPrint(
"@illegal end of condition");
4363 while ( *s && *s !=
'"' ) {
4364 if ( *s ==
'\\' ) s++;
4367 if ( *s == 0 )
goto illend;
4372 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4376 t = s; sign = 1; x = 0;
4377 if ( chartype[*t] == 0 ) {
4378 do { t++; }
while ( chartype[*t] <= 1 );
4381 if ( StrICmp(s,(UBYTE *)
"termsin") == 0 ) {
4383 WORD numdol, numexp;
4385 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4387 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4389 if ( ( numdol = GetDollar(t) ) > 0 ) {
4391 x = TermsInDollar(numdol);
4394 MesPrint(
"@$%s has not (yet) been defined",t);
4402 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4403 MesPrint(
"@%s has not (yet) been defined",t);
4409 x = TermsInExpression(numexp);
4412 while ( *tt ==
' ' || *tt ==
'\t' 4413 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4415 MesPrint(
"@Improper use of terms($var) or terms(expr)");
4423 else if ( StrICmp(s,(UBYTE *)
"exists") == 0 ) {
4425 WORD numdol, numexp;
4427 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4429 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4431 if ( ( numdol = GetDollar(t) ) >= 0 ) { x = 1; }
4438 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) { x = 0; }
4442 while ( *tt ==
' ' || *tt ==
'\t' 4443 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4445 MesPrint(
"@Improper use of exists($var) or exists(expr)");
4453 else if ( StrICmp(s,(UBYTE *)
"isnumerical") == 0 ) {
4456 WORD numdol, numexp;
4458 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4460 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4462 if ( ( numdol = GetDollar(t) ) < 0 ) {
4463 MesPrint(
"@$ variable in isnumerical(%s) does not exist",t);
4466 x = DolToLong(BHEAD numdol);
4467 if ( AN.ErrorInDollar ) {
4470 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
4471 if ( d->where[0] == 0 ) x = 1;
4472 else if ( d->where[d->where[0]] == 0 ) {
4473 if ( ABS(d->where[d->where[0]-1]) == d->where[0]-1 )
4484 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4485 MesPrint(
"@expression in isnumerical(%s) does not exist",t);
4488 x = TermsInExpression(numexp);
4489 if ( x != 1 ) x = 0;
4491 WORD *term = AT.WorkPointer;
4492 if ( GetFirstTerm(term,numexp) < 0 ) {
4493 MesPrint(
"@error reading expression in isnumerical(%s)",t);
4496 if ( *term == ABS(term[*term-1])+1 ) x = 1;
4501 while ( *tt ==
' ' || *tt ==
'\t' 4502 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4504 MesPrint(
"@Improper use of isnumerical($var) or numerical(expr)");
4512 else if ( StrICmp(s,(UBYTE *)(
"maxpowerof")) == 0 ) {
4517 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4520 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4521 MesPrint(
"@%s has not (yet) been defined",t);
4525 else if ( stype != CSYMBOL ) {
4526 MesPrint(
"@%s should be a symbol",t);
4532 x = symbols[numsym].maxpower;
4534 while ( *tt ==
' ' || *tt ==
'\t' 4535 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4537 MesPrint(
"@Improper use of maxpowerof(symbol)");
4545 else if ( StrICmp(s,(UBYTE *)(
"minpowerof")) == 0 ) {
4550 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4553 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4554 MesPrint(
"@%s has not (yet) been defined",t);
4558 else if ( stype != CSYMBOL ) {
4559 MesPrint(
"@%s should be a symbol",t);
4565 x = symbols[numsym].minpower;
4567 while ( *tt ==
' ' || *tt ==
'\t' 4568 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4570 MesPrint(
"@Improper use of minpowerof(symbol)");
4578 else if ( StrICmp(s,(UBYTE *)
"isfactorized") == 0 ) {
4580 WORD numdol, numexp;
4582 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4584 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4586 if ( ( numdol = GetDollar(t) ) > 0 ) {
4587 if ( Dollars[numdol].factors != 0 ) x = 1;
4591 MesPrint(
"@ %s should be the name of an expression or a $ variable",t-1);
4599 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4600 MesPrint(
"@ %s should be the name of an expression or a $ variable",t);
4604 if ( ( Expressions[numexp].vflags & ISFACTORIZED ) != 0 ) x = 1;
4609 while ( *tt ==
' ' || *tt ==
'\t' 4610 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4612 MesPrint(
"@Improper use of isfactorized($var) or isfactorized(expr)");
4622 else if ( *t ==
'=' || *t ==
'<' || *t ==
'>' || *t ==
'!' 4623 || *t ==
')' || *t ==
' ' || *t ==
'\t' || *t == 0 || *t ==
'\n' ) {
4629 MesPrint(
"@Illegal use of string in preprocessor condition: %s",s);
4633 while ( *t ==
'-' || *t ==
'+' || *t ==
' ' || *t ==
'\t' ) {
4634 if ( *t ==
'-' ) sign = -sign;
4637 while ( chartype[*t] == 1 ) { x = 10*x + *t++ -
'0'; }
4638 while ( *t ==
' ' || *t ==
'\t' ) t++;
4639 if ( chartype[*t] == 8 || *t ==
')' || *t ==
'=' || *t == 0 ) {
4640 *val2 = sign > 0 ? x: -x;
4644 while ( chartype[*t] != 8 && *t !=
')' && *t !=
'=' && *t ) t++;
4645 while ( ( t > s ) && ( t[-1] ==
' ' || t[-1] ==
'\t' ) ) t--;
4666 UBYTE *buff, *s = 0, *t, *newb, c;
4667 int size, i, n, parlevel = 0, bralevel = 0;
4673 if ( size == 0 ) size = 72;
4675 if ( ( newb = (UBYTE *)Malloc1(size+2,
"{}") ) == 0 )
return(0);
4681 M_free(buff,
"pre calc buffer");
4689 Error0(
"Unmatched {}");
4690 M_free(buff,
"precalc buffer");
4693 else if ( c ==
'{' ) { bralevel++; }
4694 else if ( c ==
'}' ) {
4695 if ( --bralevel < 0 ) { *s++ = c; *s = 0;
break; }
4697 else if ( c ==
'(' ) { parlevel++; }
4698 else if ( c ==
')' ) {
4699 if ( --parlevel < 0 ) { *s++ = c; *s = 0;
goto setstring; }
4701 else if ( chartype[c] != 1 && chartype[c] != 5
4702 && chartype[c] != 6 && c !=
'!' && c !=
'&' 4703 && c !=
'|' && c !=
'\\' ) { *s++ = c; *s = 0;
goto setstring; }
4705 if ( parlevel > 0 )
goto setstring;
4711 if ( PreEval(buff+1,&answer) == 0 )
goto setstring;
4714 if ( answer < 0 ) { *s++ =
'-'; answer = -answer; }
4717 *--t = ( answer % 10 ) +
'0';
4720 }
while ( answer > 0 );
4728 if ( OpenStream(buff,PRECALCSTREAM,0,PRENOACTION) == 0 )
return(0);
4740 UBYTE *PreEval(UBYTE *s, LONG *x)
4743 int tobemultiplied, tobeadded = 1, expsign, i;
4746 while ( *s ==
' ' || *s ==
'\t' ) s++;
4748 if ( *s ==
'+' || *s ==
'-' ) {
4749 if ( *s ==
'-' ) tobeadded = -1;
4752 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
4753 if ( *s ==
'-' ) tobeadded = -tobeadded;
4759 while ( *s ==
' ' || *s ==
'\t' ) s++;
4760 if ( *s <= '9' && *s >=
'0' ) {
4763 else if ( *s ==
'(' || *s ==
'{' ) {
4764 if ( ( t = PreEval(s+1,&y) ) == 0 )
return(0);
4768 while ( *s ==
' ' || *s ==
'\t' ) s++;
4770 while ( *s ==
'^' || *s ==
'!' ) {
4772 if ( s[-1] ==
'!' ) {
4773 while ( *s ==
' ' || *s ==
'\t' ) s++;
4775 MesPrint(
"@Negative value in preprocessor factorial: %l",y);
4778 else if ( y == 0 ) y = 1;
4781 while ( z > 0 ) { y = y*z; z--; }
4785 else if ( *s ==
'%' ) {
4787 while ( *s ==
' ' || *s ==
'\t' ) s++;
4790 MesPrint(
"@Illegal value in preprocessor logarithm: %l",z);
4794 while ( z ) { y++; z >>= 1; }
4797 else if ( *s ==
'/' ) {
4800 while ( *s ==
' ' || *s ==
'\t' ) s++;
4803 MesPrint(
"@Illegal value in preprocessor square root: %l",z);
4809 while ( zz ) { yy++; zz >>= 1; }
4810 zz = z >> (yy/2); i = 10; y = 0;
4812 yy = zz/2 + z/(2*zz); i--;
4813 if ( y == yy )
break;
4815 }
while ( y != yy && i > 0 );
4816 while ( y*y < z ) y++;
4817 while ( y*y > z ) y--;
4819 else if ( z >= 4 ) y = 2;
4820 else if ( z == 0 ) y = 0;
4824 while ( *s ==
' ' || *s ==
'\t' ) s++;
4825 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
4826 if ( *s ==
'-' ) expsign = -expsign;
4828 if ( *s <= '9' && *s >=
'0' ) {
4831 else if ( *s ==
'(' || *s ==
'{' ) {
4832 if ( ( t = PreEval(s+1,&z) ) == 0 )
return(0);
4836 while ( *s ==
' ' || *s ==
'\t' ) s++;
4839 if ( tobemultiplied == 0 ) {
4840 if ( expsign < 0 ) a = 1/y;
4844 if ( tobemultiplied > 2 && expsign != 1 ) {
4845 MesPrint(
"&Incorrect use of ^ with & or |. Use brackets!");
4848 tobemultiplied *= expsign;
4849 if ( tobemultiplied == 1 ) a *= y;
4850 else if ( tobemultiplied == 3 ) a &= y;
4851 else if ( tobemultiplied == 4 ) a |= y;
4853 if ( y == 0 || tobemultiplied == -2 ) {
4854 MesPrint(
"@Division by zero in preprocessor calculator");
4857 if ( tobemultiplied == 2 ) a %= y;
4861 if ( *s ==
'%' ) tobemultiplied = 2;
4862 else if ( *s ==
'*' ) tobemultiplied = 1;
4863 else if ( *s ==
'/' ) tobemultiplied = -1;
4864 else if ( *s ==
'&' ) tobemultiplied = 3;
4865 else if ( *s ==
'|' ) tobemultiplied = 4;
4867 if ( tobeadded >= 0 ) *x += a;
4869 if ( *s ==
')' || *s ==
'}' )
return(s+1);
4870 else if ( *s ==
'-' || *s ==
'+' ) { tobeadded = 1;
break; }
4884 void AddToPreTypes(
int type)
4886 if ( AP.NumPreTypes >= AP.MaxPreTypes ) {
4887 int i, *newlist = (
int *)Malloc1(
sizeof(
int)*(2*AP.MaxPreTypes+1)
4888 ,
"preprocessor type lists");
4889 for ( i = 0; i <= AP.MaxPreTypes; i++ ) newlist[i] = AP.PreTypes[i];
4890 M_free(AP.PreTypes,
"preprocessor type lists");
4891 AP.PreTypes = newlist;
4892 AP.MaxPreTypes = 2*AP.MaxPreTypes;
4894 AP.PreTypes[++AP.NumPreTypes] = type;
4902 void MessPreNesting(
int par)
4904 MesPrint(
"@(%d)Illegal nesting of %#if, %#do, %#procedure and/or %#switch",par);
4925 int DoPreAddSeparator(UBYTE *s)
4927 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4928 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4929 for(;*s !=
'\0';s++){
4930 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
4937 set_set(*s,AC.separators);
4950 int DoPreRmSeparator(UBYTE *s)
4952 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4953 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4954 for(;*s !=
'\0';s++){
4955 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
4956 set_del(*s,AC.separators);
4967 int DoExternal(UBYTE *s)
4969 #ifdef WITHEXTERNALCHANNEL 4975 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4976 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4978 #ifdef WITHEXTERNALCHANNEL 4979 while ( *s ==
' ' || *s ==
'\t' ) s++;
4983 if ( chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
4985 MesPrint(
"@Can't finde closing \"");
4987 case 0:
case 1:
continue;
4992 MesPrint(
"@Illegal name of preprocessor variable to store external channel");
4996 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5000 MesPrint(
"@Illegal external command");
5006 externalD=openExternalChannel(
5014 Error1(
"Can't start external program",s);
5021 NumToStr(buf,externalD);
5022 if (
PutPreVar(prevar,buf,0,1) < 0 )
return(-1);
5025 AX.currentExternalChannel=externalD;
5027 if(AX.currentPrompt!=0){
5028 if(setTerminatorForExternalChannel( (
char *)AX.currentPrompt)){
5029 MesPrint(
"@Prompt is too long");
5033 setKillModeForExternalChannel(AX.killSignal,AX.killWholeGroup);
5037 Error0(
"External channel: not implemented on this computer/system");
5048 int DoPrompt(UBYTE *s)
5050 #ifndef WITHEXTERNALCHANNEL 5053 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5054 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5056 #ifdef WITHEXTERNALCHANNEL 5057 while ( *s ==
' ' || *s ==
'\t' ) s++;
5058 if ( AX.currentPrompt )
5059 M_free(AX.currentPrompt,
"external channel prompt");
5061 AX.currentPrompt = (UBYTE *)strDup1((UBYTE *)
"",
"external channel prompt");
5063 AX.currentPrompt = strDup1(s,
"external channel prompt");
5064 if( setTerminatorForExternalChannel( (
char *)AX.currentPrompt) > 0 ){
5065 MesPrint(
"@Prompt is too long");
5071 Error0(
"External channel: not implemented on this computer/system");
5081 int DoSetExternal(UBYTE *s)
5083 #ifdef WITHEXTERNALCHANNEL 5088 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5089 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5091 #ifdef WITHEXTERNALCHANNEL 5092 while ( *s ==
' ' || *s ==
'\t' ) s++;
5093 while ( chartype[*s] == 1 ) { n = 10*n + *s++ -
'0'; }
5094 while ( *s ==
' ' || *s ==
'\t' ) s++;
5096 MesPrint(
"@setexternal: number expected");
5099 if(selectExternalChannel(n)<0){
5100 MesPrint(
"@setexternal: invalid number");
5103 AX.currentExternalChannel=n;
5106 Error0(
"External channel: not implemented on this computer/system");
5115 static FORM_INLINE UBYTE *pickupword(UBYTE *s)
5118 for(;*s>
' ';s++)
switch(*s){
5129 static inline int strINCmp(UBYTE *a, UBYTE *b,
int n)
5131 for(;n>0;n--)
if(tolower(*a++)!=tolower(*b++))
5137 #define KILLALL "killall" 5138 #define DAEMON "daemon" 5139 #define SHELL "shell" 5140 #define STDERR "stderr" 5142 #define TRUE_EXPR "true" 5143 #define FALSE_EXPR "false" 5144 #define NOSHELL "noshell" 5145 #define TERMINAL "terminal" 5150 int DoSetExternalAttr(UBYTE *s)
5152 #ifdef WITHEXTERNALCHANNEL 5158 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5159 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5161 #ifdef WITHEXTERNALCHANNEL 5164 while ( *s ==
' ' || *s ==
'\t' ) s++;
5165 s=pickupword(nam=s);
5167 while ( *s ==
' ' || *s ==
'\t' ) s++;
5169 MesPrint(
"@External channel:'=' expected instead of %s",s-1);
5173 while ( *s ==
' ' || *s ==
'\t' ) s++;
5180 while ( *s ==
' ' || *s ==
'\t' ) s++;
5181 if( (*s ==
',')||(*s ==
'\n')||(*s ==
';')||(*s ==
'\0') ){
5188 while ( *s ==
' ' || *s ==
'\t' ) s++;
5190 if(strINCmp((UBYTE *)SHELL,nam,lnam)==0){
5191 if(AX.shellname!=NULL)
5192 M_free(AX.shellname,
"external channel shellname");
5193 if(strINCmp((UBYTE *)NOSHELL,val,lval)==0)
5197 b=ch=AX.shellname=Malloc1(lval+1,
"external channel shellname");
5202 }
else if(strINCmp((UBYTE *)DAEMON,nam,lnam)==0){
5203 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5205 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5208 MesPrint(
"@External channel:true or false expected for %s",DAEMON);
5211 }
else if(strINCmp((UBYTE *)KILLALL,nam,lnam)==0){
5212 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5213 AX.killWholeGroup = 1;
5214 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5215 AX.killWholeGroup = 0;
5217 MesPrint(
"@External channel: true or false expected for %s",KILLALL);
5220 }
else if(strINCmp((UBYTE *)KILL,nam,lnam)==0){
5223 if( *val>=
'0' && *val<=
'9' )
5224 n = 10*n + *val++ -
'0';
5226 MesPrint(
"@External channel: number expected for %s",KILL);
5230 }
else if(strINCmp((UBYTE *)STDERR,nam,lnam)==0){
5231 if( AX.stderrname != NULL ) {
5232 M_free(AX.stderrname,
"external channel stderrname");
5234 if(strINCmp((UBYTE *)TERMINAL,val,lval)==0)
5235 AX.stderrname = NULL;
5238 b=ch=AX.stderrname=Malloc1(lval+1,
"external channel stderrname");
5245 MesPrint(
"@External channel: unrecognized attribute",nam);
5248 }
while(*s++ ==
',');
5249 if( (*(s-1)>
' ')&&(*(s-1)!=
';') ){
5250 MesPrint(
"@External channel: syntax error: %s",s-1);
5255 Error0(
"External channel: not implemented on this computer/system");
5265 int DoRmExternal(UBYTE *s)
5267 #ifdef WITHEXTERNALCHANNEL 5272 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5273 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5275 #ifdef WITHEXTERNALCHANNEL 5276 while ( *s ==
' ' || *s ==
'\t' ) s++;
5277 if( chartype[*s] == 1 ){
5278 for(n=0; chartype[*s] == 1 ; s++) { n = 10*n + *s -
'0'; }
5279 while ( *s ==
' ' || *s ==
'\t' ) s++;
5282 MesPrint(
"@rmexternal: invalid number");
5287 closeAllExternalChannels();
5288 AX.currentExternalChannel=0;
5292 n=AX.currentExternalChannel;
5295 closeExternalChannel(n);
5297 if (n == AX.currentExternalChannel)
5298 AX.currentExternalChannel=0;
5301 Error0(
"External channel: not implemented on this computer/system");
5329 int DoFromExternal(UBYTE *s)
5331 #ifdef WITHEXTERNALCHANNEL 5337 int withNoList=AC.NoShowInput;
5342 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5343 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5344 #ifdef WITHEXTERNALCHANNEL 5348 while ( *s ==
' ' || *s ==
'\t' ) s++;
5350 if ( *s ==
'-' || *s ==
'+' ) {
5356 while ( *s ==
' ' || *s ==
'\t' ) s++;
5363 if ( *s==
'$' || chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5365 MesPrint(
"@Can't finde closing \"");
5367 case 0:
case 1:
continue;
5372 MesPrint(
"@Illegal name to store output of external channel");
5376 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5380 if( chartype[*s] == 1 ){
5381 for(lbuf=0; chartype[*s] == 1 ; s++) { lbuf = 10*lbuf + *s -
'0'; }
5382 while ( *s ==
' ' || *s ==
'\t' ) s++;
5384 if( (*s!=
'\0')||(lbuf<0) ){
5385 MesPrint(
"@Illegal buffer length in fromexternal");
5390 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5393 if(selectExternalChannel(AX.currentExternalChannel)){
5394 MesPrint(
"@No current external channel");
5405 buf=Malloc1( (lbuf=255)+1,
"Fromexternal");
5411 for(i=0;(cc=getcFromExtChannel())>0;i++){
5415 UBYTE *tmp=Malloc1( (lbuf*=2)+1,
"Fromexternal");
5416 for(j=0;j<i;j++)tmp[j]=buf[j];
5417 M_free(buf,
"Fromexternal");
5424 MesPrint(
"@No current external channel");
5432 buf=Malloc1(lbuf+1,
"Fromexternal");
5433 for(i=0; i<lbuf;i++){
5439 if( (cc=getcFromExtChannel())<1 )
5452 while(getcFromExtChannel()>0);
5454 MesPrint(
"@No current external channel");
5461 int oldNumPotModdollars = NumPotModdollars;
5463 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
5464 AC.RhsExprInModuleFlag = 0;
5468 UBYTE *pbuf=Malloc1(StrLen(prevar)+1+lbuf+1,
"Fromexternal to dollar");
5471 while(*b!=
'\0'){*c++ = *b++;}
5474 while( (*c++=*b++)!=
'\0' );
5475 AP.PreAssignFlag = 1;
5476 if ( ( cc = CompileStatement(pbuf) ) || ( cc = CatchDollar(0) ) ) {
5477 Error1(
"External channel: can't asign output to dollar variable ",prevar);
5479 AP.PreAssignFlag = 0;
5480 NumPotModdollars = oldNumPotModdollars;
5482 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
5484 M_free(pbuf,
"Fromexternal to dollar");
5489 M_free(buf,
"Fromexternal");
5490 if ( cc )
return(-1);
5494 if ( OpenStream(s,EXTERNALCHANNELSTREAM,0,PRENOACTION) == 0 )
return(-1);
5496 AC.NoShowInput = withNoList;
5500 Error0(
"External channel: not implemented on this computer/system");
5511 #ifdef WITHEXTERNALCHANNEL 5514 LONG WriteToExternalChannel(
int handle, UBYTE *buffer, LONG size)
5519 if(writeBufToExtChannel((
char*)buffer,size))
5525 int DoToExternal(UBYTE *s)
5527 #ifdef WITHEXTERNALCHANNEL 5529 LONG (*OldWrite)(
int handle, UBYTE *buffer, LONG size) = WriteFile;
5534 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5535 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5536 #ifdef WITHEXTERNALCHANNEL 5538 h.oldsilent=AM.silent;
5539 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
5540 h.newhandle = h.oldhandle = AC.LogHandle;
5541 h.oldprinttype = AO.PrintType;
5543 WriteFile=&WriteToExternalChannel;
5545 while ( *s ==
' ' || *s ==
'\t' ) s++;
5547 if(AX.currentExternalChannel==0){
5548 MesPrint(
"@No current external channel");
5549 goto DoToExternalReady;
5552 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5553 selectExternalChannel(AX.currentExternalChannel);
5555 ret=writeToChannel(EXTERNALCHANNELOUT,s,&h);
5560 Error0(
"External channel: not implemented on this computer/system");
5571 UBYTE *defineChannel(UBYTE *s,
HANDLERS *h)
5580 while ( *s && *s !=
'>' ) {
5581 if ( *s ==
'\\' ) s++;
5585 MesPrint(
"@Improper termination of filename");
5591 h->newhandle = GetChannel((
char *)name);
5594 else if ( AC.LogHandle >= 0 ) {
5595 h->newhandle = AC.LogHandle;
5606 int writeToChannel(
int wtype, UBYTE *s,
HANDLERS *h)
5608 UBYTE *to, *fstring, *ss, *sss, *s1, c, c1;
5609 WORD num, number, nfac;
5610 UBYTE Out[MAXLINELENGTH+14], *stopper;
5616 while ( *s ==
',' || *s ==
' ' ) s++;
5618 MesPrint(
"@No format string present");
5621 s++; fstring = to = s;
5627 if ( *s ==
'\\' ) *to++ = *s++;
5629 else if ( *s ==
'"' ) *to++ = *s++;
5630 else { *to++ =
'\\'; *to++ = *s++; }
5632 else if ( *s ==
'"' )
break;
5636 MesPrint(
"@No closing \" in format string");
5640 if ( AC.LineLength > 20 && AC.LineLength <= MAXLINELENGTH ) stopper = Out + AC.LineLength;
5641 else stopper = Out + MAXLINELENGTH;
5648 AC.LogHandle = h->newhandle;
5649 AM.FileOnlyFlag = h->newlogonly;
5650 if ( h->newhandle >= 0 ) {
5651 AO.PrintType |= PRINTLFILE;
5653 while ( *fstring ) {
5654 if ( to >= stopper ) {
5656 WriteString(wtype,Out,num);
5659 if ( *fstring ==
'\\' ) {
5661 if ( *fstring ==
'n' ) {
5663 WriteString(wtype,Out,num);
5667 else if ( *fstring ==
't' ) { *to++ =
'\t'; fstring++; }
5668 else if ( *fstring ==
'b' ) { *to++ =
'\\'; fstring++; }
5669 else *to++ = *fstring++;
5671 else if ( *fstring ==
'%' ) {
5673 if ( *fstring ==
'$' ) {
5676 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
5677 number = AO.OutSkip;
5679 nodollar: MesPrint(
"@$-variable expected in #write instruction");
5680 AM.FileOnlyFlag = h->oldlogonly;
5681 AC.LogHandle = h->oldhandle;
5682 AO.PrintType = h->oldprinttype;
5683 AM.silent = h->oldsilent;
5687 while ( chartype[*s] <= 1 ) s++;
5688 if ( s == ss )
goto nodollar;
5690 num = GetDollar(ss);
5692 MesPrint(
"@#write instruction: $%s has not been defined",ss);
5693 AM.FileOnlyFlag = h->oldlogonly;
5694 AC.LogHandle = h->oldhandle;
5695 AO.PrintType = h->oldprinttype;
5696 AM.silent = h->oldsilent;
5701 if ( Dollars[num].nfactors <= 0 ) {
5703 MesPrint(
"@#write instruction: $%s has not been factorized",ss);
5704 AM.FileOnlyFlag = h->oldlogonly;
5705 AC.LogHandle = h->oldhandle;
5706 AO.PrintType = h->oldprinttype;
5707 AM.silent = h->oldsilent;
5713 nfac = GetDollarNumber(&s,Dollars+num);
5715 if ( Dollars[num].nfactors == 1 && nfac == 1 )
goto writewhole;
5717 if ( ( dolalloc = WriteDollarFactorToBuffer(num,nfac,0) ) == 0 ) {
5718 AM.FileOnlyFlag = h->oldlogonly;
5719 AC.LogHandle = h->oldhandle;
5720 AO.PrintType = h->oldprinttype;
5721 AM.silent = h->oldsilent;
5726 else if ( *s && *s !=
' ' && *s !=
',' && *s !=
'\t' ) {
5727 MesPrint(
"@#write instruction: illegal characters after $-variable");
5728 AM.FileOnlyFlag = h->oldlogonly;
5729 AC.LogHandle = h->oldhandle;
5730 AO.PrintType = h->oldprinttype;
5731 AM.silent = h->oldsilent;
5736 if ( ( dolalloc = WriteDollarToBuffer(num,0) ) == 0 ) {
5737 AM.FileOnlyFlag = h->oldlogonly;
5738 AC.LogHandle = h->oldhandle;
5739 AO.PrintType = h->oldprinttype;
5740 AM.silent = h->oldsilent;
5747 if ( to >= stopper ) {
5749 WriteString(wtype,Out,num);
5751 for ( i = 0; i < number; i++ ) *to++ =
' ';
5753 if ( chartype[*ss] > 3 ) { *to++ = *ss++; }
5755 sss = ss;
while ( chartype[*ss] <= 3 ) ss++;
5756 if ( ( to + (ss-sss) ) >= stopper ) {
5757 if ( (ss-sss) >= (stopper-Out) ) {
5758 if ( ( to - stopper ) < 10 ) {
5760 WriteString(wtype,Out,num);
5762 for ( i = 0; i < number; i++ ) *to++ =
' ';
5764 while ( (ss-sss) >= (stopper-Out) ) {
5765 while ( to < stopper-1 ) {
5770 WriteString(wtype,Out,num);
5772 for ( i = 0; i < number; i++ ) *to++ =
' ';
5777 WriteString(wtype,Out,num);
5779 for ( i = 0; i < number; i++ ) *to++ =
' ';
5782 while ( sss < ss ) *to++ = *sss++;
5786 M_free(dolalloc,
"written dollar");
5790 else if ( *fstring ==
's' ) {
5792 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
5796 if ( *s ==
'\\' ) s++;
5797 else if ( *s ==
'"' )
break;
5801 MesPrint(
"@#write instruction: Missing \" in string");
5802 AM.FileOnlyFlag = h->oldlogonly;
5803 AC.LogHandle = h->oldhandle;
5804 AO.PrintType = h->oldprinttype;
5805 AM.silent = h->oldsilent;
5809 if ( to >= stopper ) {
5811 WriteString(wtype,Out,num);
5814 if ( *ss ==
'\\' ) ss++;
5821 while ( *s && *s !=
',' ) {
5822 if ( *s ==
'\\' ) { s++; sss = s+1; }
5825 while ( s > sss+1 && ( s[-1] ==
' ' || s[-1] ==
'\t' ) ) s--;
5827 if ( to >= stopper ) {
5829 WriteString(wtype,Out,num);
5832 if ( *ss ==
'\\' ) ss++;
5837 else if ( *fstring ==
'X' ) {
5839 if ( cbuf[AM.sbufnum].numrhs > 0 ) {
5843 UBYTE *s = GetPreVar(AM.oldnumextrasymbols,0);
5845 while ( *s >=
'0' && *s <=
'9' ) x = 10*x + *s++ -
'0';
5847 PrintSubtermList(1,x);
5849 PrintSubtermList(1,cbuf[AM.sbufnum].numrhs);
5852 else if ( *fstring ==
'O' ) {
5853 number = AO.OutSkip;
5859 if ( AO.OptimizeResult.code == NULL && AO.OptimizationLevel != 0 ) {
5860 MesPrint(
"@In #write instruction: no optimization results available!");
5864 WriteString(wtype,Out,num);
5866 if ( AO.OptimizationLevel != 0 ) {
5867 WORD oldoutskip = AO.OutSkip;
5868 AO.OutSkip = number;
5869 optimize_print_code(0);
5870 AO.OutSkip = oldoutskip;
5873 else if ( *fstring ==
'e' || *fstring ==
'E' ) {
5874 if ( *fstring ==
'E' ) nosemi = 1;
5877 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
5878 if ( chartype[*s] != 0 && *s !=
'[' ) {
5879 noexpr: MesPrint(
"@expression name expected in #write instruction");
5880 AM.FileOnlyFlag = h->oldlogonly;
5881 AC.LogHandle = h->oldhandle;
5882 AO.PrintType = h->oldprinttype;
5883 AM.silent = h->oldsilent;
5887 if ( ( s = SkipAName(ss) ) == 0 || s[-1] ==
'_' )
goto noexpr;
5888 s1 = s; c = c1 = *s1;
5892 AO.CurBufWrt = s1+1;
5896 MesPrint(
"@Illegal () specifier in expression name in #write");
5897 AM.FileOnlyFlag = h->oldlogonly;
5898 AC.LogHandle = h->oldhandle;
5899 AO.PrintType = h->oldprinttype;
5900 AM.silent = h->oldsilent;
5904 else AO.CurBufWrt = (UBYTE *)underscore;
5907 if ( num > 0 ) WriteUnfinString(wtype,Out,num);
5909 WORD oldOptimizationLevel = AO.OptimizationLevel;
5910 AO.OptimizationLevel = 0;
5911 if ( WriteOne(ss,(
int)num,nosemi) < 0 ) {
5912 AM.FileOnlyFlag = h->oldlogonly;
5913 AC.LogHandle = h->oldhandle;
5914 AO.PrintType = h->oldprinttype;
5915 AM.silent = h->oldsilent;
5918 AO.OptimizationLevel = oldOptimizationLevel;
5920 if ( s > s1 ) *s++ = c;
5925 else if ( ( *fstring ==
'f' ) || ( *fstring ==
'F' ) ) {
5927 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
5929 while ( *s && *s !=
',' ) {
5930 if ( *s ==
'\\' ) s++;
5934 s1 = LoadInputFile(ss,HEADERFILE);
5941 ss = s1;
while ( *ss ) ss++;
5943 WriteString(wtype,s1,n);
5944 M_free(s1,
"copy file");
5946 else if ( *fstring ==
'F' ) {
5948 MesPrint(
"@Error in #write: could not open file %s",ss);
5950 goto ReturnWithError;
5954 else if ( *fstring ==
'%' ) {
5957 else if ( FG.cTable[*fstring] == 1 ) {
5959 while ( FG.cTable[*fstring] == 1 ) {
5960 number = 10*number + *fstring++ -
'0';
5962 if ( *fstring ==
'O' )
goto dooptim;
5963 else if ( *fstring ==
'$' )
goto dodollar;
5964 else if ( *fstring ==
'X' || *fstring ==
'x' ) {
5965 if ( number > 0 && number <= cbuf[AM.sbufnum].numrhs ) {
5966 UBYTE buffer[80], *out, *old1, *old2, *old3;
5968 if ( *fstring ==
'X' ) {
5969 out = StrCopy((UBYTE *)AC.extrasym,buffer);
5970 if ( AC.extrasymbols == 0 ) {
5971 out = NumCopy(number,out);
5972 out = StrCopy((UBYTE *)
"_",out);
5974 else if ( AC.extrasymbols == 1 ) {
5975 if ( AC.OutputMode == CMODE ) {
5976 out = StrCopy((UBYTE *)
"[",out);
5977 out = NumCopy(number,out);
5978 out = StrCopy((UBYTE *)
"]",out);
5981 out = StrCopy((UBYTE *)
"(",out);
5982 out = NumCopy(number,out);
5983 out = StrCopy((UBYTE *)
")",out);
5986 out = StrCopy((UBYTE *)
"=",out);
5988 while ( ss < out ) {
5989 if ( to >= stopper ) {
5991 WriteString(wtype,Out,num);
5997 term = cbuf[AM.sbufnum].rhs[number];
6004 old2 = AO.OutputLine;
6007 AO.OutputLine = Out;
6008 AO.OutStop = Out + AC.LineLength;
6010 if ( WriteInnerTerm(term,first) ) Terminate(-1);
6014 to = Out + (AO.OutFill-AO.OutputLine);
6016 AO.OutputLine = old2;
6023 goto IllegControlSequence;
6026 else if ( *fstring == 0 ) {
6030 IllegControlSequence:
6031 MesPrint(
"@Illegal control sequence in format string in #write instruction");
6033 AM.FileOnlyFlag = h->oldlogonly;
6034 AC.LogHandle = h->oldhandle;
6035 AO.PrintType = h->oldprinttype;
6036 AM.silent = h->oldsilent;
6049 if(wtype==EXTERNALCHANNELOUT){
6051 WriteUnfinString(wtype,Out,num);
6054 WriteString(wtype,Out,num);
6058 AM.FileOnlyFlag = h->oldlogonly;
6059 AC.LogHandle = h->oldhandle;
6060 AO.PrintType = h->oldprinttype;
6061 AM.silent = h->oldsilent;
6073 int DoFactDollar(UBYTE *s)
6076 WORD numdollar, *oldworkpointer;
6078 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6079 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6080 while ( *s ==
' ' || *s ==
'\t' ) s++;
6082 if ( GetName(AC.dollarnames,s+1,&numdollar,NOAUTO) != CDOLLAR ) {
6083 MesPrint(
"@%s is undefined",s);
6088 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6092 oldworkpointer = AT.WorkPointer;
6094 AT.WorkPointer = oldworkpointer;
6098 else if ( ParenthesesTest(s) )
return(-1);
6100 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6110 WORD GetDollarNumber(UBYTE **inp,
DOLLARS d)
6112 UBYTE *s = *inp, c, *name;
6113 WORD number, nfac, *w;
6118 while ( FG.cTable[*s] < 2 ) s++;
6120 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6121 MesPrint(
"@dollar in #write should have been defined previously");
6125 dd = Dollars + number;
6128 nfac = GetDollarNumber(inp,dd);
6131 MesPrint(
"@Illegal factor for dollar variable");
6136 if ( dd->nfactors > d->nfactors ) {
6138 MesPrint(
"@Factor number for dollar variable too large");
6141 return(dd->nfactors);
6143 w = dd->factors[nfac-1].where;
6145 if ( dd->factors[nfac-1].value > d->nfactors ||
6146 dd->factors[nfac-1].value < 0 )
goto TooBig;
6147 return(dd->factors[nfac-1].value);
6149 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6150 && w[1] <= d->nfactors )
return(w[1]);
6151 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6153 MesPrint(
"@Illegal factor number for dollar variable");
6157 if ( dd->type == DOLZERO ) {
6160 else if ( dd->type == DOLTERMS || dd->type == DOLNUMBER ) {
6162 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6163 && w[1] <= d->nfactors )
return(w[1]);
6164 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6170 else if ( FG.cTable[*s] == 1 ) {
6171 WORD x = *s++ -
'0';
6172 while ( FG.cTable[*s] == 1 ) {
6173 x = 10*x + *s++ -
'0';
6174 if ( x > d->nfactors ) {
6175 MesPrint(
"@Factor number %d for dollar variable too large",x);
6180 MesPrint(
"@Illegal factor number for dollar variable");
6187 MesPrint(
"@Illegal factor indicator for dollar variable");
6200 int DoSetRandom(UBYTE *s)
6203 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6204 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6205 while ( *s ==
' ' || *s ==
'\t' ) s++;
6207 while ( FG.cTable[*s] == 1 ) {
6208 x = 10*x + (*s++-
'0');
6210 while ( *s ==
' ' || *s ==
'\t' ) s++;
6214 int id, totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
6216 int id, totnum = AM.totalnumberofthreads;
6218 for (
id = 0;
id < totnum;
id++ ) {
6219 AB[id]->R.wranfseed = x;
6220 if ( AB[
id]->R.wranfia ) M_free(AB[
id]->R.wranfia,
"wranf");
6221 AB[id]->R.wranfia = 0;
6225 if ( AR.wranfia ) M_free(AR.wranfia,
"wranf");
6231 MesPrint(
"@proper syntax is #SetRandom number");
6243 int DoOptimize(UBYTE *s)
6249 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6250 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6252 exprname = s; s = SkipAName(s);
6253 if ( *s != 0 && *s !=
';' ) {
6254 MesPrint(
"@proper syntax is #Optimize,expression");
6258 if ( GetName(AC.exprnames,exprname,&numexpr,NOAUTO) != CEXPRESSION ) {
6259 MesPrint(
"@%s is not an expression",exprname);
6266 WORD *term = AT.WorkPointer;
6268 if ( AO.OptimizationLevel == 0 )
return(0);
6269 switch ( e->status ) {
6270 case LOCALEXPRESSION:
6271 case GLOBALEXPRESSION:
6274 MesPrint(
"@Expression %s is not an active unhidden local or global expression.",exprname);
6279 if ( PF.me == MASTER )
6282 for ( i = NumExpressions-1; i >= 0; i-- ) {
6283 AS.OldOnFile[i] = Expressions[i].onfile;
6284 AS.OldNumFactors[i] = Expressions[i].numfactors;
6285 AS.Oldvflags[i] = Expressions[i].vflags;
6286 Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
6288 for ( i = 0; i < NumExpressions; i++ ) {
6289 if ( i == numexpr ) {
6291 GetPreVar((UBYTE *)
"EXTRASYMBOLS_",0),0,1);
6292 Optimize(numexpr, 0);
6293 AO.OptimizeResult.nameofexpr = strDup1(exprname,
"optimize expression name");
6297 if ( PF.me == MASTER ) {
6299 e = Expressions + i;
6300 switch ( e->status ) {
6301 case LOCALEXPRESSION:
6302 case SKIPLEXPRESSION:
6303 case DROPLEXPRESSION:
6304 case DROPPEDEXPRESSION:
6305 case GLOBALEXPRESSION:
6306 case SKIPGEXPRESSION:
6307 case DROPGEXPRESSION:
6308 case HIDELEXPRESSION:
6309 case HIDEGEXPRESSION:
6310 case DROPHLEXPRESSION:
6311 case DROPHGEXPRESSION:
6312 case INTOHIDELEXPRESSION:
6313 case INTOHIDEGEXPRESSION:
6319 SetScratch(AR.infile,&(e->onfile));
6320 if ( GetTerm(BHEAD term) <= 0 ) {
6321 MesPrint(
"@Expression %d has problems reading from scratchfile",i);
6326 SeekScratch(AR.outfile,&position);
6327 e->onfile = position;
6328 *AM.S0->sBuffer = 0; firstterm = -1;
6330 WORD *oldipointer = AR.CompressPointer;
6331 WORD *comprtop = AR.ComprTop;
6332 AR.ComprTop = AM.S0->sTop;
6333 AR.CompressPointer = AM.S0->sBuffer;
6334 if ( firstterm > 0 ) {
6335 if (
PutOut(BHEAD term,&position,AR.outfile,1) < 0 )
goto DoSerr;
6337 else if ( firstterm < 0 ) {
6338 if (
PutOut(BHEAD term,&position,AR.outfile,0) < 0 )
goto DoSerr;
6342 if (
PutOut(BHEAD term,&position,AR.outfile,-1) < 0 )
goto DoSerr;
6345 AR.CompressPointer = oldipointer;
6346 AR.ComprTop = comprtop;
6347 }
while ( GetTerm(BHEAD term) );
6348 if (
FlushOut(&position,AR.outfile,1) ) {
6350 MesPrint(
"@Expression %d has problems writing to scratchfile",i);
6373 int DoClearOptimize(UBYTE *s)
6375 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6376 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6378 return(ClearOptimize());
void AddPotModdollar(WORD)
int TheDefine(UBYTE *s, int mode)
int DoRecovery(int *moduletype)
int DollarFactorize(PHEAD WORD)
int PF_BroadcastRedefinedPreVars(void)
int PutPreVar(UBYTE *name, UBYTE *value, UBYTE *args, int mode)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
WORD Generator(PHEAD WORD *, WORD)
WORD FlushOut(POSITION *, FILEHANDLE *, int)
int PF_BroadcastModifiedDollars(void)
LONG EndSort(PHEAD WORD *, int)
void DoCheckpoint(int moduletype)