36 static UBYTE pushbackchar = 0;
37 static int oldmode = 0;
38 static int stopdelay = 0;
39 static STREAM *oldstream = 0;
40 static UBYTE underscore[2] = {
'_',0};
41 static PREVAR *ThePreVar = 0;
43 static KEYWORD precommands[] = {
44 {
"add" , DoPreAdd , 0, 0}
45 ,{
"addseparator" , DoPreAddSeparator,0,0}
46 ,{
"append" , DoPreAppend , 0, 0}
48 ,{
"assign" , DoPreAssign , 0, 0}
49 ,{
"break" , DoPreBreak , 0, 0}
50 ,{
"breakdo" , DoBreakDo , 0, 0}
51 ,{
"call" , DoCall , 0, 0}
52 ,{
"case" , DoPreCase , 0, 0}
53 ,{
"clearoptimize", DoClearOptimize, 0, 0}
54 ,{
"close" , DoPreClose , 0, 0}
55 ,{
"closedictionary", DoPreCloseDictionary,0,0}
56 ,{
"commentchar" , DoCommentChar , 0, 0}
57 ,{
"create" , DoPreCreate , 0, 0}
58 ,{
"debug" , DoDebug , 0, 0}
59 ,{
"default" , DoPreDefault , 0, 0}
60 ,{
"define" , DoDefine , 0, 0}
62 ,{
"else" , DoElse , 0, 0}
63 ,{
"elseif" , DoElseif , 0, 0}
64 ,{
"enddo" , DoEnddo , 0, 0}
65 ,{
"endif" , DoEndif , 0, 0}
66 ,{
"endinside" , DoEndInside , 0, 0}
67 ,{
"endprocedure" , DoEndprocedure , 0, 0}
68 ,{
"endswitch" , DoPreEndSwitch , 0, 0}
69 ,{
"exchange" , DoPreExchange , 0, 0}
70 ,{
"external" , DoExternal , 0, 0}
71 ,{
"factdollar" , DoFactDollar , 0, 0}
72 ,{
"fromexternal" , DoFromExternal , 0, 0}
74 ,{
"ifdef" , (TFUN)DoIfdef , 1, 0}
75 ,{
"ifndef" , (TFUN)DoIfdef , 2, 0}
76 ,{
"include" , DoInclude , 0, 0}
77 ,{
"inside" , DoInside , 0, 0}
78 ,{
"message" , DoMessage , 0, 0}
79 ,{
"opendictionary", DoPreOpenDictionary,0,0}
80 ,{
"optimize" , DoOptimize , 0, 0}
81 ,{
"pipe" , DoPipe , 0, 0}
82 ,{
"preout" , DoPreOut , 0, 0}
84 ,{
"printtimes" , DoPrePrintTimes, 0, 0}
85 ,{
"procedure" , DoProcedure , 0, 0}
86 ,{
"procedureextension" , DoPrcExtension , 0, 0}
87 ,{
"prompt" , DoPrompt , 0, 0}
88 ,{
"redefine" , DoRedefine , 0, 0}
89 ,{
"remove" , DoPreRemove , 0, 0}
90 ,{
"reset" , DoPreReset , 0, 0}
91 ,{
"reverseinclude" , DoReverseInclude , 0, 0}
92 ,{
"rmexternal" , DoRmExternal , 0, 0}
93 ,{
"rmseparator" , DoPreRmSeparator,0, 0}
94 ,{
"setexternal" , DoSetExternal , 0, 0}
95 ,{
"setexternalattr" , DoSetExternalAttr , 0, 0}
96 ,{
"setrandom" , DoSetRandom , 0, 0}
97 ,{
"show" , DoPreShow , 0, 0}
98 ,{
"skipextrasymbols" , DoSkipExtraSymbols , 0, 0}
99 ,{
"switch" , DoPreSwitch , 0, 0}
100 ,{
"system" , DoSystem , 0, 0}
101 ,{
"terminate" , DoTerminate , 0, 0}
102 ,{
"toexternal" , DoToExternal , 0, 0}
103 ,{
"undefine" , DoUndefine , 0, 0}
104 ,{
"usedictionary", DoPreUseDictionary,0,0}
105 ,{
"write" , DoPreWrite , 0, 0}
121 while ( AC.CurrentStream ) {
122 c = GetFromStream(AC.CurrentStream);
123 if ( c != ENDOFSTREAM ) {
126 && AC.NoShowInput <= 0
127 && AC.CurrentStream->type != PREVARSTREAM )
129 if ( AC.NoShowInput <= 0 && AC.CurrentStream->type != PREVARSTREAM )
134 AC.CurrentStream = CloseStream(AC.CurrentStream);
135 if ( stopdelay && AC.CurrentStream == oldstream ) {
136 stopdelay = 0; AP.AllowDelay = 1;
165 UBYTE GetChar(
int level)
167 UBYTE namebuf[MAXPRENAMESIZE+2], c, *s, *t;
168 static UBYTE lastchar, charinbuf = 0;
169 int i, j, raiselow, olddelay;
175 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0;
return(c); }
176 if ( charinbuf ) { c = charinbuf; charinbuf = 0;
return(c); }
180 charinbuf = GetInput();
181 if ( charinbuf != LINEFEED ) {
182 pushbackchar = charinbuf;
187 while ( ( c = GetInput() ) ==
' ' || c ==
'\t' ) {}
189 else if ( c ==
'\'' || c ==
'`' ) {
190 if ( AP.DelayPrevar == 1 && c ==
'\'' ) {
197 if ( c ==
'!' && lastchar ==
'`' ) {
198 if ( stopdelay == 0 ) oldstream = AC.CurrentStream;
203 if ( c ==
'~' && lastchar ==
'`' ) {
204 if ( AP.AllowDelay ) {
214 olddelay = AP.DelayPrevar;
218 if ( pushbackchar ) { c = pushbackchar; pushbackchar = 0; }
219 else { c = GetInput(); }
220 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
221 && lastchar !=
'\\' ) ) {
225 if ( PreCalc() == 0 ) Terminate(-1);
228 MesPrint(
"@Illegal set inside preprocessor variable name");
232 if ( c ==
'`' && lastchar !=
'\\' ) {
234 if ( c == ENDOFINPUT || ( ( c ==
'\'' || c == LINEFEED )
235 && lastchar !=
'\\' ) ) {
239 if ( lastchar ==
'\\' ) { i--; lastchar = 0; }
242 if ( i > MAXPRENAMESIZE ) {
244 Error1(
"Preprocessor variable name too long: ",namebuf);
249 Error1(
"Unmatched quotes for preprocessor variable",namebuf);
251 AP.DelayPrevar = olddelay;
252 if ( namebuf[0] ==
'$' ) {
253 raiselow = PRENOACTION;
254 if ( AP.PreproFlag && *AP.preStart) {
255 s = EndOfToken(AP.preStart);
257 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
258 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
259 && GetDollar(namebuf+1) < 0 ) {
266 s = EndOfToken(namebuf+1);
267 if ( *s ==
'[' ) {
while ( *s ) s++; }
269 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
270 raiselow = PRELOWERAFTER;
271 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
272 raiselow = PRERAISEAFTER;
274 if ( OpenStream(namebuf+1,DOLLARSTREAM,0,raiselow) == 0 ) {
276 MesPrint(
"@Undefined variable %s used as preprocessor variable",
283 raiselow = PRENOACTION;
284 if ( AP.PreproFlag && *AP.preStart) {
285 s = EndOfToken(AP.preStart);
287 if ( ( StrICmp(AP.preStart,(UBYTE *)
"ifdef") == 0
288 || StrICmp(AP.preStart,(UBYTE *)
"ifndef") == 0 )
289 && GetPreVar(namebuf,WITHOUTERROR) == 0 ) {
295 s = EndOfToken(namebuf);
296 if ( *s ==
'_' ) s++;
297 if ( *s ==
'-' && s[1] ==
'-' && s[2] == 0 )
298 raiselow = PRELOWERAFTER;
299 else if ( *s ==
'+' && s[1] ==
'+' && s[2] == 0 )
300 raiselow = PRERAISEAFTER;
301 else if ( *s ==
'(' && namebuf[i-2] ==
')' ) {
312 *s++ = 0; namebuf[i-2] = 0;
313 if ( StrICmp(namebuf,(UBYTE *)
"random_") == 0 ) {
315 ranvalue = PreRandom(s);
316 PutPreVar(namebuf,ranvalue,(UBYTE *)
"?a",1);
317 M_free(ranvalue,
"PreRandom");
320 else if ( StrICmp(namebuf,(UBYTE *)
"tolower_") == 0 ) {
322 while ( *ss ) { *ss = (UBYTE)(tolower(*ss)); ss++; }
326 else if ( StrICmp(namebuf,(UBYTE *)
"toupper_") == 0 ) {
328 while ( *ss ) { *ss = (UBYTE)(toupper(*ss)); ss++; }
333 if ( *s ==
'\\' ) s++;
334 if ( *s ==
',' ) { *s = 0; nargs++; }
337 GetPreVar(namebuf,WITHERROR);
340 MesPrint(
"@Illegal use of arguments in preprocessor variable %s",namebuf);
344 || ( p->
wildarg > 0 && nargs < p->nargs-1 ) ) {
345 MesPrint(
"@Arguments of macro %s do not match",namebuf);
353 for ( j = 0; j < p->
wildarg; j++ ) {
357 for ( j = 0; j < nargs-p->
nargs; j++ ) {
366 while ( *s ) s++; s++;
368 for ( j = 0; j < p->
nargs; j++ ) {
369 if ( ( nargs == p->
nargs-1 ) && ( *t ==
'?' ) ) {
374 while ( *s ) s++; s++;
376 while ( *t ) t++; t++;
380 if ( ( stream = OpenStream(namebuf,PREVARSTREAM,0,raiselow) ) == 0 ) {
385 else if ( stream->inbuffer == 0 ) {
387 if ( level > 0 && c ==
'\'' )
return(c);
393 else if ( c ==
'{' ) {
394 if ( PreCalc() == 0 ) Terminate(-1);
409 VOID CharOut(UBYTE c)
411 if ( c == LINEFEED ) {
412 AM.OutBuffer[AP.InOutBuf++] = c;
413 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
417 if ( AP.InOutBuf >= AM.OutBufSize || c == LINEFEED ) {
418 WriteString(INPUTOUT,AM.OutBuffer,AP.InOutBuf);
421 AM.OutBuffer[AP.InOutBuf++] = c;
430 VOID UnsetAllowDelay()
432 if ( ThePreVar != 0 ) {
433 if ( ThePreVar->
nargs > 0 ) AP.AllowDelay = 0;
450 static UBYTE *yes = (UBYTE *)
"1";
451 static UBYTE *no = (UBYTE *)
"0";
452 static UBYTE numintopolynomial[12];
454 static Vector(UBYTE, exprstr);
456 UBYTE *GetPreVar(UBYTE *name,
int flag)
461 UBYTE *t, c = 0, *tt = 0;
462 t = name;
while ( *t ) t++;
463 if ( t[-1] ==
'-' && t[-2] ==
'-' && t-2 > name && t[-3] !=
'_' ) {
464 t -= 2; c = *t; *t = 0; tt = t;
466 else if ( t[-1] ==
'+' && t[-2] ==
'+' && t-2 > name && t[-3] !=
'_' ) {
467 t -= 2; c = *t; *t = 0; tt = t;
469 else if ( StrICmp(name,(UBYTE *)
"time_") == 0 ) {
471 LONG millitime, timepart;
472 int timepart1, timepart2;
473 static char timestring[40];
475 millitime = GetRunningTime();
476 timepart = millitime%1000;
479 timepart1 = timepart / 10;
480 timepart2 = timepart % 10;
481 NumToStr(millibuf,millitime);
482 sprintf(timestring,
"%s.%1d%1d",millibuf,timepart1,timepart2);
483 return((UBYTE *)timestring);
485 else if ( ( StrICmp(name,(UBYTE *)
"timer_") == 0 )
486 || ( StrICmp(name,(UBYTE *)
"stopwatch_") == 0 ) ) {
487 static char timestring[40];
488 sprintf(timestring,
"%ld",(GetRunningTime() - AP.StopWatchZero));
489 return((UBYTE *)timestring);
491 else if ( StrICmp(name, (UBYTE *)
"numactiveexprs_") == 0 ) {
494 for ( i = 0; i < NumExpressions; i++ ) {
496 switch ( e->status ) {
497 case LOCALEXPRESSION:
498 case GLOBALEXPRESSION:
499 case UNHIDELEXPRESSION:
500 case UNHIDEGEXPRESSION:
501 case INTOHIDELEXPRESSION:
502 case INTOHIDEGEXPRESSION:
511 else if ( StrICmp(name, (UBYTE *)
"activeexprnames_") == 0 ) {
515 for ( i = 0; i < NumExpressions; i++ ) {
519 switch ( e->status ) {
520 case LOCALEXPRESSION:
521 case GLOBALEXPRESSION:
522 case UNHIDELEXPRESSION:
523 case UNHIDEGEXPRESSION:
524 case INTOHIDELEXPRESSION:
525 case INTOHIDEGEXPRESSION:
526 s = AC.exprnames->namebuffer + e->name;
531 if ( j > 0 ) p[j++] =
',';
532 for ( k = 0; k < len; k++ ) {
533 if ( s[k] ==
',' || s[k] ==
'|' ) p[j++] =
'\\';
542 else if ( StrICmp(name, (UBYTE *)
"path_") == 0 ) {
552 while ( *t && *t !=
'_' ) t++;
553 for ( i = NumPre-1; i >= 0; i-- ) {
554 if ( *t ==
'_' && ( StrICmp(name,PreVar[i].name) == 0 ) ) {
556 ThePreVar = PreVar+i;
557 return(PreVar[i].value);
559 else if ( StrCmp(name,PreVar[i].name) == 0 ) {
561 ThePreVar = PreVar+i;
562 return(PreVar[i].value);
566 if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS_") == 0 )
goto extrashort;
568 if ( StrICmp(name,(UBYTE *)
"UNCHANGED") == 0 ) mode = 1;
569 else if ( StrICmp(name,(UBYTE *)
"ZERO") == 0 ) mode = 0;
570 else if ( StrICmp(name,(UBYTE *)
"SHOWINPUT") == 0 ) {
573 if ( AC.NoShowInput > 0 )
return(no);
576 else if ( StrICmp(name,(UBYTE *)
"EXTRASYMBOLS") == 0 ) {
579 number = cbuf[AM.sbufnum].numrhs;
580 t = numintopolynomial;
582 return(numintopolynomial);
589 if ( GetName(AC.exprnames,t,&number,NOAUTO) == CEXPRESSION ) {
591 if ( ( Expressions[number].vflags & ( 1 << mode ) ) != 0 )
602 if ( ( AR.expflags & ( 1 << mode ) ) == 0 )
return(yes);
607 if ( ( t = (UBYTE *)(getenv((
char *)(name))) ) != 0 ) {
613 if ( flag == WITHERROR ) {
614 Error1(
"Undefined preprocessor variable",name);
638 int PutPreVar(UBYTE *name, UBYTE *value, UBYTE *args,
int mode)
640 int i, ii, num = 2, nnum = 2, numargs = 0;
641 UBYTE *s, *t, *u = 0;
643 if ( value == 0 && name[0] !=
'?' ) {
644 MesPrint(
"@Illegal empty value for preprocessor variable %s",name);
650 if ( *s !=
' ' && *s !=
'\t' ) num++;
657 if ( StrCmp(name,PreVar[i].name) == 0 ) {
664 if ( i < 0 ) { p = (
PREVAR *)FromList(&AP.PreVarList); ii = p - PreVar; }
665 else { p = &(PreVar[i]); ii = i; }
667 s = value;
while ( *s ) { s++; num++; }
673 while ( *s ) { s++; nnum++; }
680 if ( value && p->
value ) {
683 while ( *s ) *t++ = *s++; *t = 0;
689 s = name;
while ( *s ) { s++; num++; }
690 t = (UBYTE *)Malloc1(num,
"PreVariable");
692 s = name;
while ( *s ) *t++ = *s++; *t++ = 0;
695 s = value;
while ( *s ) *t++ = *s++; *t = 0;
696 if ( AM.atstartup && t[-1] ==
'\n' ) t[-1] = 0;
705 if ( *s ==
' ' || *s ==
'\t' ) { s++;
continue; }
707 s++; *t++ = 0; numargs++;
708 while ( *s ==
' ' || *s ==
'\t' ) s++;
711 Error0(
"More than one ?var in #define");
716 else if ( *s ==
'?' && first ) {
719 else { *t++ = *s++; }
730 if ( u ) M_free(u,
"replace PreVar value");
739 VOID PopPreVars(
int tonumber)
741 PREVAR *p = &(PreVar[NumPre]);
742 while ( NumPre > tonumber ) {
744 M_free(p->
name,
"popping PreVar");
754 VOID IniModule(
int type)
758 CBUF *C = cbuf+AC.cbufnum;
772 AR.StoreData.dirtyflag = 0;
773 AC.bracketindexflag = 0;
774 AT.bracketindexflag = 0;
779 AC.RhsExprInModuleFlag = 0;
782 PF.slavebuf.PObuffer=NULL;
783 for(i=0; i<NumExpressions; i++)
784 Expressions[i].vflags &= ~ISINRHS;
796 w = C->
rhs; i = C->maxrhs;
797 do { *w++ = 0; }
while ( --i > 0 );
800 w = C->
lhs; i = C->maxlhs;
801 do { *w++ = 0; }
while ( --i > 0 );
804 C->numlhs = C->numrhs = 0;
805 ClearTree(AC.cbufnum);
806 while ( AC.NumLabels > 0 ) {
808 if ( AC.LabelNames[AC.NumLabels] ) M_free(AC.LabelNames[AC.NumLabels],
"LabelName");
813 AC.Commercial[0] = 0;
815 AC.IfStack = AC.IfHeap;
823 AC.MustTestTable = 0;
828 AC.SymChangeFlag = 0;
829 AP.lhdollarerror = 0;
830 AR.PolyFun = AC.lPolyFun;
831 AR.PolyFunInv = AC.lPolyFunInv;
832 AR.PolyFunType = AC.lPolyFunType;
833 AR.PolyFunExp = AC.lPolyFunExp;
834 AR.PolyFunVar = AC.lPolyFunVar;
835 AR.PolyFunPow = AC.lPolyFunPow;
836 AC.mparallelflag = AC.parallelflag | AM.hparallelflag;
837 AC.inparallelflag = 0;
838 AC.mProcessBucketSize = AC.ProcessBucketSize;
839 NumPotModdollars = 0;
840 AC.topolynomialflag = 0;
842 if ( AM.totalnumberofthreads > 1 ) AS.MultiThreaded = 1;
843 else AS.MultiThreaded = 0;
844 for ( i = 1; i < AM.totalnumberofthreads; i++ ) {
845 AB[i]->T.S0->PolyWise = 0;
856 VOID IniSpecialModule(
int type)
868 int moduletype = FIRSTMODULE;
870 int error1 = 0, error2 = 0, retcode, numstatement, retval;
872 AP.StopWatchZero = GetRunningTime();
874 AP.PreContinuation = 0;
875 AP.PreAssignLevel = 0;
877 AC.iPointer = AC.iBuffer;
880 if ( AC.CheckpointFlag == -1 )
DoRecovery(&moduletype);
881 AC.CheckpointStamp = Timer(0);
886 IniModule(moduletype);
892 NumToStr(buf,AC.CModule);
896 if ( specialtype ) IniSpecialModule(specialtype);
901 if ( c == AP.ComChar ) {
903 if ( AC.CurrentStream->FoldName ) {
905 if ( *t && t[1] && t[2] ==
'#' && t[3] ==
']' ) {
907 while ( *t ==
' ' || *t ==
'\t' ) t++;
908 s = AC.CurrentStream->FoldName;
909 while ( *s == *t ) { s++; t++; }
910 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t' 912 while ( *t ==
' ' || *t ==
'\t' ) t++;
914 AC.CurrentStream = CloseStream(AC.CurrentStream);
922 while ( c ==
' ' || c ==
'\t' ) c = GetChar(0);
923 if ( c == LINEFEED )
continue;
924 if ( c == ENDOFINPUT ) {
926 Warning(
".end instruction generated");
927 moduletype = ENDMODULE; specialtype = 0;
931 if ( PreProInstruction() ) { error1++; error2++; AP.preError++; }
934 else if ( c ==
'.' ) {
935 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
936 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
940 if ( ModuleInstruction(&moduletype,&specialtype) ) { error2++; AP.preError++; }
941 if ( specialtype ) SetSpecialMode(moduletype,specialtype);
942 if ( AP.PreInsideLevel != 0 ) {
943 MesPrint(
"@end of module instructions may not be used inside");
944 MesPrint(
"@the scope of a %#inside %#endinside construction.");
947 if ( AC.RepLevel > 0 ) {
948 MesPrint(
"&EndRepeat statement(s) missing");
949 error2++; AP.preError++;
951 if ( AC.tablecheck == 0 ) {
953 if ( TestTables() ) { error2++; AP.preError++; }
955 if ( AP.PreContinuation ) {
957 MesPrint(
"&Unfinished statement. Missing ;?");
959 if ( moduletype == GLOBALMODULE ) MakeGlobal();
961 endmodule:
if ( error2 == 0 && AM.qError == 0 ) {
962 retcode = ExecModule(moduletype);
964 if(PF.slavebuf.PObuffer!=NULL){
965 M_free(PF.slavebuf.PObuffer,
"PF inbuf");
966 PF.slavebuf.PObuffer=NULL;
970 if ( retcode < 0 ) error1++;
971 if ( retcode ) { error2++; AP.preError++; }
976 for ( j = 0, e = Expressions; j < NumExpressions; j++, e++ ) {
977 if ( e->replace == NEWLYDEFINEDEXPRESSION ) e->replace = REGULAREXPRESSION;
980 switch ( moduletype ) {
982 if ( ExecStore() ) error1++;
986 error1 = error2 = AP.preError = 0;
988 PutPreVar((UBYTE *)
"DATE_",(UBYTE *)MakeDate(),0,1);
990 if ( AM.resetTimeOnClear ) {
997 AP.StopWatchZero = GetRunningTime();
1000 Terminate( -( error1 | error2 ) );
1005 if ( AC.exprfillwarning > 0 ) {
1006 AC.exprfillwarning = 0;
1008 if ( AC.CheckpointFlag && error1 == 0 && error2 == 0 )
DoCheckpoint(moduletype);
1012 if ( ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ||
1013 ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) ) {
1019 if ( AP.PreContinuation ) {
1020 retval = LoadStatement(OLDSTATEMENT);
1024 AC.CurrentStream->prevline = AC.CurrentStream->linenumber;
1025 retval = LoadStatement(NEWSTATEMENT);
1029 if ( retval == -1 ) AP.PreContinuation = 0;
1030 else AP.PreContinuation = 1;
1033 else if ( retval > 0 ) AP.PreContinuation = 0;
1034 else AP.PreContinuation = 1;
1035 if ( error1 == 0 && !AP.PreContinuation ) {
1036 if ( ( AP.PreDebug & PREPROONLY ) == 0 ) {
1037 int onpmd = NumPotModdollars;
1039 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
1040 if ( AP.PreAssignFlag ) AC.RhsExprInModuleFlag = 0;
1042 if ( AP.PreOut || ( AP.PreDebug & DUMPTOCOMPILER )
1044 MesPrint(
" %s",AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1045 retcode = CompileStatement(AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1046 if ( retcode < 0 ) error1++;
1047 if ( retcode ) { error2++; AP.preError++; }
1048 if ( AP.PreAssignFlag ) {
1049 if ( retcode == 0 ) {
1050 if ( ( retcode = CatchDollar(0) ) < 0 ) error1++;
1051 else if ( retcode > 0 ) { error2++; AP.preError++; }
1053 else CatchDollar(-1);
1055 if ( AP.PreAssignLevel <=0 )
1056 AP.PreAssignFlag = 0;
1057 NumPotModdollars = onpmd;
1059 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
1064 MesPrint(
" %s",AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]);
1067 else if ( !AP.PreContinuation ) {
1068 if ( AP.PreAssignLevel > 0 ) {
1070 if ( AP.PreAssignLevel <=0 )
1071 AP.PreAssignFlag = 0;
1087 int PreProInstruction()
1097 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
1099 if ( ( StrICmp(AP.preStart,(UBYTE *)
"case") == 0
1100 || StrICmp(AP.preStart,(UBYTE *)
"default") == 0 )
1101 && AP.PreSwitchModes[AP.PreSwitchLevel] == SEARCHINGPRECASE ) {
1104 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
1105 else { LoadInstruction(1); }
1107 else if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
1109 if ( ( StrICmp(AP.preStart,(UBYTE *)
"else") == 0
1110 || StrICmp(AP.preStart,(UBYTE *)
"elseif") == 0 )
1111 && AP.PreIfStack[AP.PreIfLevel] == LOOKINGFORELSE ) {
1114 else if ( StrICmp(AP.preStart,(UBYTE *)
"assign ") == 0 ) {}
1125 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1126 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1129 else if ( *t ==
'+' ) {
1130 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH
1131 && AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF )
1134 else if ( *t ==
':' ) {}
1137 key = FindKeyWord(t,precommands,
sizeof(precommands)/
sizeof(
KEYWORD));
1145 MesPrint(
"@Unrecognized preprocessor instruction: %s",t);
1149 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
1152 while ( ( t[-1] ==
';' ) && ( t[-2] !=
'\\' ) ) {
1155 if ( key->type )
return(((TFUN1)key->func)(s,key->type));
1156 else return((key->func)(s));
1176 int LoadInstruction(
int mode)
1178 UBYTE *s, *sstart, *t, c, cp;
1179 LONG position, fillpos = 0;
1180 int bralevel = 0, parlevel = 0, first = 1;
1185 if ( s[1] != LINEFEED && s[1] != ENDOFINPUT ) {
1188 else { oldmode = mode;
return(0); }
1190 else { s = AP.preStart; }
1193 if ( ( mode & 1 ) == 1 ) {
1194 if ( pushbackchar && ( mode == 3 || mode == 5 ) ) {
1195 c = pushbackchar; pushbackchar = 0;
1197 else c = GetInput();
1203 if ( mode == 2 && c ==
';' )
break;
1204 if ( ( mode == 1 || mode == 5 ) && c == LINEFEED )
break;
1205 if ( mode == 3 && FG.cTable[c] != 0 ) {
1208 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1209 *s++ =
'g'; *s++ =
'n'; *s++ =
' '; *s = 0;
1211 AP.preFill = s; *s++ = 0; *s = c;
1215 if ( mode == 0 && first ) {
1217 dodollar: s = sstart;
1218 *s++ =
'a'; *s++ =
's'; *s++ =
's'; *s++ =
'i';
1219 *s++ =
'g'; *s++ =
'n'; *s = 0;
1224 if ( c ==
' ' || c ==
'\t' || c ==
',' ) {}
1227 else if ( mode == 1 && first && c ==
'$' && oldmode == 3 )
goto dodollar;
1228 if ( c == ENDOFINPUT || ( c == LINEFEED
1230 && quotelevel == 0 ) ) {
1231 if ( mode == 2 && c == ENDOFINPUT ) {
1232 MesPrint(
"@Unexpected end of instruction");
1243 if ( mode != 2 )
break;
1247 if ( ( mode == 1 ) || ( mode == 5 ) ) c = GetInput();
1251 if ( c == ENDOFINPUT ) {
1252 MesPrint(
"@Unmatched \"");
1253 if ( mode == 2 && c == ENDOFINPUT ) {
1254 MesPrint(
"@Unexpected end of instruction");
1264 else if ( c == LINEFEED ) {}
1265 else if ( c ==
'"' ) { *s++ =
'\\'; }
1270 else if ( c ==
'"' ) {
1275 else if ( c ==
'\\' ) {
1276 if ( ( mode == 1 ) || ( mode == 5 ) ) cp = GetInput();
1280 if ( cp == LINEFEED )
continue;
1281 if ( mode != 2 || cp !=
';' ) *s++ = c;
1284 else if ( c ==
'"' ) {
1290 while ( FG.cTable[*t] <= 1 ) t++;
1292 if ( ( StrICmp(AP.preStart,(UBYTE *)
"define") == 0 )
1293 || ( StrICmp(AP.preStart,(UBYTE *)
"redefine") == 0 ) ) {
1295 oldstream = AC.CurrentStream;
1300 else if ( quotelevel == 0 && bralevel == 0 && c ==
'(' ) {
1302 while ( FG.cTable[*t] <= 1 ) t++;
1304 if ( ( parlevel == 0 )
1305 && ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 ) ) {
1307 oldstream = AC.CurrentStream;
1312 else if ( quotelevel == 0 && bralevel == 0 && c ==
')' ) {
1315 else if ( quotelevel == 0 && parlevel == 0 && c ==
'{' ) {
1317 while ( FG.cTable[*t] <= 1 ) t++;
1319 if ( ( bralevel == 0 )
1320 && ( ( StrICmp(AP.preStart,(UBYTE *)
"call") == 0 )
1321 || ( StrICmp(AP.preStart,(UBYTE *)
"do") == 0 ) ) ) {
1323 oldstream = AC.CurrentStream;
1328 else if ( quotelevel == 0 && parlevel == 0 && c ==
'}' ) {
1330 if ( bralevel < 0 ) {
1332 MesPrint(
"@Unmatched brackets");
1339 if ( s >= (AP.preStop-1) ) {
1341 position = s - AP.preStart;
1342 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1343 ppp = &(AP.preStart);
1344 if ( DoubleLList((VOID ***)ppp,&AP.pSize,
sizeof(UBYTE),
1345 "instruction buffer") ) { *s = 0; oldmode = mode;
return(-1); }
1346 AP.preStop = AP.preStart + AP.pSize-3;
1347 s = AP.preStart + position;
1348 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1355 if ( ExpandTripleDots(1) < 0 )
return(-1);
1374 int LoadStatement(
int type)
1377 int retval = 0, stringlevel = 0, newstatement = 0;
1378 if ( type == NEWSTATEMENT ) { AP.eat = 1; newstatement = 1;
1379 s = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; }
1380 else { s = AC.iPointer; *s = 0; c =
' ';
goto blank; }
1384 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1385 if ( stringlevel == 0 ) {
1386 if ( c == LINEFEED ) { retval = 0;
break; }
1388 if ( AP.eat < 0 ) s--;
1389 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1390 if ( c != LINEFEED ) UngetChar(c);
1397 if ( cp == LINEFEED )
continue;
1402 if ( stringlevel == 0 ) stringlevel = 1;
1403 else stringlevel = 0;
1406 else if ( stringlevel == 0 ) {
1407 if ( c ==
'\t' ) c =
' ';
1409 blank:
if ( newstatement < 0 ) newstatement = 0;
1410 if ( AP.eat && ( newstatement == 0 ) )
continue;
1413 if ( newstatement > 0 ) newstatement = -1;
1415 else if ( chartype[c] <= 3 ) {
1417 if ( newstatement < 0 ) newstatement = 0;
1419 else if ( c ==
',' ) {
1420 if ( newstatement > 0 ) {
1425 else if ( AP.eat == -2 ) { AP.eat = 1;
continue; }
1426 else {
goto doall; }
1429 doall:;
if ( AP.eat < 0 ) {
1430 if ( newstatement == 0 ) s--;
1431 else { newstatement = 0; }
1433 else if ( newstatement == 1 ) newstatement = 0;
1435 if ( c ==
'*' && s > AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] && s[-1] ==
'*' ) {
1441 if ( s >= AC.iStop ) {
1442 if ( !AP.iBufError ) {
1443 LONG position = s - AC.iBuffer;
1444 LONG position2 = AC.iPointer - AC.iBuffer;
1445 UBYTE **ppp = &(AC.iBuffer);
1446 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1447 ,
sizeof(UBYTE),
"statement buffer") ) {
1448 *s = 0; retval = -1; AP.iBufError = 1;
1450 AC.iPointer = AC.iBuffer + position2;
1451 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1452 s = AC.iBuffer + position;
1454 if ( AP.iBufError ) {
1457 if ( c == ENDOFINPUT ) { retval = -1;
break; }
1459 if ( stringlevel > 0 ) stringlevel = 0;
1460 else stringlevel = 1;
1462 else if ( c == LINEFEED && !stringlevel ) { retval = -2;
break; }
1463 else if ( c ==
';' && !stringlevel ) {
1464 while ( ( c = GetChar(0) ) ==
' ' || c ==
'\t' ) {}
1465 if ( c != LINEFEED ) UngetChar(c);
1469 else if ( c ==
'\\' ) c = GetChar(0);
1478 if ( stringlevel > 0 ) {
1479 MesPrint(
"@Unbalanced \". Runaway string");
1482 if ( retval == 1 ) {
1483 if ( ExpandTripleDots(0) < 0 ) retval = -1;
1493 static inline int IsSignChar(UBYTE c)
1495 return c ==
'+' || c ==
'-';
1498 static inline int IsAlphanumericChar(UBYTE c)
1500 return FG.cTable[c] == 0 || FG.cTable[c] == 1;
1503 static inline int CanParseSignedNumber(
const UBYTE *s)
1505 while ( IsSignChar(*s) ) s++;
1506 return FG.cTable[*s] == 1;
1509 int ExpandTripleDots(
int par)
1511 UBYTE *s, *s1, *s2, *n1, *n2, *t1, *t2, *startp, operator1, operator2, c, cc;
1512 UBYTE *nBuffer, *strngs, *Buffer, *Stop;
1513 LONG withquestion, x1, x2, y1, y2, number, inc, newsize, pow, fullsize;
1514 int i, error = 0, i1 ,i2, ii, *nums = 0;
1517 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1520 Buffer = AP.preStart; Stop = AP.preStop;
1522 s = Buffer;
while ( *s ) s++;
1523 fullsize = s - Buffer;
1524 if ( fullsize < 7 )
return(error);
1528 if ( *s !=
'.' || ( s[-1] !=
',' && FG.cTable[s[-1]] != 5 ) )
1530 if ( s[-1] ==
'%' || s[-1] ==
'^' || s[1] !=
'.' || s[2] !=
'.' )
1534 if ( *s != s[-4] && ( *s !=
'+' || s[-4] !=
'-' )
1535 && ( *s !=
'-' || s[-4] !=
'+' ) ) {
1536 MesPrint(
"&Improper operators for ...");
1541 if ( operator1 ==
':' ) operator1 =
'.';
1542 if ( operator2 ==
':' ) operator2 =
'.';
1552 if ( *s2 !=
'<' || *s1 !=
'>' ) {
1554 withquestion = ( *s1 ==
'?' ); s1--;
1555 while ( FG.cTable[*s1] == 1 && s1 >= Buffer ) s1--;
1557 if ( FG.cTable[*n1] != 1 ) {
1558 MesPrint(
"&No first number in ... operator");
1561 while ( FG.cTable[*s1] <= 1 && s1 >= Buffer ) s1--;
1567 while ( t1 < n1 && *t1 == *t2 ) { t1++; t2++; }
1569 if ( FG.cTable[*t2] != 1 ) {
1570 MesPrint(
"&No second number in ... operator");
1574 while ( FG.cTable[*t2] == 1 ) x2 = 10*x2 + *t2++ -
'0';
1576 while ( FG.cTable[*t1] == 1 ) x1 = 10*x1 + *t1++ -
'0';
1577 if ( withquestion != ( *t2 ==
'?' ) ) {
1578 MesPrint(
"&Improper use of ? in ... operator");
1579 if ( *t2 ==
'?' ) t2++;
1582 else if ( withquestion ) t2++;
1583 if ( FG.cTable[*t2] <= 2 ) {
1584 MesPrint(
"&Illegal object after ... construction");
1587 c = *n1; *n1 = 0; s = t2;
1588 if ( error )
continue;
1597 if ( x2 < x1 ) { number = x1-x2; inc = -1; y1 = x2; y2 = x1; }
1598 else { number = x2-x1; inc = 1; y1 = x1; y2 = x2; }
1599 newsize = (number+1)*(n1-s1)
1601 +(number+1)*(withquestion?1:0)
1604 for ( i = 1; i < 10; i++, pow *= 10 ) {
1605 if ( y1 >= pow ) newsize += number+1;
1606 else if ( y2 >= pow ) newsize += y2-pow+1;
1609 while ( Buffer+(fullsize+newsize-(s-s1)) >= Stop ) {
1610 LONG strpos = s1-Buffer;
1611 LONG endstr = n1-Buffer;
1612 LONG startq = startp - Buffer;
1613 LONG position = s - Buffer;
1616 LONG position2 = AC.iPointer - AC.iBuffer;
1617 ppp = &(AC.iBuffer);
1618 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1619 ,
sizeof(UBYTE),
"statement buffer") ) {
1622 AC.iPointer = AC.iBuffer + position2;
1623 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1624 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1628 if ( AP.preFill ) fillpos = AP.preFill - AP.preStart;
1629 ppp = &(AP.preStart);
1630 if ( DoubleLList((VOID ***)ppp,&AP.pSize,
sizeof(UBYTE),
1631 "instruction buffer") ) {
1634 AP.preStop = AP.preStart + AP.pSize-3;
1635 if ( AP.preFill ) AP.preFill = fillpos + AP.preStart;
1636 Buffer = AP.preStart; Stop = AP.preStop;
1638 s = Buffer + position;
1639 n1 = Buffer + endstr;
1640 s1 = Buffer + strpos;
1641 startp = Buffer + startq;
1649 if ( newsize > (s-s1) ) {
1650 t2 = Buffer + fullsize;
1651 t1 = t2 + (newsize - (s-s1));
1653 while ( t2 > s ) { *--t1 = *--t2; }
1655 else if ( newsize < (s-s1) ) {
1656 t1 = s1 + newsize; t2 = s; s = t1;
1657 while ( *t2 ) *t1++ = *t2++;
1660 for ( x1 += inc, t1 = startp; number > 0; number--, x1 += inc ) {
1662 cc = operator1; operator1 = operator2; operator2 = cc;
1663 t2 = s1;
while ( *t2 ) *t1++ = *t2++;
1666 *t1++ =
'0' + x2 % 10;
1670 while ( s2 > n2 ) { cc = *s2; *s2 = *n2; *n2++ = cc; s2--; }
1671 if ( withquestion ) *t1++ =
'?';
1673 fullsize += newsize - ( s - s1 );
1678 while ( s1 > Buffer ) {
1679 if ( *s1 ==
'<' )
break;
1684 if ( *t2 ==
'>' )
break;
1687 if ( *s1 !=
'<' || *t2 !=
'>' ) {
1688 MesPrint(
"&Illegal attempt to use ... operator");
1692 nums = (
int *)Malloc1((t1-s1)*2*(
sizeof(int)+
sizeof(UBYTE))
1694 strngs = (UBYTE *)(nums + 2*(t1-s1));
1695 n1 = s1; n2 = s2; ii = -1; i = 0;
1697 while ( n1 < t1 || n2 < t2 ) {
1699 if ( CanParseSignedNumber(n1) && CanParseSignedNumber(n2) ) {
1708 int sign1 = IsSignChar(*n1);
1709 int sign2 = IsSignChar(*n2);
1710 int inword1 = s1 < n1 && IsAlphanumericChar(n1[-1]);
1711 int inword2 = s2 < n2 && IsAlphanumericChar(n2[-1]);
1712 if ( ( sign1 ^ sign2 ) && ( inword1 || inword2 ) )
break;
1713 if ( sign1 || sign2 ) {
1718 if ( *n1 == *n2 ) { *s++ = *n1++; n2++;
continue; }
1721 ParseSignedNumber(x1,n1)
1722 ParseSignedNumber(x2,n2)
1724 if ( s != strngs && ( s[-1] ==
'+' || s[-1] ==
'-' ) ) {
1734 nums[2*i] = x1; nums[2*i+1] = x2;
1738 if ( n1 < t1 || n2 < t2 ) {
1739 MesPrint(
"&Improper use of ... operator.");
1740 theend: M_free(nums,
"Expand ...");
1744 if ( i == 0 ) ii = 0;
1746 ii = nums[0] - nums[1];
1747 if ( ii < 0 ) ii = -ii;
1748 for ( x1 = 1; x1 < i; x1++ ) {
1749 x2 = nums[2*x1]-nums[2*x1+1];
1750 if ( x2 < 0 ) x2 = -x2;
1752 MesPrint(
"&Improper synchronization of numbers in ... operator");
1767 x2 = s - strngs - i;
1768 for ( i1 = 0; i1 < i; i1++ ) {
1771 if ( i2 < 0 ) i2 = -i2;
1772 if ( x1 < 0 ) x1 = -x1;
1773 if ( x1 > i2 ) i2 = x1;
1775 while ( i2 > 0 ) { i2 /= 10; x1++; }
1781 x2 +=
sizeof(UBYTE *);
1782 x2 = x2 - (x2 & (
sizeof(UBYTE *)-1));
1784 nBuffer = (UBYTE *)Malloc1(x2,
"input buffer");
1785 n1 = nBuffer; s = Buffer; s1--;
1786 while ( s < s1 ) *n1++ = *s++;
1794 if ( ( ( n1 > nBuffer ) && ( ( FG.cTable[n1[-1]] <= 1 )
1795 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1796 ( ( FG.cTable[strngs[0]] <= 1 ) || ( strngs[0] ==
'[' )
1797 || ( strngs[0] ==
'_' ) ) ) *n1++ =
',';
1799 for ( i1 = 0; i1 < ii; i1++ ) {
1800 s = strngs;
while ( *s ) *n1++ = *s++;
1801 for ( i2 = 0; i2 < i; i2++ ) {
1802 if ( n1 > nBuffer && IsSignChar(n1[-1]) ) {
1805 if ( nums[2*i2] >= 0 ) {
1809 n1 = NumCopy((WORD)(nums[2*i2]),n1);
1810 if ( nums[2*i2] > nums[2*i2+1] ) nums[2*i2]--;
1812 s++;
while ( *s ) *n1++ = *s++;
1814 if ( ( i1 & 1 ) == 0 ) *n1++ = operator1;
1815 else *n1++ = operator2;
1818 s = t2 + 1; n2 = n1;
1822 if ( ( ( ( FG.cTable[n1[-1]] <= 1 )
1823 || ( n1[-1] ==
'_' ) || ( n1[-1] ==
']' ) ) ) &&
1824 ( ( FG.cTable[s[0]] <= 1 ) || ( s[0] ==
'[' )
1825 || ( s[0] ==
'_' ) ) ) *n1++ =
',';
1827 while ( *s ) *n1++ = *s++;
1830 LONG nnn1 = n1-nBuffer;
1831 LONG nnn2 = n2-nBuffer;
1833 while ( AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel] + x2 >= AC.iStop ) {
1834 LONG position = s-Buffer;
1835 LONG position2 = AC.iPointer - AC.iBuffer;
1837 ppp = &(AC.iBuffer);
1838 if ( DoubleLList((VOID ***)ppp,&AC.iBufferSize
1839 ,
sizeof(UBYTE),
"statement buffer") ) {
1842 AC.iPointer = AC.iBuffer + position2;
1843 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
1844 Buffer = AC.iBuffer+AP.PreAssignStack[AP.PreAssignLevel]; Stop = AC.iStop;
1845 s = Buffer + position;
1850 for ( nnn3 = 0; nnn3 < nnn1; nnn3++ ) Buffer[nnn3] = nBuffer[nnn3];
1854 M_free(nBuffer,
"input buffer");
1855 M_free(nums,
"Expand ...");
1858 AP.preStop = nBuffer + x2 - 2;
1860 M_free(AP.preStart,
"input buffer");
1861 M_free(nums,
"Expand ...");
1862 AP.preStart = nBuffer;
1863 Buffer = AP.preStart; Stop = AP.preStop;
1865 fullsize = n1 - Buffer;
1883 while ( hi >= low ) {
1885 s1 = (UBYTE *)(table[med].name);
1887 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1893 FG.cTable[*s2] != 0 && FG.cTable[*s2] != 1
1897 if ( tolower(*s2) > tolower(*s1) ) low = med+1;
1912 for ( i = 0; i < size; i++ ) {
1913 s1 = (UBYTE *)(table[i].name);
1915 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1916 if ( *s2 == 0 || *s2 ==
' ' || *s2 ==
',' || *s2 ==
'\t' )
1940 UBYTE *name, *value, *valpoin, *args = 0, c;
1941 if ( ( mode & 2 ) == 0 ) {
1942 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
1943 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
1945 else { mode &= ~2; }
1947 if ( chartype[*s] != 0 )
goto illname;
1949 while ( chartype[*s] <= 1 ) s++;
1951 while ( *s ==
' ' || *s ==
'\t' ) s++;
1954 if (
PutPreVar(name,(UBYTE *)
"1",0,mode) < 0 )
return(-1);
1960 if ( chartype[*s] != 0 )
goto illarg;
1962 while ( chartype[*s] <= 1 ) s++;
1963 while ( *s ==
' ' || *s ==
'\t' ) s++;
1964 if ( *s ==
')' )
break;
1965 if ( *s !=
',' )
goto illargs;
1967 while ( *s ==
' ' || *s ==
'\t' ) s++;
1970 while ( *s ==
' ' || *s ==
'\t' ) s++;
1974 s++; valpoin = value = s;
1975 while ( *s !=
'"' ) {
1977 if ( s[1] ==
'n' ) { *valpoin++ = LINEFEED; s += 2; }
1978 else if ( s[1] ==
'"' ) { *valpoin++ =
'"'; s += 2; }
1979 else if ( s[1] == 0 )
goto illval;
1980 else { *valpoin++ = *s++; *valpoin++ = *s++; }
1982 else *valpoin++ = *s++;
1985 if (
PutPreVar(name,value,args,mode) < 0 )
return(-1);
1988 MesPrint(
"@Illegal string for preprocessor variable %s. Forgotten double quotes (\") ?",name);
1993 MesPrint(
"@Illegally formed name of preprocessor variable");
1996 MesPrint(
"@Illegally formed name of argument of preprocessor definition");
1999 MesPrint(
"@Illegally formed arguments of preprocessor definition");
2002 MesPrint(
"@Illegal valpoin for preprocessor variable %s",name);
2011 int DoCommentChar(UBYTE *s)
2014 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2015 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2016 while ( *s ==
' ' || *s ==
'\t' ) s++;
2017 if ( *s == 0 || *s ==
'\n' ) {
2018 MesPrint(
"@No valid comment character specified");
2022 while ( *s ==
' ' || *s ==
'\t' ) s++;
2023 if ( *s != 0 && *s !=
'\n' ) {
2024 MesPrint(
"@Comment character should be a single valid character");
2042 int DoPreAssign(UBYTE *s)
2045 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH ) {
2048 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) {
2052 MesPrint(
"@Illegal characters in %#assign instruction");
2056 AP.PreAssignFlag = 1;
2073 int DoDefine(UBYTE *s)
2083 int DoRedefine(UBYTE *s)
2095 int ClearMacro(UBYTE *name)
2100 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2101 if ( StrCmp(name,p->
name) == 0 )
break;
2103 if ( i < 0 )
return(-1);
2104 if ( p->
nargs <= 0 )
return(0);
2106 for ( i = 0; i < p->
nargs; i++ ) {
2123 int TheUndefine(UBYTE *name)
2125 int i, inum, error = 0;
2127 for ( i = NumPre-1, p = &(PreVar[NumPre-1]); i >= 0; i--, p-- ) {
2128 if ( StrCmp(name,p->
name) == 0 ) {
2129 M_free(p->
name,
"undefining PreVar");
2132 while ( i < NumPre ) {
2139 CBUF *CC = cbuf + AC.cbufnum;
2141 for ( j = 1; j <= CC->numlhs; j++ ) {
2142 if ( CC->
lhs[j][0] == TYPEREDEFPRE ) {
2143 if ( CC->
lhs[j][2] > inum ) CC->
lhs[j][2]--;
2144 else if ( CC->
lhs[j][2] == inum ) {
2145 for ( k = inum - 1; k >= 0; k-- )
2146 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2147 if ( k >= 0 ) CC->
lhs[j][2] = k;
2149 MesPrint(
"@Conflict between undefining a preprocessor variable and a redefine statement");
2156 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2157 if ( AC.pfirstnum[j] > inum ) AC.pfirstnum[j]--;
2158 else if ( AC.pfirstnum[j] == inum ) {
2159 for ( k = inum - 1; k >= 0; k-- )
2160 if ( StrCmp(name, PreVar[k].name) == 0 )
break;
2161 if ( k >= 0 ) AC.pfirstnum[j] = k;
2177 int DoUndefine(UBYTE *s)
2180 int error = 0, retval;
2185 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2186 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2188 if ( chartype[*s] != 0 )
goto illname;
2190 while ( chartype[*s] <= 1 ) s++;
2192 if ( *s && *s !=
' ' && *s !=
'\t' )
goto illname;
2193 while ( *s ==
' ' || *s ==
'\t' ) s++;
2195 MesPrint(
"@Undefine should just have a variable name");
2199 if ( ( retval = TheUndefine(name) ) != 0 ) {
2200 if ( error == 0 )
return(retval);
2201 if ( error > 0 ) error = retval;
2220 MesPrint(
"@Illegally formed name of preprocessor variable");
2229 int DoInclude(UBYTE *s) {
return(Include(s,FILESTREAM)); }
2236 int DoReverseInclude(UBYTE *s) {
return(Include(s,REVERSEFILESTREAM)); }
2243 int Include(UBYTE *s,
int type)
2245 UBYTE *name = s, *fold, *t, c, c1 = 0, c2 = 0, c3 = 0;
2246 int str1offset, withnolist = AC.NoShowInput;
2247 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2248 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2249 if ( *s ==
'-' || *s ==
'+' ) {
2250 if ( *s ==
'-' ) withnolist = 1;
2251 else withnolist = 0;
2253 while ( *s ==
' ' || *s ==
'\t' ) s++;
2257 while ( *s && *s !=
'"' ) {
2258 if ( *s ==
'\\' ) s++;
2264 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2265 if ( *s ==
'\\' ) s++;
2270 while ( *s ==
' ' || *s ==
'\t' ) s++;
2274 while ( *s ==
' ' || *s ==
'\t' ) s++;
2277 MesPrint(
"@Empty fold name");
2281 while ( *s && *s !=
' ' && *s !=
'\t' ) {
2282 if ( *s ==
'\\' ) s++;
2286 while ( *s ==
' ' || *s ==
'\t' ) s++;
2294 else if ( *s == 0 ) {
2298 MesPrint(
"@Improper syntax for file name");
2303 fold = strDup1(fold,
"foldname");
2308 if ( OpenStream(name,type,0,PRENOACTION) == 0 ) {
2309 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2315 LONG linenum = 0, prevline = 0;
2316 name = strDup1(name,
"name of include file");
2317 AC.CurrentStream->FoldName = strDup1(fold,
"name of fold");
2320 c = GetFromStream(AC.CurrentStream);
2321 if ( c == ENDOFSTREAM ) {
2322 AC.CurrentStream = CloseStream(AC.CurrentStream);
2325 if ( c == AP.ComChar ) {
2326 str1offset = AC.CurrentStream-AC.Streams;
2328 if ( AC.CurrentStream != str1offset+AC.Streams ) {
2333 if ( t[2] ==
'#' && ( ( t[3] ==
'[' && !foldopen )
2334 || ( t[3] ==
']' && foldopen ) ) ) {
2336 while ( *t ==
' ' || *t ==
'\t' ) t++;
2337 s = AC.CurrentStream->FoldName;
2338 while ( *s == *t ) { s++; t++; }
2339 if ( *s == 0 && ( *t ==
' ' || *t ==
'\t' 2341 while ( *t ==
' ' || *t ==
'\t' ) t++;
2343 if ( foldopen == 0 ) {
2345 position = GetStreamPosition(AC.CurrentStream);
2346 linenum = AC.CurrentStream->linenumber;
2347 prevline = AC.CurrentStream->prevline;
2348 c3 = AC.CurrentStream->isnextchar;
2349 c1 = AC.CurrentStream->nextchar[0];
2350 c2 = AC.CurrentStream->nextchar[1];
2354 PositionStream(AC.CurrentStream,position);
2355 AC.CurrentStream->linenumber = linenum;
2356 AC.CurrentStream->prevline = prevline;
2357 AC.CurrentStream->eqnum = 1;
2359 AC.CurrentStream->isnextchar = c3;
2360 AC.CurrentStream->nextchar[0] = c1;
2361 AC.CurrentStream->nextchar[1] = c2;
2370 while ( c != LINEFEED && c != ENDOFSTREAM ) {
2371 c = GetFromStream(AC.CurrentStream);
2372 if ( c == ENDOFSTREAM ) {
2373 AC.CurrentStream = CloseStream(AC.CurrentStream);
2378 if ( c == ENDOFSTREAM ) {
2380 MesPrint(
"@Cannot find fold %s in file %s",fold,name);
2383 M_free(name,
"name of include file");
2387 M_free(name,
"name of include file");
2389 AC.NoShowInput = withnolist;
2390 if ( fold ) { M_free(fold,
"foldname"); fold = 0; }
2404 int DoPreExchange(UBYTE *s)
2409 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2410 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2411 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2413 s++; s1 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2414 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2416 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2417 if ( *s !=
'$' )
goto syntax;
2418 s++; s2 = s;
while ( FG.cTable[*s] <= 1 ) s++;
2419 if ( *s != 0 && *s !=
';' )
goto syntax;
2421 if ( ( num1 = GetDollar(s1) ) <= 0 ) {
2422 MesPrint(
"@$%s has not been defined (yet)",s1);
2425 if ( ( num2 = GetDollar(s2) ) <= 0 ) {
2426 MesPrint(
"@$%s has not been defined (yet)",s2);
2430 ExchangeDollars((
int)num1,(
int)num2);
2434 s1 = s; s = SkipAName(s);
2435 if ( *s !=
',' && *s !=
' ' && *s !=
'\t' )
goto syntax;
2437 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
2438 if ( FG.cTable[*s] != 0 && *s !=
'[' )
goto syntax;
2439 s2 = s; s = SkipAName(s);
2440 if ( *s != 0 && *s !=
';' )
goto syntax;
2442 if ( GetName(AC.exprnames,s1,&num1,NOAUTO) != CEXPRESSION ) {
2443 MesPrint(
"@%s is not an expression",s1);
2446 if ( GetName(AC.exprnames,s2,&num2,NOAUTO) != CEXPRESSION ) {
2447 MesPrint(
"@%s is not an expression",s2);
2451 ExchangeExpressions((
int)num1,(
int)num2);
2456 MesPrint(
"@Proper syntax: %#exchange expr1,expr2 or %#exchange $var1,$var2");
2465 int DoCall(UBYTE *s)
2467 UBYTE *t, *u, *v, *name, c, cp, *args1, *args2, *t1, *t2, *wild = 0;
2468 int bratype = 0, wildargs = 0, inwildargs = 0, nwildargs = 0;
2471 int i, namesize, narg1, narg2, bralevel, numpre;
2473 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2474 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2479 name = s; s = EndOfToken(s); c = *s; *s = 0;
2480 for ( i = NumProcedures-1; i >= 0; i-- ) {
2481 if ( StrCmp(Procedures[i].name,name) == 0 )
break;
2483 p = (
PROCEDURE *)FromList(&AP.ProcList);
2487 while ( *t ) { t++; namesize++; }
2488 t = AP.procedureExtension;
2489 while ( *t ) { t++; namesize++; }
2490 t = p->name = (UBYTE *)Malloc1(namesize+2,
"procedure");
2492 while ( *u ) *t++ = *u++;
2494 v = AP.procedureExtension;
2495 while ( *v ) *t++ = *v++;
2498 p->p.buffer = LoadInputFile(p->name,PROCEDUREFILE);
2499 if ( p->p.buffer == 0 )
return(-1);
2503 p->p.buffer = Procedures[i].p.buffer;
2504 p->name = Procedures[i].name;
2509 if ( *t++ !=
'#' )
goto wrongfile;
2515 if ( StrCmp(t,name) != 0 )
goto wrongfile;
2523 bralevel = narg1 = narg2 = 0; args2 = u;
2528 while ( *u !=
')' ) {
2529 if ( *u ==
'?' ) { wildargs++; u++; nwildargs = narg2+1; }
2530 narg2++; u = EndOfToken(u); SKIPBLANKS(u)
2531 if ( *u ==
',' ) { u++; SKIPBLANKS(u) }
2532 else if ( *u !=
')' || ( wildargs > 1 ) ) {
2533 MesPrint(
"@Illegal argument field in procedure %s",p->name);
2538 while ( *u != LINEFEED ) u++;
2541 if ( *s ==
'(' ) bratype = 1;
2543 if ( *s ==
'{' && bratype == 0 ) bralevel++;
2544 else if ( *s ==
'(' && bratype == 1 ) bralevel++;
2545 else if ( *s ==
'}' && bratype == 0 ) {
2547 if ( bralevel == 0 ) {
2549 if ( wildargs && narg1 == nwildargs ) wild = s;
2552 else if ( *s ==
')' && bratype == 1 ) {
2554 if ( bralevel == 0 ) {
2556 if ( wildargs && narg1 == nwildargs ) wild = s;
2561 else if (set_in(*s,AC.separators)) {
2565 if ( wildargs && narg1 == nwildargs ) wild = s;
2567 else if ( *s ==
'\\' ) s++;
2569 }
while ( bralevel > 0 );
2570 if ( wildargs && narg1 >= narg2-1 ) {
2571 inwildargs = narg1-narg2+1;
2572 if ( inwildargs == 0 ) nwildargs = 0;
2574 while ( inwildargs > 1 ) {
2576 while ( *wild ) wild++;
2581 else if ( narg1 != narg2 && ( narg2 != 0 || narg1 != 1 || *args1 != 0 ) ) {
2582 MesPrint(
"@Arguments of procedure %s are not matching",p->name);
2586 for ( i = 0; i < narg2; i++ ) {
2591 if ( *t ==
'?' && inwildargs == 0 ) {
2592 args2 = EndOfToken(args2); c = *args2; *args2 = 0;
2593 if (
PutPreVar(t,(UBYTE *)
"",0,0) < 0 )
return(-1);
2596 args2 = EndOfToken(args2); c = *args2; *args2 = 0;
2599 if ( *t1 ==
'\\' ) t1++;
2600 if ( t1 != t2 ) *t2 = *t1;
2604 if (
PutPreVar(t,args1,0,0) < 0 )
return(-1);
2607 *args2 = c; SKIPBLANKS(args2)
2608 args2++; SKIPBLANKS(args2)
2610 streamoffset = AC.CurrentStream - AC.Streams;
2611 args1 = AC.CurrentStream->name;
2612 AC.CurrentStream->name = p->name;
2613 i1 = AC.CurrentStream->linenumber;
2614 i2 = AC.CurrentStream->prevline;
2615 AC.CurrentStream->prevline =
2616 AC.CurrentStream->linenumber = 2;
2617 OpenStream(u+1,PREREADSTREAM3,numpre,PRENOACTION);
2618 AC.Streams[streamoffset].name = args1;
2619 AC.Streams[streamoffset].linenumber = i1;
2620 AC.Streams[streamoffset].prevline = i2;
2621 AddToPreTypes(PRETYPEPROCEDURE);
2624 if ( i < 0 ) MesPrint(
"@File %s is not a proper procedure",p->name);
2625 else MesPrint(
"!!!Internal error with procedure names: %s",name);
2634 int DoDebug(UBYTE *s)
2637 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2638 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2639 NeedNumber(x,s,nonumber)
2640 if ( x < 0 || x >(PREPROONLY
2651 if ( ( x & PREPROONLY ) != 0 ) AP.PreDebug |= PREPROONLY;
2652 if ( ( x & DUMPTOCOMPILER ) != 0 ) AP.PreDebug |= DUMPTOCOMPILER;
2653 if ( ( x & DUMPOUTTERMS ) != 0 ) AP.PreDebug |= DUMPOUTTERMS;
2654 if ( ( x & DUMPINTERMS ) != 0 ) AP.PreDebug |= DUMPINTERMS;
2655 if ( ( x & DUMPTOSORT ) != 0 ) AP.PreDebug |= DUMPTOSORT;
2656 if ( ( x & DUMPTOPARALLEL ) != 0 ) AP.PreDebug |= DUMPTOPARALLEL;
2658 if ( ( x & THREADSDEBUG ) != 0 ) AP.PreDebug |= THREADSDEBUG;
2662 MesPrint(
"@Illegal argument for debug instruction");
2671 int DoTerminate(UBYTE *s)
2674 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2675 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2677 NeedNumber(x,s,nonumber)
2685 MesPrint(
"@Illegal argument for terminate instruction");
2703 UBYTE *t, c, *u, *uu;
2706 LONG linenum = AC.CurrentStream->linenumber;
2707 int oldNoShowInput = AC.NoShowInput, i, oldpreassignflag;
2709 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
2710 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
2711 if ( PreSkip((UBYTE *)
"do",(UBYTE *)
"enddo",1) )
return(-1);
2719 AddToPreTypes(PRETYPEDO);
2721 loop = (
DOLOOP *)FromList(&AP.LoopList);
2722 loop->firstdollar = loop->lastdollar = loop->incdollar = -1;
2723 loop->NumPreTypes = AP.NumPreTypes-1;
2724 loop->PreIfLevel = AP.PreIfLevel;
2725 loop->PreSwitchLevel = AP.PreSwitchLevel;
2727 if ( PreLoad(&(loop->
p),(UBYTE *)
"do",(UBYTE *)
"enddo",1,
"doloop") )
return(-1);
2728 AC.NoShowInput = oldNoShowInput;
2729 loop->NoShowInput = AC.NoShowInput;
2733 s = loop->
p.buffer + (s - AP.preStart);
2736 if ( chartype[*s] != 0 )
goto illname;
2738 while ( chartype[*s] <= 1 ) s++;
2740 while ( *s ==
' ' || *s ==
'\t' ) s++;
2741 if ( *s !=
'=' )
goto illdo;
2743 while ( *s ==
' ' || *s ==
'\t' ) s++;
2747 loop->type = LISTEDLOOP;
2748 s++; loop->vars = s;
2750 while ( *s !=
'}' && *s != 0 ) {
2751 if ( set_in(*s,AC.separators) ) { *s = 0; loop->lastnum++; }
2752 else if ( *s ==
'\\' ) s++;
2755 if ( *s == 0 )
goto illdo;
2761 else if ( *s ==
'-' || *s ==
'+' || chartype[*s] == 1 || *s ==
'$' ) {
2762 loop->type = NUMERICALLOOP;
2764 while ( *s && *s !=
',' ) s++;
2765 if ( *s == 0 )
goto illdo;
2768 if ( GetName(AC.dollarnames,t+1,&loop->firstdollar,NOAUTO) != CDOLLAR ) {
2769 MesPrint(
"@%s is undefined in first parameter in %#do instruction",t);
2772 loop->firstnum = DolToLong(BHEAD loop->firstdollar);
2773 if ( AN.ErrorInDollar ) {
2774 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2781 if ( PreEval(t,&loop->firstnum) == 0 )
goto illdo;
2785 while ( *s && *s !=
',' && *s !=
';' && *s != LINEFEED ) s++;
2789 if ( GetName(AC.dollarnames,t+1,&loop->lastdollar,NOAUTO) != CDOLLAR ) {
2790 MesPrint(
"@%s is undefined in second parameter in %#do instruction",t);
2793 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
2794 if ( AN.ErrorInDollar ) {
2795 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2802 if ( PreEval(t,&loop->lastnum) == 0 )
goto illdo;
2807 while ( *s && *s !=
';' && *s != LINEFEED ) s++;
2810 if ( GetName(AC.dollarnames,t+1,&loop->incdollar,NOAUTO) != CDOLLAR ) {
2811 MesPrint(
"@%s is undefined in third parameter in %#do instruction",t);
2814 loop->incnum = DolToLong(BHEAD loop->incdollar);
2815 if ( AN.ErrorInDollar ) {
2816 MesPrint(
"@%s does not evaluate into a valid loop parameter",t);
2823 if ( PreEval(t,&loop->incnum) == 0 )
goto illdo;
2827 else loop->incnum = 1;
2830 else if ( ( chartype[*s] == 0 ) || ( *s ==
'[' ) ) {
2831 int oldNumPotModdollars = NumPotModdollars;
2833 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
2834 AC.RhsExprInModuleFlag = 0;
2837 if ( ( s = SkipAName(s) ) == 0 )
goto illdo;
2839 if ( GetName(AC.exprnames,t,&expnum,NOAUTO) == CEXPRESSION ) {
2840 loop->type = ONEEXPRESSION;
2849 if ( c ==
',' || c ==
'\t' || c ==
';' ) { s++; }
2850 else if ( c != 0 && c !=
'\n' )
goto illdo;
2851 while ( *s ==
',' || *s ==
'\t' || *s ==
';' ) s++;
2852 if ( *s != 0 && *s !=
'\n' )
goto illdo;
2863 while ( *t ) { t++; i++; }
2865 loop->
dollarname = Malloc1((LONG)i,
"do-loop instruction");
2870 *u++ =
'$'; t = loop->
name;
while ( *t ) *u++ = *t++;
2871 *u++ =
'_'; uu = u; *u++ =
'='; t = loop->vars;
2872 while ( *t ) *u++ = *t++; *t = 0; *u = 0;
2877 oldpreassignflag = AP.PreAssignFlag;
2878 AP.PreAssignFlag = 2;
2880 if ( CatchDollar(0) ) {
2881 MesPrint(
"@Cannot load expression in do loop");
2884 AP.PreAssignFlag = oldpreassignflag;
2885 NumPotModdollars = oldNumPotModdollars;
2887 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
2892 loop->errorsinloop = 0;
2894 loop->startlinenumber = linenum;
2896 loop->firstloopcall = 1;
2899 MesPrint(
"@Improper name for do loop variable");
2902 MesPrint(
"@Improper syntax in do loop instruction");
2914 int DoBreakDo(UBYTE *s)
2919 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2920 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
2922 if ( NumDoLoops <= 0 ) {
2923 MesPrint(
"@%#dobreak without %#do");
2929 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
2933 else if ( FG.cTable[*s] == 1 ) {
2935 while ( *s >=
'0' && *s <=
'9' ) { levels = 10*levels + *s++ -
'0'; }
2936 if ( *s != 0 )
goto improper;
2940 MesPrint(
"@Improper syntax of %#dobreak instruction");
2943 if ( levels > NumDoLoops ) {
2944 MesPrint(
"@Too many loop levels requested in %#breakdo instruction");
2947 while ( levels > 0 ) {
2948 while ( AC.CurrentStream->type != PREREADSTREAM
2949 && AC.CurrentStream->type != PREREADSTREAM2
2950 && AC.CurrentStream->type != PREREADSTREAM3 ) {
2951 AC.CurrentStream = CloseStream(AC.CurrentStream);
2953 while ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO
2954 && AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) AP.NumPreTypes--;
2955 if ( AC.CurrentStream->type == PREREADSTREAM3
2956 || AP.PreTypes[AP.NumPreTypes] == PRETYPEPROCEDURE ) {
2957 MesPrint(
"@Trying to jump out of a procedure with a %#breakdo instruction");
2960 loop = &(DoLoops[NumDoLoops-1]);
2961 AP.NumPreTypes = loop->NumPreTypes;
2962 AP.PreIfLevel = loop->PreIfLevel;
2963 AP.PreSwitchLevel = loop->PreSwitchLevel;
2968 DoUndefine(loop->
name);
2969 M_free(loop->
p.buffer,
"loop->p.buffer");
2970 loop->firstloopcall = 0;
2972 AC.CurrentStream = CloseStream(AC.CurrentStream);
2983 int DoElse(UBYTE *s)
2985 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
2986 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#else without corresponding %#if");
2987 else MessPreNesting(1);
2990 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
2991 while ( *s ==
' ' ) s++;
2992 if ( tolower(*s) ==
'i' && tolower(s[1]) ==
'f' && s[2]
2993 && FG.cTable[s[2]] > 1 && s[2] !=
'_' ) {
2995 while ( *s ==
' ' ) s++;
2996 return(DoElseif(s));
2998 if ( AP.PreIfLevel <= 0 ) {
2999 MesPrint(
"@%#else without corresponding %#if");
3002 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3004 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3006 case LOOKINGFORELSE:
3007 AP.PreIfStack[AP.PreIfLevel] = EXECUTINGIF;
3009 case LOOKINGFORENDIF:
3020 int DoElseif(UBYTE *s)
3023 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3024 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#elseif without corresponding %#if");
3025 else MessPreNesting(2);
3028 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3029 if ( AP.PreIfLevel <= 0 ) {
3030 MesPrint(
"@%#elseif without corresponding %#if");
3033 switch ( AP.PreIfStack[AP.PreIfLevel] ) {
3035 AP.PreIfStack[AP.PreIfLevel] = LOOKINGFORENDIF;
3037 case LOOKINGFORELSE:
3038 if ( ( condition = EvalPreIf(s) ) < 0 )
return(-1);
3039 AP.PreIfStack[AP.PreIfLevel] = condition;
3041 case LOOKINGFORENDIF:
3055 int DoEnddo(UBYTE *s)
3059 UBYTE *t, *tt, *value, numstr[16];
3063 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3064 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3073 if ( NumDoLoops <= 0 ) {
3074 MesPrint(
"@%#enddo without %#do");
3077 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEDO ) { MessPreNesting(4);
return(-1); }
3078 loop = &(DoLoops[NumDoLoops-1]);
3079 if ( !loop->firstloopcall ) AC.CurrentStream = CloseStream(AC.CurrentStream);
3081 if ( loop->errorsinloop ) {
3082 MesPrint(
"++++Errors in Loop");
3085 if ( loop->type == LISTEDLOOP ) {
3086 if ( loop->firstnum >= loop->lastnum )
goto finish;
3088 t = value = loop->vars;
3089 while ( *value ) value++;
3094 if ( *value ==
'\\' ) value++;
3100 else if ( loop->type == NUMERICALLOOP ) {
3102 if ( !loop->firstloopcall ) {
3107 t = GetPreVar(loop->name,WITHOUTERROR);
3111 while ( *value && ( *value ==
' ' 3112 || *value ==
'-' || *value ==
'+' ) ) {
3113 if ( *value ==
'-' ) xsign = -xsign;
3116 t = value; xval = 0;
3117 while ( *value >=
'0' && *value <=
'9' ) xval = 10*xval + *value++ -
'0';
3118 while ( *value && *value ==
' ' ) value++;
3119 if ( *value == 0 ) {
3123 if ( xsign < 0 ) xval = -xval;
3124 if ( loop->incdollar >= 0 ) {
3125 loop->incnum = DolToLong(BHEAD loop->incdollar);
3126 if ( AN.ErrorInDollar ) {
3127 MesPrint(
"@%s does not evaluate into a valid third loop parameter",DOLLARNAME(Dollars,loop->incdollar));
3131 loop->firstnum = xval + loop->incnum;
3134 if ( loop->lastdollar >= 0 ) {
3135 loop->lastnum = DolToLong(BHEAD loop->lastdollar);
3136 if ( AN.ErrorInDollar ) {
3137 MesPrint(
"@%s does not evaluate into a valid second loop parameter",DOLLARNAME(Dollars,loop->lastdollar));
3142 if ( ( loop->incnum > 0 && loop->firstnum > loop->lastnum )
3143 || ( loop->incnum < 0 && loop->firstnum < loop->lastnum ) )
goto finish;
3144 NumToStr(numstr,loop->firstnum);
3146 loop->firstnum += loop->incnum;
3149 else if ( loop->type == ONEEXPRESSION ) {
3153 WORD numdollar = GetDollar(loop->dollarname+1);
3154 DOLLARS d = Dollars + numdollar;
3155 WORD *w, *dw, v, *ww;
3156 if ( (d->where) == 0 ) {
3157 d->type = DOLUNDEFINED;
3158 M_free(loop->dollarname,
"do-loop instruction");
3161 w = d->where + loop->incnum;
3163 M_free(d->where,
"dollar");
3165 d->type = DOLUNDEFINED;
3166 M_free(loop->dollarname,
"do-loop instruction");
3173 ww = w + *w; v = *ww; *ww = 0;
3174 dw = d->where; d->where = w;
3175 t = WriteDollarToBuffer(numdollar,1);
3176 d->where = dw; *ww = v;
3180 if ( loop->firstloopcall ) OpenStream(loop->contents,PREREADSTREAM2,0,PRENOACTION);
3181 else OpenStream(loop->contents,PREREADSTREAM,0,PRENOACTION);
3182 AC.CurrentStream->prevline =
3183 AC.CurrentStream->linenumber = loop->startlinenumber;
3184 AC.CurrentStream->eqnum = 0;
3185 loop->firstloopcall = 0;
3189 retval = DoUndefine(loop->name);
3190 M_free(loop->p.buffer,
"loop->p.buffer");
3191 loop->firstloopcall = 0;
3201 int DoEndif(UBYTE *s)
3204 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEIF ) {
3205 if ( AP.PreIfLevel <= 0 ) MesPrint(
"@%#endif without corresponding %#if");
3206 else MessPreNesting(5);
3210 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3211 if ( AP.PreIfLevel <= 0 ) {
3212 MesPrint(
"@%#endif without corresponding %#if");
3229 int DoEndprocedure(UBYTE *s)
3232 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEPROCEDURE ) {
3237 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3238 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3239 AC.CurrentStream = CloseStream(AC.CurrentStream);
3242 if ( Procedures[NumProcedures].loadmode == 0 ) {
3243 M_free(Procedures[NumProcedures].p.buffer,
"procedures buffer");
3244 M_free(Procedures[NumProcedures].name,
"procedures name");
3246 }
while ( Procedures[NumProcedures].loadmode > 1 );
3258 AddToPreTypes(PRETYPEIF);
3259 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3260 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3261 condition = EvalPreIf(s);
3262 if ( condition < 0 )
return(-1);
3264 else condition = LOOKINGFORENDIF;
3265 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3266 int **ppp = &AP.PreIfStack;
3267 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3268 "PreIfLevels") )
return(-1);
3270 AP.PreIfStack[++AP.PreIfLevel] = condition;
3279 int DoIfdef(UBYTE *s,
int par)
3282 AddToPreTypes(PRETYPEIF);
3283 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3284 if ( AP.PreIfStack[AP.PreIfLevel] == EXECUTINGIF ) {
3285 while ( *s ==
' ' || *s ==
'\t' ) s++;
3286 if ( ( *s == 0 ) == ( par == 1 ) ) condition = LOOKINGFORELSE;
3287 else condition = EXECUTINGIF;
3289 else condition = LOOKINGFORENDIF;
3290 if ( AP.PreIfLevel+1 >= AP.MaxPreIfLevel ) {
3291 int **ppp = &AP.PreIfStack;
3292 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
3293 "PreIfLevels") )
return(-1);
3295 AP.PreIfStack[++AP.PreIfLevel] = condition;
3319 int DoInside(UBYTE *s)
3322 int numdol, error = 0;
3323 WORD *nb, newsize, i;
3325 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3326 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3327 if ( AP.PreInsideLevel != 0 ) {
3328 MesPrint(
"@Illegal nesting of %#inside/%#endinside instructions");
3341 AP.inside.numdollars = 0;
3343 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
3344 if ( *s == 0 )
break;
3346 MesPrint(
"@%#inside instruction can have only $ variables for parameters");
3351 while (chartype[*s] <= 1 ) s++;
3353 if ( ( numdol = GetDollar(name) ) < 0 ) {
3354 MesPrint(
"@%#inside: $%s has not (yet) been defined",name);
3360 if ( AP.inside.numdollars >= AP.inside.size ) {
3361 if ( AP.inside.buffer == 0 ) newsize = 20;
3362 else newsize = 2*AP.inside.size;
3363 nb = (WORD *)Malloc1(newsize*
sizeof(WORD),
"insidebuffer");
3364 if ( AP.inside.buffer ) {
3365 for ( i = 0; i < AP.inside.size; i++ ) nb[i] = AP.inside.buffer[i];
3366 M_free(AP.inside.buffer,
"insidebuffer");
3368 AP.inside.buffer = nb;
3369 AP.inside.size = newsize;
3371 AP.inside.buffer[AP.inside.numdollars++] = numdol;
3378 AP.inside.oldcompiletype = AC.compiletype;
3379 AP.inside.oldparallelflag = AC.mparallelflag;
3380 AP.inside.oldnumpotmoddollars = NumPotModdollars;
3381 AP.inside.oldcbuf = AC.cbufnum;
3382 AP.inside.oldrbuf = AM.rbufnum;
3383 AP.inside.oldcnumlhs = AR.Cnumlhs,
3384 AddToPreTypes(PRETYPEINSIDE);
3385 AP.PreInsideLevel = 1;
3386 AC.cbufnum = AP.inside.inscbuf;
3387 AM.rbufnum = AP.inside.inscbuf;
3390 AC.mparallelflag = PARALLELFLAG;
3399 PF_StoreInsideInfo();
3400 AC.RhsExprInModuleFlag = 0;
3401 NumPotModdollars = 0;
3402 AC.numpfirstnum = 0;
3412 int DoEndInside(UBYTE *s)
3415 WORD numdol, *oldworkpointer = AT.WorkPointer, *term, *t, j, i;
3417 WORD oldbracketon = AR.BracketOn;
3418 WORD *oldcompresspointer = AR.CompressPointer;
3419 int oldmultithreaded = AS.MultiThreaded;
3426 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3427 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3428 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPEINSIDE ) {
3429 if ( AP.PreInsideLevel != 1 ) MesPrint(
"@%#endinside without corresponding %#inside");
3430 else MessPreNesting(11);
3434 if ( AP.PreInsideLevel != 1 ) {
3435 MesPrint(
"@%#endinside without corresponding %#inside");
3438 if ( AP.PreContinuation ) {
3439 MesPrint(
"@%#endinside: previous statement not terminated.");
3442 AC.compiletype = AP.inside.oldcompiletype;
3443 AR.Cnumlhs = cbuf[AM.rbufnum].numlhs;
3450 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
3453 AS.MultiThreaded = 0;
3455 if ( AR.CompressPointer == 0 ) AR.CompressPointer = AR.CompressBuffer;
3456 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3460 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3461 numdol = AP.inside.buffer[i];
3462 nd = d = Dollars + numdol;
3463 if ( d->type != DOLZERO ) {
3464 if ( d->type != DOLTERMS ) nd = DolToTerms(BHEAD numdol);
3468 AR.MaxDum = AM.IndDum;
3470 t = oldworkpointer; j = *term;
3473 AN.IndDum = AM.IndDum;
3474 AR.CurDum = ReNumber(BHEAD term);
3475 if (
Generator(BHEAD oldworkpointer,0) ) {
3476 MesPrint(
"@Called from %#endinside");
3477 MesPrint(
"@Evaluating variable $%s",DOLLARNAME(Dollars,numdol));
3481 AT.WorkPointer = oldworkpointer;
3482 CleanDollarFactors(d);
3483 if ( d->where ) { M_free(d->where,
"dollar contents"); d->where = 0; }
3484 EndSort(BHEAD (WORD *)((VOID *)(&(d->where))),2);
3486 term = d->where;
while ( *term ) term += *term;
3487 d->size = term - d->where;
3488 if ( nd != d ) M_free(nd,
"Copy of dollar variable");
3489 if ( d->where[0] == 0 ) {
3490 M_free(d->where,
"dollar contents"); d->where = 0;
3497 if ( AC.RhsExprInModuleFlag ) {
3502 for ( i = 0; i < AP.inside.numdollars; i++ ) {
3510 if ( NumPotModdollars > 0 ) {
3512 if ( error )
goto cleanup;
3514 if ( AC.numpfirstnum > 0 ) {
3516 if ( error )
goto cleanup;
3521 f = AR.infile; AR.infile = AR.outfile; AR.outfile = f;
3522 AC.cbufnum = AP.inside.oldcbuf;
3523 AM.rbufnum = AP.inside.oldrbuf;
3524 AR.Cnumlhs = AP.inside.oldcnumlhs;
3525 AR.BracketOn = oldbracketon;
3526 AP.PreInsideLevel = 0;
3527 AR.CompressPointer = oldcompresspointer;
3528 AS.MultiThreaded = oldmultithreaded;
3529 AC.mparallelflag = AP.inside.oldparallelflag;
3530 NumPotModdollars = AP.inside.oldnumpotmoddollars;
3533 PF_RestoreInsideInfo();
3534 if ( error )
return error;
3544 int DoMessage(UBYTE *s)
3546 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3547 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3548 while ( *s ==
' ' || *s ==
'\t' ) s++;
3549 MesPrint(
"~~~%s",s);
3558 int DoPipe(UBYTE *s)
3563 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3564 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3567 while ( *s ==
' ' || *s ==
'\t' ) s++;
3568 if ( OpenStream(s,PIPESTREAM,0,PRENOACTION) == 0 )
return(-1);
3571 Error0(
"Pipes not implemented on this computer/system");
3581 int DoPrcExtension(UBYTE *s)
3584 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3585 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3586 while ( *s ==
' ' || *s ==
'\t' ) s++;
3587 if ( *s == 0 || *s ==
'\n' ) {
3588 MesPrint(
"@No valid procedure extension specified");
3591 if ( FG.cTable[*s] != 0 ) {
3592 MesPrint(
"@Procedure extension should be a string starting with an alphabetic character. No whitespace.");
3596 while ( *s && *s !=
'\n' && *s !=
' ' && *s !=
'\t' ) s++;
3598 while ( *s ==
' ' || *s ==
'\t' ) s++;
3599 if ( *s != 0 && *s !=
'\n' ) {
3600 MesPrint(
"@Too many parameters in ProcedureExtension instruction");
3604 if ( AP.procedureExtension ) M_free(AP.procedureExtension,
"ProcedureExtension");
3605 AP.procedureExtension = strDup1(t,
"ProcedureExtension");
3615 int DoPreOut(UBYTE *s)
3617 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3618 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3619 if ( tolower(*s) ==
'o' ) {
3620 if ( tolower(s[1]) ==
'n' && s[2] == 0 ) {
3624 if ( tolower(s[1]) ==
'f' && tolower(s[2]) ==
'f' && s[3] == 0 ) {
3629 MesPrint(
"@Illegal option in PreOut instruction");
3638 int DoPrePrintTimes(UBYTE *s)
3641 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3642 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3655 int DoPreAppend(UBYTE *s)
3659 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3660 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3661 if ( AP.preError )
return(0);
3662 while ( *s ==
' ' || *s ==
'\t' ) s++;
3669 while ( *s && *s !=
'>' ) {
3670 if ( *s ==
'\\' ) s++;
3674 MesPrint(
"@Improper termination of filename");
3679 if ( *name ) { GetAppendChannel((
char *)name); }
3684 MesPrint(
"@Proper syntax is: %#append <filename>");
3698 int DoPreCreate(UBYTE *s)
3702 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3703 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3704 if ( AP.preError )
return(0);
3705 while ( *s ==
' ' || *s ==
'\t' ) s++;
3712 while ( *s && *s !=
'>' ) {
3713 if ( *s ==
'\\' ) s++;
3717 MesPrint(
"@Improper termination of filename");
3722 if ( *name ) { GetChannel((
char *)name); }
3727 MesPrint(
"@Proper syntax is: %#create <filename>");
3738 int DoPreRemove(UBYTE *s)
3741 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3742 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3743 if ( AP.preError )
return(0);
3744 while ( *s ==
' ' || *s ==
'\t' ) s++;
3745 if ( *s ==
'<' ) { s++; }
3747 MesPrint(
"@Proper syntax is: %#remove <filename>");
3751 while ( *s && *s !=
'>' ) {
3752 if ( *s ==
'\\' ) s++;
3756 MesPrint(
"@Improper filename");
3761 CloseChannel((
char *)name);
3762 remove((
char *)name);
3771 int DoPreClose(UBYTE *s)
3774 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3775 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3776 if ( AP.preError )
return(0);
3777 while ( *s ==
' ' || *s ==
'\t' ) s++;
3778 if ( *s ==
'<' ) { s++; }
3780 MesPrint(
"@Proper syntax is: %#close <filename>");
3784 while ( *s && *s !=
'>' ) {
3785 if ( *s ==
'\\' ) s++;
3789 MesPrint(
"@Improper filename");
3794 return(CloseChannel((
char *)name));
3815 int DoPreWrite(UBYTE *s)
3819 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
3820 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3821 if ( AP.preError )
return(0);
3824 if ( PF.me != MASTER )
return 0;
3827 h.oldsilent = AM.silent;
3828 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
3829 h.newhandle = h.oldhandle = AC.LogHandle;
3830 h.oldprinttype = AO.PrintType;
3832 while ( *s ==
' ' || *s ==
'\t' ) s++;
3836 if( (s=defineChannel(s,&h))==0 )
return(-1);
3838 return(writeToChannel(WRITEOUT,s,&h));
3856 int DoProcedure(UBYTE *s)
3861 if ( ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
3862 || ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF ) ) {
3863 if ( PreSkip((UBYTE *)
"procedure",(UBYTE *)
"endprocedure",1) )
return(-1);
3866 p = (
PROCEDURE *)FromList(&AP.ProcList);
3867 if ( PreLoad(&(p->p),(UBYTE *)
"procedure",(UBYTE *)
"endprocedure" 3868 ,1,(
char *)
"procedure") )
return(-1);
3871 s = p->p.buffer + 10;
3872 while ( *s ==
' ' || *s == LINEFEED ) s++;
3873 if ( chartype[*s] ) {
3874 MesPrint(
"@Illegal name for procedure");
3878 while ( chartype[*s] == 0 || chartype[*s] == 1 ) s++;
3880 p->name = strDup1(p->name,
"procedure");
3885 for ( i = NumProcedures-2; i >= 0; i-- ) {
3886 if ( StrCmp(Procedures[i].name,p->name) == 0 ) {
3887 Error1(
"Multiple occurrence of procedure name ",p->name);
3898 int DoPreBreak(UBYTE *s)
3901 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3902 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3903 if ( AP.PreSwitchLevel <= 0 )
3904 MesPrint(
"@Break without corresponding Switch");
3905 else MessPreNesting(7);
3908 if ( AP.PreSwitchLevel <= 0 ) {
3909 MesPrint(
"@Break without corresponding Switch");
3912 if ( AP.PreSwitchModes[AP.PreSwitchLevel] == EXECUTINGPRESWITCH )
3913 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
3922 int DoPreCase(UBYTE *s)
3925 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3926 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3927 if ( AP.PreSwitchLevel <= 0 )
3928 MesPrint(
"@Case without corresponding Switch");
3929 else MessPreNesting(8);
3932 if ( AP.PreSwitchLevel <= 0 ) {
3933 MesPrint(
"@Case without corresponding Switch");
3936 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
3940 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
3941 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
3942 if ( s[-2] ==
'\\' ) s--;
3945 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
3949 s = AP.PreSwitchStrings[AP.PreSwitchLevel];
3950 while ( *t == *s && *t ) { s++; t++; }
3951 if ( *t || *s )
return(0);
3952 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
3961 int DoPreDefault(UBYTE *s)
3964 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3965 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3966 if ( AP.PreSwitchLevel <= 0 )
3967 MesPrint(
"@Default without corresponding Switch");
3968 else MessPreNesting(9);
3971 if ( AP.PreSwitchLevel <= 0 ) {
3972 MesPrint(
"@Default without corresponding Switch");
3975 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != SEARCHINGPRECASE )
return(0);
3976 AP.PreSwitchModes[AP.PreSwitchLevel] = EXECUTINGPRESWITCH;
3985 int DoPreEndSwitch(UBYTE *s)
3988 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
3989 if ( AP.PreTypes[AP.NumPreTypes] != PRETYPESWITCH ) {
3990 if ( AP.PreSwitchLevel <= 0 )
3991 MesPrint(
"@EndSwitch without corresponding Switch");
3992 else MessPreNesting(10);
3996 if ( AP.PreSwitchLevel <= 0 ) {
3997 MesPrint(
"@EndSwitch without corresponding Switch");
4000 M_free(AP.PreSwitchStrings[AP.PreSwitchLevel--],
"pre switch string");
4012 int DoPreSwitch(UBYTE *s)
4014 UBYTE *t, *switchstring, **newstrings;
4015 int newnum, i, *newmodes;
4016 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4019 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
4020 while ( s > t && ( s[-1] ==
' ' || s[-1] ==
'\t' ) && s[-2] !=
'\\' ) {
4021 if ( s[-2] ==
'\\' ) s--;
4024 if ( *t ==
'"' && s > t+1 && s[-1] ==
'"' && s[-2] !=
'\\' ) {
4028 switchstring = (UBYTE *)Malloc1((s-t)+1,
"case string");
4031 if ( *t ==
'\\' ) t++;
4035 if ( AP.PreSwitchLevel >= AP.NumPreSwitchStrings ) {
4036 newnum = 2*AP.NumPreSwitchStrings;
4037 newstrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*(newnum+1),
"case strings");
4038 newmodes = (
int *)Malloc1(
sizeof(
int)*(newnum+1),
"case strings");
4039 for ( i = 0; i < AP.NumPreSwitchStrings; i++ )
4040 newstrings[i] = AP.PreSwitchStrings[i];
4041 M_free(AP.PreSwitchStrings,
"AP.PreSwitchStrings");
4042 for ( i = 0; i <= AP.NumPreSwitchStrings; i++ )
4043 newmodes[i] = AP.PreSwitchModes[i];
4044 M_free(AP.PreSwitchModes,
"AP.PreSwitchModes");
4045 AP.PreSwitchStrings = newstrings;
4046 AP.PreSwitchModes = newmodes;
4047 AP.NumPreSwitchStrings = newnum;
4049 AP.PreSwitchStrings[++AP.PreSwitchLevel] = switchstring;
4050 if ( ( AP.PreSwitchLevel > 1 )
4051 && ( AP.PreSwitchModes[AP.PreSwitchLevel-1] != EXECUTINGPRESWITCH ) )
4052 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPREENDSWITCH;
4054 AP.PreSwitchModes[AP.PreSwitchLevel] = SEARCHINGPRECASE;
4055 AddToPreTypes(PRETYPESWITCH);
4066 int DoPreShow(UBYTE *s)
4070 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4071 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4072 while ( *s ==
' ' || *s ==
'\t' ) s++;
4074 MesPrint(
"%#The preprocessor variables:");
4075 for ( i = 0; i < NumPre; i++ ) {
4076 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4081 name = s;
while ( *s && *s !=
' ' && *s !=
'\t' && *s !=
',' ) s++;
4083 for ( i = 0; i < NumPre; i++ ) {
4084 if ( StrCmp(PreVar[i].name,name) == 0 )
4085 MesPrint(
"%d: %s = \"%s\"",i,PreVar[i].name,PreVar[i].value);
4088 while ( *s ==
' ' || *s ==
'\t' ) s++;
4099 int DoSystem(UBYTE *s)
4101 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
4102 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
4103 if ( AP.preError )
return(0);
4106 while ( *s ==
' ' || *s ==
'\t' ) s++;
4107 if ( system((
char *)s) ) {
4108 MesPrint(
"@System call returned with error condition");
4113 Error0(
"External programs not implemented on this computer/system");
4126 int PreLoad(
PRELOAD *p, UBYTE *start, UBYTE *stop,
int mode,
char *message)
4128 UBYTE *s, *t, *top, *newbuffer, c;
4129 LONG i, ppsize, linenum = AC.CurrentStream->linenumber;
4130 int size1, size2, level, com=0, last=1, strng = 0;
4132 p->buffer = (UBYTE *)Malloc1(p->size+1,message);
4133 top = p->buffer + p->size - 2;
4134 t = p->buffer; *t++ =
'#';
4135 s = start; size1 = size2 = 0;
4136 while ( *s ) { s++; size1++; }
4137 s = stop;
while ( *s ) { s++; size2++; }
4138 s = AP.preStart;
while ( *s ) *t++ = *s++; *t++ = LINEFEED;
4143 if ( c == ENDOFINPUT ) {
4144 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4147 if ( c == AP.ComChar && last == 1 ) com = 1;
4148 if ( c == LINEFEED ) { last = 1; com = 0; }
4151 if ( ( c ==
'"' ) && ( com == 0 ) ) { strng ^= 1; }
4153 if ( ( c ==
'#' ) && ( com == 0 ) ) i = 0;
4157 ppsize = t - p->buffer;
4159 newbuffer = (UBYTE *)Malloc1(p->size,message);
4160 t = newbuffer; s = p->buffer;
4161 while ( --ppsize >= 0 ) *t++ = *s++;
4162 M_free(p->buffer,
"loading do loop");
4163 p->buffer = newbuffer;
4164 top = p->buffer + p->size - 2;
4168 if ( ( i == size2 ) && ( com == 0 ) ) {
4170 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4171 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4173 if ( level <= 0 )
break;
4174 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4175 *t++ = LINEFEED; *t = 0; last = 1;
4178 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4180 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4188 if ( i == 1 && t[-2] == LINEFEED ) {
4189 if ( c ==
'-' ) AC.NoShowInput = 1;
4190 else if ( c ==
'+' ) AC.NoShowInput = 0;
4207 #define SKIPBUFSIZE 20 4209 int PreSkip(UBYTE *start, UBYTE *stop,
int mode)
4211 UBYTE *s, *t, buffer[SKIPBUFSIZE+2], c;
4212 LONG i, linenum = AC.CurrentStream->linenumber;
4213 int size1, size2, level, com=0, last=1;
4215 t = buffer; *t++ =
'#';
4216 s = start; size1 = size2 = 0;
4217 while ( *s ) { s++; size1++; }
4218 s = stop;
while ( *s ) { s++; size2++; }
4223 if ( c == ENDOFINPUT ) {
4224 MesPrint(
"@Missing %#%s, Should match line %l",stop,linenum);
4227 if ( c == AP.ComChar && last == 1 ) com = 1;
4228 if ( c == LINEFEED ) { last = 1; com = 0; i = 0; t = buffer; }
4230 if ( ( c ==
'#' ) && ( com == 0 ) ) { i = 0; t = buffer; }
4233 if ( i < SKIPBUFSIZE ) *t++ = c;
4234 if ( ( i == size2 ) && ( com == 0 ) ) {
4236 if ( StrICmp(t-size2,(UBYTE *)(stop)) == 0 ) {
4237 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4240 pushbackchar = LINEFEED;
4243 if ( c == ENDOFINPUT ) Error1(
"Missing #",stop);
4247 if ( ( i == size1 ) && mode && ( com == 0 ) ) {
4249 if ( StrICmp(t-size1,(UBYTE *)(start)) == 0 ) {
4250 while ( ( c = GetInput() ) != LINEFEED && c != ENDOFINPUT ) {}
4267 AP.MaxPreIfLevel = 2;
4268 ppp = &AP.PreIfStack;
4269 if ( DoubleList((VOID ***)ppp,&AP.MaxPreIfLevel,
sizeof(
int),
4270 "PreIfLevels") ) Terminate(-1);
4271 AP.PreIfLevel = 0; AP.PreIfStack[0] = EXECUTINGIF;
4273 AP.NumPreSwitchStrings = 10;
4274 AP.PreSwitchStrings = (UBYTE **)Malloc1(
sizeof(UBYTE *)*
4275 (AP.NumPreSwitchStrings+1),
"case strings");
4276 AP.PreSwitchModes = (
int *)Malloc1(
sizeof(
int)*
4277 (AP.NumPreSwitchStrings+1),
"case strings");
4278 AP.PreSwitchModes[0] = EXECUTINGPRESWITCH;
4279 AP.PreSwitchLevel = 0;
4292 int EvalPreIf(UBYTE *s)
4300 if ( ( u = PreIfEval(s,&val) ) == 0 )
return(-1);
4302 MesPrint(
"@Unmatched parentheses in condition");
4305 if ( val )
return(EXECUTINGIF);
4306 else return(LOOKINGFORELSE);
4327 UBYTE *PreIfEval(UBYTE *s,
int *value)
4329 int orlevel = 0, andlevel = 0, eqlevel = 0, cmplevel = 0;
4332 int ortype, orval, cmptype, cmpval, eqtype, eqval, andtype, andval;
4333 UBYTE *t, *eqt, *cmpt, c;
4335 ortype = orval = cmptype = cmpval = eqtype = eqval = andtype = andval = 0;
4339 while ( *s !=
')' ) {
4340 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4342 s = pParseObject(s,&type,&val2);
4343 if ( s == 0 )
return(0);
4347 while ( c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' ) {
4350 if ( *t ==
'"' ) t++;
4353 if ( *s !=
'|' )
goto illoper;
4357 if ( type == 0 || cmptype == 0 )
goto illobject;
4358 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4363 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4368 if ( andtype != 0 || type != 0 )
goto illobject;
4373 if ( ortype != 0 || type != 0 )
goto illobject;
4385 if ( *s !=
'&' )
goto illoper;
4388 if ( type == 0 || cmptype == 0 )
goto illobject;
4389 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4394 val = PreEq(type,val,t,eqtype,eqval,eqt,eqop);
4399 if ( andtype != 0 || type != 0 )
goto illobject;
4408 if ( eqlevel )
goto illorder;
4410 if ( type == 0 || cmptype == 0 )
goto illobject;
4411 val = PreCmp(type,val,t,cmptype,cmpval,cmpt,cmpop);
4415 if ( c ==
'!' && *s !=
'=' )
goto illoper;
4416 if ( *s ==
'=' ) s++;
4417 if ( c ==
'!' ) eqop = 1;
4419 eqlevel = 1; eqt = t; eqval = val; eqtype = type;
4423 if ( cmplevel )
goto illorder;
4424 if ( c ==
'<' ) cmpop = -1;
4426 cmplevel = 1; cmpt = t; cmpval = val; cmptype = type;
4429 if ( *s ==
'~' ) { s++; cmpop *= 4; }
4432 else if ( *s ==
'~' ) { s++; cmpop *= 3; }
4440 MesPrint(
"@illegal order of operators");
4443 MesPrint(
"@illegal object for this operator");
4446 MesPrint(
"@illegal operator");
4455 int PreCmp(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int cmpop)
4457 if ( type == 2 || type2 == 2 || cmpop < -2 || cmpop > 2 ) {
4458 if ( cmpop < 0 && cmpop > -3 ) cmpop -= 2;
4459 if ( cmpop > 0 && cmpop < 3 ) cmpop += 2;
4460 if ( cmpop == 3 ) val = StrCmp(t2,t) > 0;
4461 else if ( cmpop == 4 ) val = StrCmp(t2,t) >= 0;
4462 else if ( cmpop == -3 ) val = StrCmp(t2,t) < 0;
4463 else if ( cmpop == -4 ) val = StrCmp(t2,t) <= 0;
4466 if ( cmpop == 1 ) val = ( val2 > val );
4467 else if ( cmpop == 2 ) val = ( val2 >= val );
4468 else if ( cmpop == -1 ) val = ( val2 < val );
4469 else if ( cmpop == -2 ) val = ( val2 <= val );
4479 int PreEq(
int type,
int val, UBYTE *t,
int type2,
int val2, UBYTE *t2,
int eqop)
4482 if ( type == 2 || type2 == 2 ) {
4483 if ( type != 2 ) { NumToStr(str,val ); t = str; }
4484 if ( type2 != 2 ) { NumToStr(str,val2); t2 = str; }
4485 if ( eqop == 1 ) val = StrCmp(t,t2) != 0;
4486 else val = StrCmp(t,t2) == 0;
4489 if ( eqop ) val = val != val2;
4490 else val = val == val2;
4508 UBYTE *pParseObject(UBYTE *s,
int *type, LONG *val2)
4513 while ( *s ==
' ' || *s ==
'\t' ) s++;
4516 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4517 s = PreIfEval(s,&val);
4522 else if ( *s ==
'$' && s[1] ==
'(' ) {
4524 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4525 s = PreIfDollarEval(s,&val);
4526 *type = 0; *val2 = val;
4531 MesPrint(
"@illegal end of condition");
4536 while ( *s && *s !=
'"' ) {
4537 if ( *s ==
'\\' ) s++;
4540 if ( *s == 0 )
goto illend;
4545 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
4549 t = s; sign = 1; x = 0;
4550 if ( chartype[*t] == 0 ) {
4551 do { t++; }
while ( chartype[*t] <= 1 );
4554 if ( StrICmp(s,(UBYTE *)
"termsin") == 0 ) {
4556 WORD numdol, numexp;
4558 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4560 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4562 if ( ( numdol = GetDollar(t) ) > 0 ) {
4564 x = TermsInDollar(numdol);
4567 MesPrint(
"@$%s has not (yet) been defined",t);
4575 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4576 MesPrint(
"@%s has not (yet) been defined",t);
4582 x = TermsInExpression(numexp);
4585 while ( *tt ==
' ' || *tt ==
'\t' 4586 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4588 MesPrint(
"@Improper use of terms($var) or terms(expr)");
4596 else if ( StrICmp(s,(UBYTE *)
"exists") == 0 ) {
4598 WORD numdol, numexp;
4600 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4602 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4604 if ( ( numdol = GetDollar(t) ) >= 0 ) { x = 1; }
4611 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) { x = 0; }
4615 while ( *tt ==
' ' || *tt ==
'\t' 4616 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4618 MesPrint(
"@Improper use of exists($var) or exists(expr)");
4626 else if ( StrICmp(s,(UBYTE *)
"isnumerical") == 0 ) {
4629 WORD numdol, numexp;
4631 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4633 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4635 if ( ( numdol = GetDollar(t) ) < 0 ) {
4636 MesPrint(
"@$ variable in isnumerical(%s) does not exist",t);
4639 x = DolToLong(BHEAD numdol);
4640 if ( AN.ErrorInDollar ) {
4643 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
4644 if ( d->where[0] == 0 ) x = 1;
4645 else if ( d->where[d->where[0]] == 0 ) {
4646 if ( ABS(d->where[d->where[0]-1]) == d->where[0]-1 )
4657 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4658 MesPrint(
"@expression in isnumerical(%s) does not exist",t);
4661 x = TermsInExpression(numexp);
4662 if ( x != 1 ) x = 0;
4664 WORD *term = AT.WorkPointer;
4665 if ( GetFirstTerm(term,numexp) < 0 ) {
4666 MesPrint(
"@error reading expression in isnumerical(%s)",t);
4669 if ( *term == ABS(term[*term-1])+1 ) x = 1;
4674 while ( *tt ==
' ' || *tt ==
'\t' 4675 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4677 MesPrint(
"@Improper use of isnumerical($var) or numerical(expr)");
4685 else if ( StrICmp(s,(UBYTE *)(
"maxpowerof")) == 0 ) {
4690 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4693 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4694 MesPrint(
"@%s has not (yet) been defined",t);
4698 else if ( stype != CSYMBOL ) {
4699 MesPrint(
"@%s should be a symbol",t);
4705 x = symbols[numsym].maxpower;
4707 while ( *tt ==
' ' || *tt ==
'\t' 4708 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4710 MesPrint(
"@Improper use of maxpowerof(symbol)");
4718 else if ( StrICmp(s,(UBYTE *)(
"minpowerof")) == 0 ) {
4723 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4726 if ( ( stype = GetName(AC.varnames,t,&numsym,NOAUTO) ) == NAMENOTFOUND ) {
4727 MesPrint(
"@%s has not (yet) been defined",t);
4731 else if ( stype != CSYMBOL ) {
4732 MesPrint(
"@%s should be a symbol",t);
4738 x = symbols[numsym].minpower;
4740 while ( *tt ==
' ' || *tt ==
'\t' 4741 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4743 MesPrint(
"@Improper use of minpowerof(symbol)");
4751 else if ( StrICmp(s,(UBYTE *)
"isfactorized") == 0 ) {
4753 WORD numdol, numexp;
4755 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4757 t++; tt = t;
while (chartype[*tt] <= 1 ) tt++;
4759 if ( ( numdol = GetDollar(t) ) > 0 ) {
4760 if ( Dollars[numdol].factors != 0 ) x = 1;
4764 MesPrint(
"@ %s should be the name of an expression or a $ variable",t-1);
4772 if ( GetName(AC.exprnames,t,&numexp,NOAUTO) == NAMENOTFOUND ) {
4773 MesPrint(
"@ %s should be the name of an expression or a $ variable",t);
4777 if ( ( Expressions[numexp].vflags & ISFACTORIZED ) != 0 ) x = 1;
4782 while ( *tt ==
' ' || *tt ==
'\t' 4783 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4785 MesPrint(
"@Improper use of isfactorized($var) or isfactorized(expr)");
4793 else if ( StrICmp(s,(UBYTE *)
"isdefined") == 0 ) {
4796 while ( *t ==
' ' || *t ==
'\t' || *t ==
'\n' || *t ==
'\r' ) t++;
4799 if ( GetPreVar(t,WITHOUTERROR) != 0 ) x = 1;
4802 while ( *tt ==
' ' || *tt ==
'\t' 4803 || *tt ==
'\n' || *tt ==
'\r' ) tt++;
4805 MesPrint(
"@Improper use of isdefined(var)");
4815 else if ( *t ==
'=' || *t ==
'<' || *t ==
'>' || *t ==
'!' 4816 || *t ==
')' || *t ==
' ' || *t ==
'\t' || *t == 0 || *t ==
'\n' ) {
4822 MesPrint(
"@Illegal use of string in preprocessor condition: %s",s);
4826 while ( *t ==
'-' || *t ==
'+' || *t ==
' ' || *t ==
'\t' ) {
4827 if ( *t ==
'-' ) sign = -sign;
4830 while ( chartype[*t] == 1 ) { x = 10*x + *t++ -
'0'; }
4831 while ( *t ==
' ' || *t ==
'\t' ) t++;
4832 if ( chartype[*t] == 8 || *t ==
')' || *t ==
'=' || *t == 0 ) {
4833 *val2 = sign > 0 ? x: -x;
4837 while ( chartype[*t] != 8 && *t !=
')' && *t !=
'=' && *t ) t++;
4838 while ( ( t > s ) && ( t[-1] ==
' ' || t[-1] ==
'\t' ) ) t--;
4859 UBYTE *buff, *s = 0, *t, *newb, c;
4860 int size, i, n, parlevel = 0, bralevel = 0;
4866 if ( size == 0 ) size = 72;
4868 if ( ( newb = (UBYTE *)Malloc1(size+2,
"{}") ) == 0 )
return(0);
4874 M_free(buff,
"pre calc buffer");
4882 Error0(
"Unmatched {}");
4883 M_free(buff,
"precalc buffer");
4886 else if ( c ==
'{' ) { bralevel++; }
4887 else if ( c ==
'}' ) {
4888 if ( --bralevel < 0 ) { *s++ = c; *s = 0;
break; }
4890 else if ( c ==
'(' ) { parlevel++; }
4891 else if ( c ==
')' ) {
4892 if ( --parlevel < 0 ) { *s++ = c; *s = 0;
goto setstring; }
4894 else if ( chartype[c] != 1 && chartype[c] != 5
4895 && chartype[c] != 6 && c !=
'!' && c !=
'&' 4896 && c !=
'|' && c !=
'\\' ) { *s++ = c; *s = 0;
goto setstring; }
4898 if ( parlevel > 0 )
goto setstring;
4904 if ( PreEval(buff+1,&answer) == 0 )
goto setstring;
4907 if ( answer < 0 ) { *s++ =
'-'; answer = -answer; }
4910 *--t = ( answer % 10 ) +
'0';
4913 }
while ( answer > 0 );
4921 if ( OpenStream(buff,PRECALCSTREAM,0,PRENOACTION) == 0 )
return(0);
4933 UBYTE *PreEval(UBYTE *s, LONG *x)
4936 int tobemultiplied, tobeadded = 1, expsign, i;
4939 while ( *s ==
' ' || *s ==
'\t' ) s++;
4941 if ( *s ==
'+' || *s ==
'-' ) {
4942 if ( *s ==
'-' ) tobeadded = -1;
4945 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
4946 if ( *s ==
'-' ) tobeadded = -tobeadded;
4952 while ( *s ==
' ' || *s ==
'\t' ) s++;
4953 if ( *s <= '9' && *s >=
'0' ) {
4956 else if ( *s ==
'(' || *s ==
'{' ) {
4957 if ( ( t = PreEval(s+1,&y) ) == 0 )
return(0);
4961 while ( *s ==
' ' || *s ==
'\t' ) s++;
4963 while ( *s ==
'^' || *s ==
'!' ) {
4965 if ( s[-1] ==
'!' ) {
4966 while ( *s ==
' ' || *s ==
'\t' ) s++;
4968 MesPrint(
"@Negative value in preprocessor factorial: %l",y);
4971 else if ( y == 0 ) y = 1;
4974 while ( z > 0 ) { y = y*z; z--; }
4978 else if ( *s ==
'%' ) {
4980 while ( *s ==
' ' || *s ==
'\t' ) s++;
4983 MesPrint(
"@Illegal value in preprocessor logarithm: %l",z);
4987 while ( z ) { y++; z >>= 1; }
4990 else if ( *s ==
'/' ) {
4993 while ( *s ==
' ' || *s ==
'\t' ) s++;
4996 MesPrint(
"@Illegal value in preprocessor square root: %l",z);
5002 while ( zz ) { yy++; zz >>= 1; }
5003 zz = z >> (yy/2); i = 10; y = 0;
5005 yy = zz/2 + z/(2*zz); i--;
5006 if ( y == yy )
break;
5008 }
while ( y != yy && i > 0 );
5009 while ( y*y < z ) y++;
5010 while ( y*y > z ) y--;
5012 else if ( z >= 4 ) y = 2;
5013 else if ( z == 0 ) y = 0;
5017 while ( *s ==
' ' || *s ==
'\t' ) s++;
5018 while ( *s ==
'-' || *s ==
'+' || *s ==
' ' || *s ==
'\t' ) {
5019 if ( *s ==
'-' ) expsign = -expsign;
5021 if ( *s <= '9' && *s >=
'0' ) {
5024 else if ( *s ==
'(' || *s ==
'{' ) {
5025 if ( ( t = PreEval(s+1,&z) ) == 0 )
return(0);
5029 while ( *s ==
' ' || *s ==
'\t' ) s++;
5032 if ( tobemultiplied == 0 ) {
5033 if ( expsign < 0 ) a = 1/y;
5037 if ( tobemultiplied > 2 && expsign != 1 ) {
5038 MesPrint(
"&Incorrect use of ^ with & or |. Use brackets!");
5041 tobemultiplied *= expsign;
5042 if ( tobemultiplied == 1 ) a *= y;
5043 else if ( tobemultiplied == 3 ) a &= y;
5044 else if ( tobemultiplied == 4 ) a |= y;
5046 if ( y == 0 || tobemultiplied == -2 ) {
5047 MesPrint(
"@Division by zero in preprocessor calculator");
5050 if ( tobemultiplied == 2 ) a %= y;
5054 if ( *s ==
'%' ) tobemultiplied = 2;
5055 else if ( *s ==
'*' ) tobemultiplied = 1;
5056 else if ( *s ==
'/' ) tobemultiplied = -1;
5057 else if ( *s ==
'&' ) tobemultiplied = 3;
5058 else if ( *s ==
'|' ) tobemultiplied = 4;
5060 if ( tobeadded >= 0 ) *x += a;
5062 if ( *s ==
')' || *s ==
'}' )
return(s+1);
5063 else if ( *s ==
'-' || *s ==
'+' ) { tobeadded = 1;
break; }
5077 void AddToPreTypes(
int type)
5079 if ( AP.NumPreTypes >= AP.MaxPreTypes ) {
5080 int i, *newlist = (
int *)Malloc1(
sizeof(
int)*(2*AP.MaxPreTypes+1)
5081 ,
"preprocessor type lists");
5082 for ( i = 0; i <= AP.MaxPreTypes; i++ ) newlist[i] = AP.PreTypes[i];
5083 M_free(AP.PreTypes,
"preprocessor type lists");
5084 AP.PreTypes = newlist;
5085 AP.MaxPreTypes = 2*AP.MaxPreTypes;
5087 AP.PreTypes[++AP.NumPreTypes] = type;
5095 void MessPreNesting(
int par)
5097 MesPrint(
"@(%d)Illegal nesting of %#if, %#do, %#procedure and/or %#switch",par);
5118 int DoPreAddSeparator(UBYTE *s)
5120 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5121 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5122 for(;*s !=
'\0';s++){
5123 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5130 set_set(*s,AC.separators);
5143 int DoPreRmSeparator(UBYTE *s)
5145 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5146 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5147 for(;*s !=
'\0';s++){
5148 while ( *s ==
' ' || *s ==
'\t' || *s ==
'"') s++;
5149 set_del(*s,AC.separators);
5160 int DoExternal(UBYTE *s)
5162 #ifdef WITHEXTERNALCHANNEL 5168 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5169 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5170 if ( AP.preError )
return(0);
5172 #ifdef WITHEXTERNALCHANNEL 5173 while ( *s ==
' ' || *s ==
'\t' ) s++;
5177 if ( chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5179 MesPrint(
"@Can't finde closing \"");
5181 case 0:
case 1:
continue;
5186 MesPrint(
"@Illegal name of preprocessor variable to store external channel");
5190 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5194 MesPrint(
"@Illegal external command");
5200 externalD=openExternalChannel(
5208 Error1(
"Can't start external program",s);
5215 NumToStr(buf,externalD);
5216 if (
PutPreVar(prevar,buf,0,1) < 0 )
return(-1);
5219 AX.currentExternalChannel=externalD;
5221 if(AX.currentPrompt!=0){
5222 if(setTerminatorForExternalChannel( (
char *)AX.currentPrompt)){
5223 MesPrint(
"@Prompt is too long");
5227 setKillModeForExternalChannel(AX.killSignal,AX.killWholeGroup);
5231 Error0(
"External channel: not implemented on this computer/system");
5242 int DoPrompt(UBYTE *s)
5244 #ifndef WITHEXTERNALCHANNEL 5247 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5248 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5250 #ifdef WITHEXTERNALCHANNEL 5251 while ( *s ==
' ' || *s ==
'\t' ) s++;
5252 if ( AX.currentPrompt )
5253 M_free(AX.currentPrompt,
"external channel prompt");
5255 AX.currentPrompt = (UBYTE *)strDup1((UBYTE *)
"",
"external channel prompt");
5257 AX.currentPrompt = strDup1(s,
"external channel prompt");
5258 if( setTerminatorForExternalChannel( (
char *)AX.currentPrompt) > 0 ){
5259 MesPrint(
"@Prompt is too long");
5265 Error0(
"External channel: not implemented on this computer/system");
5275 int DoSetExternal(UBYTE *s)
5277 #ifdef WITHEXTERNALCHANNEL 5282 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5283 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5284 if ( AP.preError )
return(0);
5286 #ifdef WITHEXTERNALCHANNEL 5287 while ( *s ==
' ' || *s ==
'\t' ) s++;
5288 while ( chartype[*s] == 1 ) { n = 10*n + *s++ -
'0'; }
5289 while ( *s ==
' ' || *s ==
'\t' ) s++;
5291 MesPrint(
"@setexternal: number expected");
5294 if(selectExternalChannel(n)<0){
5295 MesPrint(
"@setexternal: invalid number");
5298 AX.currentExternalChannel=n;
5301 Error0(
"External channel: not implemented on this computer/system");
5310 static FORM_INLINE UBYTE *pickupword(UBYTE *s)
5313 for(;*s>
' ';s++)
switch(*s){
5324 static inline int strINCmp(UBYTE *a, UBYTE *b,
int n)
5326 for(;n>0;n--)
if(tolower(*a++)!=tolower(*b++))
5332 #define KILLALL "killall" 5333 #define DAEMON "daemon" 5334 #define SHELL "shell" 5335 #define STDERR "stderr" 5337 #define TRUE_EXPR "true" 5338 #define FALSE_EXPR "false" 5339 #define NOSHELL "noshell" 5340 #define TERMINAL "terminal" 5345 int DoSetExternalAttr(UBYTE *s)
5347 #ifdef WITHEXTERNALCHANNEL 5353 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5354 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5355 if ( AP.preError )
return(0);
5357 #ifdef WITHEXTERNALCHANNEL 5360 while ( *s ==
' ' || *s ==
'\t' ) s++;
5361 s=pickupword(nam=s);
5363 while ( *s ==
' ' || *s ==
'\t' ) s++;
5365 MesPrint(
"@External channel:'=' expected instead of %s",s-1);
5369 while ( *s ==
' ' || *s ==
'\t' ) s++;
5376 while ( *s ==
' ' || *s ==
'\t' ) s++;
5377 if( (*s ==
',')||(*s ==
'\n')||(*s ==
';')||(*s ==
'\0') ){
5384 while ( *s ==
' ' || *s ==
'\t' ) s++;
5386 if(strINCmp((UBYTE *)SHELL,nam,lnam)==0){
5387 if(AX.shellname!=NULL)
5388 M_free(AX.shellname,
"external channel shellname");
5389 if(strINCmp((UBYTE *)NOSHELL,val,lval)==0)
5393 b=ch=AX.shellname=Malloc1(lval+1,
"external channel shellname");
5398 }
else if(strINCmp((UBYTE *)DAEMON,nam,lnam)==0){
5399 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5401 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5404 MesPrint(
"@External channel:true or false expected for %s",DAEMON);
5407 }
else if(strINCmp((UBYTE *)KILLALL,nam,lnam)==0){
5408 if(strINCmp((UBYTE *)TRUE_EXPR,val,lval)==0)
5409 AX.killWholeGroup = 1;
5410 else if(strINCmp((UBYTE *)FALSE_EXPR,val,lval)==0)
5411 AX.killWholeGroup = 0;
5413 MesPrint(
"@External channel: true or false expected for %s",KILLALL);
5416 }
else if(strINCmp((UBYTE *)KILL,nam,lnam)==0){
5419 if( *val>=
'0' && *val<=
'9' )
5420 n = 10*n + *val++ -
'0';
5422 MesPrint(
"@External channel: number expected for %s",KILL);
5426 }
else if(strINCmp((UBYTE *)STDERR,nam,lnam)==0){
5427 if( AX.stderrname != NULL ) {
5428 M_free(AX.stderrname,
"external channel stderrname");
5430 if(strINCmp((UBYTE *)TERMINAL,val,lval)==0)
5431 AX.stderrname = NULL;
5434 b=ch=AX.stderrname=Malloc1(lval+1,
"external channel stderrname");
5441 MesPrint(
"@External channel: unrecognized attribute",nam);
5444 }
while(*s++ ==
',');
5445 if( (*(s-1)>
' ')&&(*(s-1)!=
';') ){
5446 MesPrint(
"@External channel: syntax error: %s",s-1);
5451 Error0(
"External channel: not implemented on this computer/system");
5461 int DoRmExternal(UBYTE *s)
5463 #ifdef WITHEXTERNALCHANNEL 5468 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5469 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5470 if ( AP.preError )
return(0);
5472 #ifdef WITHEXTERNALCHANNEL 5473 while ( *s ==
' ' || *s ==
'\t' ) s++;
5474 if( chartype[*s] == 1 ){
5475 for(n=0; chartype[*s] == 1 ; s++) { n = 10*n + *s -
'0'; }
5476 while ( *s ==
' ' || *s ==
'\t' ) s++;
5479 MesPrint(
"@rmexternal: invalid number");
5484 closeAllExternalChannels();
5485 AX.currentExternalChannel=0;
5489 n=AX.currentExternalChannel;
5492 closeExternalChannel(n);
5494 if (n == AX.currentExternalChannel)
5495 AX.currentExternalChannel=0;
5498 Error0(
"External channel: not implemented on this computer/system");
5526 int DoFromExternal(UBYTE *s)
5528 #ifdef WITHEXTERNALCHANNEL 5531 int withNoList=AC.NoShowInput;
5532 int oldpreassignflag;
5536 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5537 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5538 if ( AP.preError )
return(0);
5539 #ifdef WITHEXTERNALCHANNEL 5543 while ( *s ==
' ' || *s ==
'\t' ) s++;
5545 if ( *s ==
'-' || *s ==
'+' ) {
5551 while ( *s ==
' ' || *s ==
'\t' ) s++;
5558 if ( *s==
'$' || chartype[*s] == 0 )
for(;*s !=
'"'; s++)
switch(chartype[*s]){
5560 MesPrint(
"@Can't finde closing \"");
5562 case 0:
case 1:
continue;
5567 MesPrint(
"@Illegal name to store output of external channel");
5571 for(s++; *s ==
' ' || *s ==
'\t'; s++);
5575 if( chartype[*s] == 1 ){
5576 for(lbuf=0; chartype[*s] == 1 ; s++) { lbuf = 10*lbuf + *s -
'0'; }
5577 while ( *s ==
' ' || *s ==
'\t' ) s++;
5579 if( (*s!=
'\0')||(lbuf<0) ){
5580 MesPrint(
"@Illegal buffer length in fromexternal");
5585 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5588 if(selectExternalChannel(AX.currentExternalChannel)){
5589 MesPrint(
"@No current external channel");
5600 buf=Malloc1( (lbuf=255)+1,
"Fromexternal");
5606 for(i=0;(cc=getcFromExtChannel())>0;i++){
5610 UBYTE *tmp=Malloc1( (lbuf*=2)+1,
"Fromexternal");
5611 for(j=0;j<i;j++)tmp[j]=buf[j];
5612 M_free(buf,
"Fromexternal");
5619 MesPrint(
"@No current external channel");
5627 buf=Malloc1(lbuf+1,
"Fromexternal");
5628 for(i=0; i<lbuf;i++){
5634 if( (cc=getcFromExtChannel())<1 )
5647 while(getcFromExtChannel()>0);
5649 MesPrint(
"@No current external channel");
5656 int oldNumPotModdollars = NumPotModdollars;
5658 WORD oldRhsExprInModuleFlag = AC.RhsExprInModuleFlag;
5659 AC.RhsExprInModuleFlag = 0;
5663 UBYTE *pbuf=Malloc1(StrLen(prevar)+1+lbuf+1,
"Fromexternal to dollar");
5666 while(*b!=
'\0'){*c++ = *b++;}
5669 while( (*c++=*b++)!=
'\0' );
5670 oldpreassignflag = AP.PreAssignFlag;
5671 AP.PreAssignFlag = 1;
5672 if ( ( cc = CompileStatement(pbuf) ) || ( cc = CatchDollar(0) ) ) {
5673 Error1(
"External channel: can't asign output to dollar variable ",prevar);
5675 AP.PreAssignFlag = oldpreassignflag;
5676 NumPotModdollars = oldNumPotModdollars;
5678 AC.RhsExprInModuleFlag = oldRhsExprInModuleFlag;
5680 M_free(pbuf,
"Fromexternal to dollar");
5685 M_free(buf,
"Fromexternal");
5686 if ( cc )
return(-1);
5690 if ( OpenStream(s,EXTERNALCHANNELSTREAM,0,PRENOACTION) == 0 )
return(-1);
5692 AC.NoShowInput = withNoList;
5696 Error0(
"External channel: not implemented on this computer/system");
5707 #ifdef WITHEXTERNALCHANNEL 5710 LONG WriteToExternalChannel(
int handle, UBYTE *buffer, LONG size)
5715 if(writeBufToExtChannel((
char*)buffer,size))
5721 int DoToExternal(UBYTE *s)
5723 #ifdef WITHEXTERNALCHANNEL 5725 LONG (*OldWrite)(
int handle, UBYTE *buffer, LONG size) = WriteFile;
5730 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
5731 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
5732 if ( AP.preError )
return(0);
5733 #ifdef WITHEXTERNALCHANNEL 5735 h.oldsilent=AM.silent;
5736 h.newlogonly = h.oldlogonly = AM.FileOnlyFlag;
5737 h.newhandle = h.oldhandle = AC.LogHandle;
5738 h.oldprinttype = AO.PrintType;
5740 WriteFile=&WriteToExternalChannel;
5742 while ( *s ==
' ' || *s ==
'\t' ) s++;
5744 if(AX.currentExternalChannel==0){
5745 MesPrint(
"@No current external channel");
5746 goto DoToExternalReady;
5749 if(getCurrentExternalChannel()!=AX.currentExternalChannel)
5750 selectExternalChannel(AX.currentExternalChannel);
5752 ret=writeToChannel(EXTERNALCHANNELOUT,s,&h);
5757 Error0(
"External channel: not implemented on this computer/system");
5768 UBYTE *defineChannel(UBYTE *s,
HANDLERS *h)
5777 while ( *s && *s !=
'>' ) {
5778 if ( *s ==
'\\' ) s++;
5782 MesPrint(
"@Improper termination of filename");
5788 h->newhandle = GetChannel((
char *)name);
5791 else if ( AC.LogHandle >= 0 ) {
5792 h->newhandle = AC.LogHandle;
5803 int writeToChannel(
int wtype, UBYTE *s,
HANDLERS *h)
5805 UBYTE *to, *fstring, *ss, *sss, *s1, c, c1;
5806 WORD num, number, nfac;
5807 UBYTE Out[MAXLINELENGTH+14], *stopper;
5813 while ( *s ==
',' || *s ==
' ' ) s++;
5815 MesPrint(
"@No format string present");
5818 s++; fstring = to = s;
5824 if ( *s ==
'\\' ) *to++ = *s++;
5826 else if ( *s ==
'"' ) *to++ = *s++;
5827 else { *to++ =
'\\'; *to++ = *s++; }
5829 else if ( *s ==
'"' )
break;
5833 MesPrint(
"@No closing \" in format string");
5837 if ( AC.LineLength > 20 && AC.LineLength <= MAXLINELENGTH ) stopper = Out + AC.LineLength;
5838 else stopper = Out + MAXLINELENGTH;
5845 AC.LogHandle = h->newhandle;
5846 AM.FileOnlyFlag = h->newlogonly;
5847 if ( h->newhandle >= 0 ) {
5848 AO.PrintType |= PRINTLFILE;
5850 while ( *fstring ) {
5851 if ( to >= stopper ) {
5852 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
5856 WriteString(wtype,Out,num);
5858 if ( AC.OutputMode == FORTRANMODE
5859 || AC.OutputMode == PFORTRANMODE ) {
5861 for ( i = 0; i < number; i++ ) *to++ =
' ';
5865 if ( *fstring ==
'\\' ) {
5867 if ( *fstring ==
'n' ) {
5869 WriteString(wtype,Out,num);
5873 else if ( *fstring ==
't' ) { *to++ =
'\t'; fstring++; }
5874 else if ( *fstring ==
'b' ) { *to++ =
'\\'; fstring++; }
5875 else *to++ = *fstring++;
5877 else if ( *fstring ==
'%' ) {
5879 if ( *fstring ==
'd' ) {
5883 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
5885 while ( *s ==
'+' || *s ==
'-' ) {
5886 if ( *s ==
'-' ) sign = -sign;
5889 dig = 0; ss = s;
if ( sign < 0 ) { ss--; *ss =
'-'; dig++; }
5890 while ( *s >=
'0' && *s <=
'9' ) { s++; dig++; }
5893 if ( to >= stopper ) {
5895 WriteString(wtype,Out,num);
5898 if ( *ss ==
'\\' ) ss++;
5903 if ( number < dig ) { dig = number; ss = s - dig; }
5904 while ( number > dig ) {
5905 if ( to >= stopper ) {
5907 WriteString(wtype,Out,num);
5910 *to++ =
' '; number--;
5913 if ( to >= stopper ) {
5915 WriteString(wtype,Out,num);
5918 if ( *ss ==
'\\' ) ss++;
5924 else if ( *fstring ==
'$' ) {
5926 number = AO.OutSkip;
5928 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
5929 if ( AC.OutputMode == FORTRANMODE
5930 || AC.OutputMode == PFORTRANMODE ) {
5934 nodollar: MesPrint(
"@$-variable expected in #write instruction");
5935 AM.FileOnlyFlag = h->oldlogonly;
5936 AC.LogHandle = h->oldhandle;
5937 AO.PrintType = h->oldprinttype;
5938 AM.silent = h->oldsilent;
5942 while ( chartype[*s] <= 1 ) s++;
5943 if ( s == ss )
goto nodollar;
5945 num = GetDollar(ss);
5947 MesPrint(
"@#write instruction: $%s has not been defined",ss);
5948 AM.FileOnlyFlag = h->oldlogonly;
5949 AC.LogHandle = h->oldhandle;
5950 AO.PrintType = h->oldprinttype;
5951 AM.silent = h->oldsilent;
5956 if ( Dollars[num].nfactors <= 0 ) {
5958 MesPrint(
"@#write instruction: $%s has not been factorized",ss);
5959 AM.FileOnlyFlag = h->oldlogonly;
5960 AC.LogHandle = h->oldhandle;
5961 AO.PrintType = h->oldprinttype;
5962 AM.silent = h->oldsilent;
5968 nfac = GetDollarNumber(&s,Dollars+num);
5970 if ( Dollars[num].nfactors == 1 && nfac == 1 )
goto writewhole;
5972 if ( ( dolalloc = WriteDollarFactorToBuffer(num,nfac,0) ) == 0 ) {
5973 AM.FileOnlyFlag = h->oldlogonly;
5974 AC.LogHandle = h->oldhandle;
5975 AO.PrintType = h->oldprinttype;
5976 AM.silent = h->oldsilent;
5981 else if ( *s && *s !=
' ' && *s !=
',' && *s !=
'\t' ) {
5982 MesPrint(
"@#write instruction: illegal characters after $-variable");
5983 AM.FileOnlyFlag = h->oldlogonly;
5984 AC.LogHandle = h->oldhandle;
5985 AO.PrintType = h->oldprinttype;
5986 AM.silent = h->oldsilent;
5991 if ( ( dolalloc = WriteDollarToBuffer(num,0) ) == 0 ) {
5992 AM.FileOnlyFlag = h->oldlogonly;
5993 AC.LogHandle = h->oldhandle;
5994 AO.PrintType = h->oldprinttype;
5995 AM.silent = h->oldsilent;
6002 if ( to >= stopper ) {
6003 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6007 WriteString(wtype,Out,num);
6009 for ( i = 0; i < number; i++ ) *to++ =
' ';
6010 if ( AC.OutputMode == FORTRANMODE
6011 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6013 if ( chartype[*ss] > 3 ) { *to++ = *ss++; }
6015 sss = ss;
while ( chartype[*ss] <= 3 ) ss++;
6016 if ( ( to + (ss-sss) ) >= stopper ) {
6017 if ( (ss-sss) >= (stopper-Out) ) {
6018 if ( ( to - stopper ) < 10 ) {
6019 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6023 WriteString(wtype,Out,num);
6025 for ( i = 0; i < number; i++ ) *to++ =
' ';
6026 if ( AC.OutputMode == FORTRANMODE
6027 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6029 while ( (ss-sss) >= (stopper-Out) ) {
6030 while ( to < stopper-1 ) {
6033 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6040 WriteString(wtype,Out,num);
6042 if ( AC.OutputMode == FORTRANMODE
6043 || AC.OutputMode == PFORTRANMODE ) {
6044 for ( i = 0; i < number; i++ ) *to++ =
' ';
6050 if ( AC.OutputMode == FORTRANMODE && AC.IsFortran90 == ISFORTRAN90 ) {
6054 WriteString(wtype,Out,num);
6056 for ( i = 0; i < number; i++ ) *to++ =
' ';
6057 if ( AC.OutputMode == FORTRANMODE
6058 || AC.OutputMode == PFORTRANMODE ) to[-2] =
'&';
6061 while ( sss < ss ) *to++ = *sss++;
6065 M_free(dolalloc,
"written dollar");
6069 else if ( *fstring ==
's' ) {
6071 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6075 if ( *s ==
'\\' ) s++;
6076 else if ( *s ==
'"' )
break;
6080 MesPrint(
"@#write instruction: Missing \" in string");
6081 AM.FileOnlyFlag = h->oldlogonly;
6082 AC.LogHandle = h->oldhandle;
6083 AO.PrintType = h->oldprinttype;
6084 AM.silent = h->oldsilent;
6088 if ( to >= stopper ) {
6090 WriteString(wtype,Out,num);
6093 if ( *ss ==
'\\' ) ss++;
6100 while ( *s && *s !=
',' ) {
6101 if ( *s ==
'\\' ) { s++; sss = s+1; }
6104 while ( s > sss+1 && ( s[-1] ==
' ' || s[-1] ==
'\t' ) ) s--;
6106 if ( to >= stopper ) {
6108 WriteString(wtype,Out,num);
6111 if ( *ss ==
'\\' ) ss++;
6116 else if ( *fstring ==
'X' ) {
6118 if ( cbuf[AM.sbufnum].numrhs > 0 ) {
6122 UBYTE *s = GetPreVar(AM.oldnumextrasymbols,0);
6124 while ( *s >=
'0' && *s <=
'9' ) x = 10*x + *s++ -
'0';
6126 PrintSubtermList(1,x);
6128 PrintSubtermList(1,cbuf[AM.sbufnum].numrhs);
6131 else if ( *fstring ==
'O' ) {
6132 number = AO.OutSkip;
6138 if ( AO.OptimizeResult.code == NULL && AO.OptimizationLevel != 0 ) {
6139 MesPrint(
"@In #write instruction: no optimization results available!");
6143 WriteString(wtype,Out,num);
6145 if ( AO.OptimizationLevel != 0 ) {
6146 WORD oldoutskip = AO.OutSkip;
6147 AO.OutSkip = number;
6148 optimize_print_code(0);
6149 AO.OutSkip = oldoutskip;
6152 else if ( *fstring ==
'e' || *fstring ==
'E' ) {
6153 if ( *fstring ==
'E' 6154 || AC.OutputMode == FORTRANMODE
6155 || AC.OutputMode == PFORTRANMODE ) nosemi = 1;
6158 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6159 if ( chartype[*s] != 0 && *s !=
'[' ) {
6160 noexpr: MesPrint(
"@expression name expected in #write instruction");
6161 AM.FileOnlyFlag = h->oldlogonly;
6162 AC.LogHandle = h->oldhandle;
6163 AO.PrintType = h->oldprinttype;
6164 AM.silent = h->oldsilent;
6168 if ( ( s = SkipAName(ss) ) == 0 || s[-1] ==
'_' )
goto noexpr;
6169 s1 = s; c = c1 = *s1;
6173 AO.CurBufWrt = s1+1;
6177 MesPrint(
"@Illegal () specifier in expression name in #write");
6178 AM.FileOnlyFlag = h->oldlogonly;
6179 AC.LogHandle = h->oldhandle;
6180 AO.PrintType = h->oldprinttype;
6181 AM.silent = h->oldsilent;
6185 else AO.CurBufWrt = (UBYTE *)underscore;
6188 if ( num > 0 ) WriteUnfinString(wtype,Out,num);
6190 WORD oldOptimizationLevel = AO.OptimizationLevel;
6191 AO.OptimizationLevel = 0;
6192 if ( WriteOne(ss,(
int)num,nosemi) < 0 ) {
6193 AM.FileOnlyFlag = h->oldlogonly;
6194 AC.LogHandle = h->oldhandle;
6195 AO.PrintType = h->oldprinttype;
6196 AM.silent = h->oldsilent;
6199 AO.OptimizationLevel = oldOptimizationLevel;
6201 if ( s > s1 ) *s++ = c;
6206 else if ( ( *fstring ==
'f' ) || ( *fstring ==
'F' ) ) {
6208 while ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) s++;
6210 while ( *s && *s !=
',' ) {
6211 if ( *s ==
'\\' ) s++;
6215 s1 = LoadInputFile(ss,HEADERFILE);
6222 ss = s1;
while ( *ss ) ss++;
6224 WriteString(wtype,s1,n);
6225 M_free(s1,
"copy file");
6227 else if ( *fstring ==
'F' ) {
6229 MesPrint(
"@Error in #write: could not open file %s",ss);
6231 goto ReturnWithError;
6235 else if ( *fstring ==
'%' ) {
6238 else if ( FG.cTable[*fstring] == 1 ) {
6240 while ( FG.cTable[*fstring] == 1 ) {
6241 number = 10*number + *fstring++ -
'0';
6243 if ( *fstring ==
'O' )
goto dooptim;
6244 else if ( *fstring ==
'd' )
goto donumber;
6245 else if ( *fstring ==
'$' )
goto dodollar;
6246 else if ( *fstring ==
'X' || *fstring ==
'x' ) {
6247 if ( number > 0 && number <= cbuf[AM.sbufnum].numrhs ) {
6248 UBYTE buffer[80], *out, *old1, *old2, *old3;
6250 if ( *fstring ==
'X' ) {
6251 out = StrCopy((UBYTE *)AC.extrasym,buffer);
6252 if ( AC.extrasymbols == 0 ) {
6253 out = NumCopy(number,out);
6254 out = StrCopy((UBYTE *)
"_",out);
6256 else if ( AC.extrasymbols == 1 ) {
6257 if ( AC.OutputMode == CMODE ) {
6258 out = StrCopy((UBYTE *)
"[",out);
6259 out = NumCopy(number,out);
6260 out = StrCopy((UBYTE *)
"]",out);
6263 out = StrCopy((UBYTE *)
"(",out);
6264 out = NumCopy(number,out);
6265 out = StrCopy((UBYTE *)
")",out);
6268 out = StrCopy((UBYTE *)
"=",out);
6270 while ( ss < out ) {
6271 if ( to >= stopper ) {
6273 WriteString(wtype,Out,num);
6279 term = cbuf[AM.sbufnum].rhs[number];
6286 old2 = AO.OutputLine;
6289 AO.OutputLine = Out;
6290 AO.OutStop = Out + AC.LineLength;
6292 if ( WriteInnerTerm(term,first) ) Terminate(-1);
6296 to = Out + (AO.OutFill-AO.OutputLine);
6298 AO.OutputLine = old2;
6305 goto IllegControlSequence;
6308 else if ( *fstring == 0 ) {
6312 IllegControlSequence:
6313 MesPrint(
"@Illegal control sequence in format string in #write instruction");
6315 AM.FileOnlyFlag = h->oldlogonly;
6316 AC.LogHandle = h->oldhandle;
6317 AO.PrintType = h->oldprinttype;
6318 AM.silent = h->oldsilent;
6331 if(wtype==EXTERNALCHANNELOUT){
6333 WriteUnfinString(wtype,Out,num);
6336 WriteString(wtype,Out,num);
6340 AM.FileOnlyFlag = h->oldlogonly;
6341 AC.LogHandle = h->oldhandle;
6342 AO.PrintType = h->oldprinttype;
6343 AM.silent = h->oldsilent;
6355 int DoFactDollar(UBYTE *s)
6358 WORD numdollar, *oldworkpointer;
6360 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6361 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6362 while ( *s ==
' ' || *s ==
'\t' ) s++;
6364 if ( GetName(AC.dollarnames,s+1,&numdollar,NOAUTO) != CDOLLAR ) {
6365 MesPrint(
"@%s is undefined",s);
6370 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6374 oldworkpointer = AT.WorkPointer;
6375 if ( DollarFactorize(BHEAD numdollar) )
return(-1);
6376 AT.WorkPointer = oldworkpointer;
6380 else if ( ParenthesesTest(s) )
return(-1);
6382 MesPrint(
"@#FactDollar should have a single $variable for its argument");
6392 WORD GetDollarNumber(UBYTE **inp,
DOLLARS d)
6394 UBYTE *s = *inp, c, *name;
6395 WORD number, nfac, *w;
6400 while ( FG.cTable[*s] < 2 ) s++;
6402 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6403 MesPrint(
"@dollar in #write should have been defined previously");
6407 dd = Dollars + number;
6410 nfac = GetDollarNumber(inp,dd);
6413 MesPrint(
"@Illegal factor for dollar variable");
6418 if ( dd->nfactors > d->nfactors ) {
6420 MesPrint(
"@Factor number for dollar variable too large");
6423 return(dd->nfactors);
6425 w = dd->factors[nfac-1].where;
6427 if ( dd->factors[nfac-1].value > d->nfactors ||
6428 dd->factors[nfac-1].value < 0 )
goto TooBig;
6429 return(dd->factors[nfac-1].value);
6431 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6432 && w[1] <= d->nfactors )
return(w[1]);
6433 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6435 MesPrint(
"@Illegal factor number for dollar variable");
6439 if ( dd->type == DOLZERO ) {
6442 else if ( dd->type == DOLTERMS || dd->type == DOLNUMBER ) {
6444 if ( *w == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1
6445 && w[1] <= d->nfactors )
return(w[1]);
6446 if ( w[*w] == 0 && w[*w-1] == *w-1 )
goto TooBig;
6452 else if ( FG.cTable[*s] == 1 ) {
6453 WORD x = *s++ -
'0';
6454 while ( FG.cTable[*s] == 1 ) {
6455 x = 10*x + *s++ -
'0';
6456 if ( x > d->nfactors ) {
6457 MesPrint(
"@Factor number %d for dollar variable too large",x);
6462 MesPrint(
"@Illegal factor number for dollar variable");
6469 MesPrint(
"@Illegal factor indicator for dollar variable");
6482 int DoSetRandom(UBYTE *s)
6485 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6486 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6487 while ( *s ==
' ' || *s ==
'\t' ) s++;
6489 while ( FG.cTable[*s] == 1 ) {
6490 x = 10*x + (*s++-
'0');
6492 while ( *s ==
' ' || *s ==
'\t' ) s++;
6496 int id, totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
6498 int id, totnum = AM.totalnumberofthreads;
6500 for (
id = 0;
id < totnum;
id++ ) {
6501 AB[id]->R.wranfseed = x;
6502 if ( AB[
id]->R.wranfia ) M_free(AB[
id]->R.wranfia,
"wranf");
6503 AB[id]->R.wranfia = 0;
6507 if ( AR.wranfia ) M_free(AR.wranfia,
"wranf");
6513 MesPrint(
"@proper syntax is #SetRandom number");
6525 int DoOptimize(UBYTE *s)
6531 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6532 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6534 exprname = s; s = SkipAName(s);
6535 if ( *s != 0 && *s !=
';' ) {
6536 MesPrint(
"@proper syntax is #Optimize,expression");
6540 if ( GetName(AC.exprnames,exprname,&numexpr,NOAUTO) != CEXPRESSION ) {
6541 MesPrint(
"@%s is not an expression",exprname);
6544 else if ( AP.preError == 0 ) {
6548 WORD *term = AT.WorkPointer;
6550 if ( AO.OptimizationLevel == 0 )
return(0);
6551 switch ( e->status ) {
6552 case LOCALEXPRESSION:
6553 case GLOBALEXPRESSION:
6556 MesPrint(
"@Expression %s is not an active unhidden local or global expression.",exprname);
6561 if ( PF.me == MASTER )
6564 for ( i = NumExpressions-1; i >= 0; i-- ) {
6565 AS.OldOnFile[i] = Expressions[i].onfile;
6566 AS.OldNumFactors[i] = Expressions[i].numfactors;
6567 AS.Oldvflags[i] = Expressions[i].vflags;
6568 Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
6570 for ( i = 0; i < NumExpressions; i++ ) {
6571 if ( i == numexpr ) {
6573 GetPreVar((UBYTE *)
"EXTRASYMBOLS_",0),0,1);
6574 Optimize(numexpr, 0);
6575 AO.OptimizeResult.nameofexpr = strDup1(exprname,
"optimize expression name");
6579 if ( PF.me == MASTER ) {
6581 e = Expressions + i;
6582 switch ( e->status ) {
6583 case LOCALEXPRESSION:
6584 case SKIPLEXPRESSION:
6585 case DROPLEXPRESSION:
6586 case DROPPEDEXPRESSION:
6587 case GLOBALEXPRESSION:
6588 case SKIPGEXPRESSION:
6589 case DROPGEXPRESSION:
6590 case HIDELEXPRESSION:
6591 case HIDEGEXPRESSION:
6592 case DROPHLEXPRESSION:
6593 case DROPHGEXPRESSION:
6594 case INTOHIDELEXPRESSION:
6595 case INTOHIDEGEXPRESSION:
6601 SetScratch(AR.infile,&(e->onfile));
6602 if ( GetTerm(BHEAD term) <= 0 ) {
6603 MesPrint(
"@Expression %d has problems reading from scratchfile",i);
6608 SeekScratch(AR.outfile,&position);
6609 e->onfile = position;
6610 *AM.S0->sBuffer = 0; firstterm = -1;
6612 WORD *oldipointer = AR.CompressPointer;
6613 WORD *comprtop = AR.ComprTop;
6614 AR.ComprTop = AM.S0->sTop;
6615 AR.CompressPointer = AM.S0->sBuffer;
6616 if ( firstterm > 0 ) {
6617 if (
PutOut(BHEAD term,&position,AR.outfile,1) < 0 )
goto DoSerr;
6619 else if ( firstterm < 0 ) {
6620 if (
PutOut(BHEAD term,&position,AR.outfile,0) < 0 )
goto DoSerr;
6624 if (
PutOut(BHEAD term,&position,AR.outfile,-1) < 0 )
goto DoSerr;
6627 AR.CompressPointer = oldipointer;
6628 AR.ComprTop = comprtop;
6629 }
while ( GetTerm(BHEAD term) );
6630 if (
FlushOut(&position,AR.outfile,1) ) {
6632 MesPrint(
"@Expression %d has problems writing to scratchfile",i);
6658 int DoClearOptimize(UBYTE *s)
6660 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6661 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6663 return(ClearOptimize());
6678 int DoSkipExtraSymbols(UBYTE *s)
6680 CBUF *C = cbuf + AM.sbufnum;
6681 WORD tt = 0, j = 0, oldval = AO.OptimizeResult.minvar;
6682 if ( AO.OptimizeResult.code == NULL )
return(0);
6683 if ( AO.OptimizationLevel == 0 )
return(0);
6684 while ( *s ==
',' ) s++;
6686 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
6689 while ( *s <= '9' && *s >=
'0' ) j = 10*j + *s++ -
'0';
6691 MesPrint(
"@Illegal use of #SkipExtraSymbols instruction");
6694 AO.OptimizeResult.minvar += j;
6695 if ( AO.OptimizeResult.minvar > AO.OptimizeResult.maxvar )
6696 AO.OptimizeResult.minvar = AO.OptimizeResult.maxvar+1;
6698 j = AO.OptimizeResult.minvar - oldval;
6703 InsTree(AM.sbufnum,C->numrhs);
6717 int DoPreReset(UBYTE *s)
6720 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6721 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6722 while ( *s ==
' ' || *s ==
'\t' ) s++;
6724 MesPrint(
"@proper syntax is #Reset variable");
6728 while ( FG.cTable[*s] == 0 ) s++;
6730 if ( ( StrICmp(ss,(UBYTE *)
"timer") == 0 )
6731 || ( StrICmp(ss,(UBYTE *)
"stopwatch") == 0 ) ) {
6733 AP.StopWatchZero = GetRunningTime();
6738 MesPrint(
"@proper syntax is #Reset variable");
6748 static int DoAddPath(UBYTE *s,
int bPrepend)
6752 UBYTE *path, *path_end, *current_dir, *current_dir_end, *NewPath, *t;
6755 if ( AP.PreSwitchModes[AP.PreSwitchLevel] != EXECUTINGPRESWITCH )
return(0);
6756 if ( AP.PreIfStack[AP.PreIfLevel] != EXECUTINGIF )
return(0);
6759 while ( *s ==
' ' || *s ==
'\t' ) s++;
6762 while ( *s && *s !=
'"' ) {
6763 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
6764 if ( !s[1] )
goto ImproperPath;
6769 if ( *s !=
'"' )
goto ImproperPath;
6774 while ( *s && *s !=
' ' && *s !=
'\t' ) {
6775 if ( SEPARATOR !=
'\\' && *s ==
'\\' ) {
6776 if ( !s[1] )
goto ImproperPath;
6783 if ( path == path_end )
goto ImproperPath;
6784 while ( *s ==
' ' || *s ==
'\t' ) s++;
6785 if ( *s )
goto ImproperPath;
6789 if ( path[0] == SEPARATOR ) {
6793 else if ( chartype[path[0]] == 0 && path[1] ==
':' ) {
6800 if ( !AC.CurrentStream )
goto FileNameUnavailable;
6801 if ( AC.CurrentStream->type != FILESTREAM && AC.CurrentStream->type != REVERSEFILESTREAM )
goto FileNameUnavailable;
6802 if ( !AC.CurrentStream->name )
goto FileNameUnavailable;
6803 s = current_dir = current_dir_end = AC.CurrentStream->name;
6805 if ( SEPARATOR !=
'\\' && *s ==
'\\' && s[1] ) {
6809 if ( *s == SEPARATOR ) {
6810 current_dir_end = s;
6816 current_dir = current_dir_end = NULL;
6820 n = path_end - path;
6821 if ( AM.Path ) n += StrLen(AM.Path) + 1;
6822 if ( current_dir != current_dir_end ) n+= current_dir_end - current_dir + 1;
6823 s = NewPath = (UBYTE *)Malloc1(n + 1,
"add path");
6827 if ( current_dir != current_dir_end ) {
6829 while ( t != current_dir_end ) *s++ = *t++;
6833 while ( t != path_end ) *s++ = *t++;
6834 if ( AM.Path ) *s++ = PATHSEPARATOR;
6838 while ( *t ) *s++ = *t++;
6841 if ( AM.Path ) *s++ = PATHSEPARATOR;
6842 if ( current_dir != current_dir_end ) {
6844 while ( t != current_dir_end ) *s++ = *t++;
6848 while ( t != path_end ) *s++ = *t++;
6853 if ( AM.Path ) M_free(AM.Path,
"add path");
6859 MesPrint(
"@Improper syntax for %#%sPath", bPrepend ?
"Prepend" :
"Append");
6862 FileNameUnavailable:
6864 MesPrint(
"@Sorry, %#%sPath can't resolve the current file name from here", bPrepend ?
"Prepend" :
"Append");
6877 return DoAddPath(s, 0);
6894 return DoAddPath(s, 1);
void AddPotModdollar(WORD)
int TheDefine(UBYTE *s, int mode)
#define VectorReserve(X, newcapacity)
int DoRecovery(int *moduletype)
int DoPrePrependPath(UBYTE *s)
int PF_BroadcastRedefinedPreVars(void)
int DoPreAppendPath(UBYTE *s)
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)