1 /* as.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Hauptmodul                                                                */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 #include <setjmp.h>
15 #include <assert.h>
16 
17 #include "version.h"
18 #include "endian.h"
19 #include "bpemu.h"
20 
21 #include "stdhandl.h"
22 #include "nls.h"
23 #include "nlmessages.h"
24 #include "as.rsc"
25 #include "ioerrs.h"
26 #include "strutil.h"
27 #include "stringlists.h"
28 #include "cmdarg.h"
29 #include "asmitree.h"
30 #include "trees.h"
31 #include "chunks.h"
32 #include "console.h"
33 #include "asminclist.h"
34 #include "asmfnums.h"
35 #include "asmdef.h"
36 #include "cpulist.h"
37 #include "asmerr.h"
38 #include "asmsub.h"
39 #include "asmpars.h"
40 #include "asmmac.h"
41 #include "asmstructs.h"
42 #include "asmif.h"
43 #include "asmcode.h"
44 #include "asmlist.h"
45 #include "asmlabel.h"
46 #include "asmdebug.h"
47 #include "asmrelocs.h"
48 #include "asmallg.h"
49 #include "codepseudo.h"
50 #include "as.h"
51 
52 #include "code68k.h"
53 #include "code56k.h"
54 #include "code601.h"
55 #include "codemcore.h"
56 #include "codexgate.h"
57 #include "code68.h"
58 #include "code6805.h"
59 #include "code6809.h"
60 #include "code6812.h"
61 #include "codes12z.h"
62 #include "code6816.h"
63 #include "code68rs08.h"
64 #include "codeh8_3.h"
65 #include "codeh8_5.h"
66 #include "code7000.h"
67 #include "code65.h"
68 #include "codeh16.h"
69 #include "code7700.h"
70 #include "codehmcs400.h"
71 #include "code4500.h"
72 #include "codem16.h"
73 #include "codem16c.h"
74 #include "code4004.h"
75 #include "code8008.h"
76 #include "code48.h"
77 #include "code51.h"
78 #include "code96.h"
79 #include "code85.h"
80 #include "code86.h"
81 #include "code960.h"
82 #include "code8x30x.h"
83 #include "code2650.h"
84 #include "codexa.h"
85 #include "codeavr.h"
86 #include "code29k.h"
87 #include "code166.h"
88 #include "codez80.h"
89 #include "codez8.h"
90 #include "codekcpsm.h"
91 #include "codekcp3.h"
92 #include "codemic8.h"
93 #include "code96c141.h"
94 #include "code90c141.h"
95 #include "code87c800.h"
96 #include "code870c.h"
97 #include "code47c00.h"
98 #include "code97c241.h"
99 #include "code9331.h"
100 #include "code16c5x.h"
101 #include "code16c8x.h"
102 #include "code17c4x.h"
103 #include "codesx20.h"
104 #include "codest6.h"
105 #include "codest7.h"
106 #include "codest9.h"
107 #include "code6804.h"
108 #include "code3201x.h"
109 #include "code3202x.h"
110 #include "code3203x.h"
111 #include "code3205x.h"
112 #include "code3254x.h"
113 #include "code3206x.h"
114 #include "code9900.h"
115 #include "codetms7.h"
116 #include "code370.h"
117 #include "codemsp.h"
118 #include "codetms1.h"
119 #include "codescmp.h"
120 #include "code807x.h"
121 #include "codecop4.h"
122 #include "codecop8.h"
123 #include "codesc14xxx.h"
124 #include "codeace.h"
125 #include "codef8.h"
126 #include "code78c10.h"
127 #include "code75xx.h"
128 #include "code75k0.h"
129 #include "code78k0.h"
130 #include "code78k2.h"
131 #include "code78k3.h"
132 #include "code78k4.h"
133 #include "code7720.h"
134 #include "code77230.h"
135 #include "code53c8xx.h"
136 #include "codefmc8.h"
137 #include "codefmc16.h"
138 #include "codemn1610.h"
139 #include "codemn2610.h"
140 #include "codeol40.h"
141 #include "codeol50.h"
142 #include "code1802.h"
143 #include "codevector.h"
144 #include "codexcore.h"
145 #include "code1750.h"
146 #include "codekenbak.h"
147 /**          Code21xx};**/
148 
149 static char *FileMask;
150 static long StartTime, StopTime;
151 static Boolean GlobErrFlag;
152 static Boolean MasterFile;
153 static unsigned MacroNestLevel = 0;
154 
155 /*=== Zeilen einlesen ======================================================*/
156 
157 
158 #if 0
159 # define dbgentry(str) printf("***enter %s\n", str);
160 # define dbgexit(str) printf("***exit %s\n", str);
161 #else
162 # define dbgentry(str) {}
163 # define dbgexit(str) {}
164 #endif
165 
NULL_Restorer(PInputTag PInp)166 static void NULL_Restorer(PInputTag PInp)
167 {
168   UNUSED(PInp);
169 }
170 
NULL_GetPos(PInputTag PInp,char * dest,size_t DestSize)171 static Boolean NULL_GetPos(PInputTag PInp, char *dest, size_t DestSize)
172 {
173   UNUSED(PInp);
174 
175   if (DestSize)
176     *dest = '\0';
177   return False;
178 }
179 
180 static Boolean INCLUDE_Processor(PInputTag PInp, char *Erg);
181 
GenerateProcessor(void)182 static PInputTag GenerateProcessor(void)
183 {
184   PInputTag PInp = (PInputTag)malloc(sizeof(TInputTag));
185 
186   PInp->IsMacro = False;
187   PInp->Next = NULL;
188   PInp->First = True;
189   PInp->OrigDoLst = DoLst;
190   PInp->StartLine = CurrLine;
191   PInp->ParCnt = 0; PInp->ParZ = 0;
192   InitStringList(&(PInp->Params));
193   PInp->LineCnt = 0; PInp->LineZ = 1;
194   PInp->Lines = PInp->LineRun = NULL;
195   StrCompMkTemp(&PInp->SpecName, PInp->SpecNameStr);
196   StrCompReset(&PInp->SpecName);
197   PInp->AllArgs[0] = '\0';
198   PInp->NumArgs[0] = '\0';
199   PInp->IsEmpty = False;
200   PInp->Buffer = NULL;
201   PInp->Datei = NULL;
202   PInp->IfLevel = SaveIFs();
203   PInp->Restorer = NULL_Restorer;
204   PInp->GetPos = NULL_GetPos;
205   PInp->Macro = NULL;
206   PInp->SaveAttr[0] = '\0';
207   PInp->SaveLabel[0] = '\0';
208   PInp->GlobalSymbols = False;
209   PInp->UsesNumArgs =
210   PInp->UsesAllArgs = False;
211 
212   /* in case the input tag chain is empty, this must be the master file */
213 
214   PInp->FromFile = (!FirstInputTag) || (FirstInputTag->Processor == INCLUDE_Processor);
215 
216   return PInp;
217 }
218 
GenerateOUTProcessor(SimpProc Processor,tErrorNum OpenErrMsg)219 static POutputTag GenerateOUTProcessor(SimpProc Processor, tErrorNum OpenErrMsg)
220 {
221   POutputTag POut;
222 
223   POut = (POutputTag) malloc(sizeof(TOutputTag));
224   POut->Processor = Processor;
225   POut->NestLevel = 0;
226   POut->Tag = NULL;
227   POut->Mac = NULL;
228   POut->ParamNames = NULL;
229   POut->ParamDefVals = NULL;
230   POut->PubSect = 0;
231   POut->GlobSect = 0;
232   POut->DoExport = False;
233   POut->DoGlobCopy= False;
234   POut->UsesNumArgs =
235   POut->UsesAllArgs = False;
236   *POut->GName = '\0';
237   POut->OpenErrMsg = OpenErrMsg;
238 
239   return POut;
240 }
241 
242 /*=========================================================================*/
243 /* Makroprozessor */
244 
245 /*-------------------------------------------------------------------------*/
246 /* allgemein gebrauchte Subfunktionen */
247 
248 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
249 /* werden gebraucht, um festzustellen, ob innerhalb eines Makrorumpfes weitere
250    Makroschachtelungen auftreten */
251 
MacroStart(void)252 static Boolean MacroStart(void)
253 {
254   return ((Memo("MACRO")) || (Memo("IRP")) || (Memo("IRPC")) || (Memo("REPT")) || (Memo("WHILE")));
255 }
256 
MacroEnd(void)257 static Boolean MacroEnd(void)
258 {
259   if (Memo("ENDM"))
260   {
261     WasMACRO = True;
262     return True;
263   }
264   else
265     return False;
266 }
267 
268 typedef void (*tMacroArgCallback)(Boolean CtrlArg, const tStrComp *pArg, void *pUser);
269 
ProcessMacroArgs(tMacroArgCallback Callback,void * pUser)270 static void ProcessMacroArgs(tMacroArgCallback Callback, void *pUser)
271 {
272   tStrComp *pArg;
273   int l;
274 
275   for (pArg = ArgStr + 1; pArg <= ArgStr + ArgCnt; pArg++)
276   {
277     l = strlen(pArg->Str);
278     if ((l >= 2) && (pArg->Str[0] == '{') && (pArg->Str[l - 1] == '}'))
279     {
280       tStrComp Arg;
281 
282       StrCompRefRight(&Arg, pArg, 1);
283       StrCompShorten(&Arg, 1);
284       Callback(TRUE, &Arg, pUser);
285     }
286     else
287     {
288       Callback(FALSE, pArg, pUser);
289     }
290   }
291 }
292 
293 /*-------------------------------------------------------------------------*/
294 /* Dieser Einleseprozessor dient nur dazu, eine fehlerhafte Makrodefinition
295   bis zum Ende zu ueberlesen */
296 
WaitENDM_Processor(void)297 static void WaitENDM_Processor(void)
298 {
299   POutputTag Tmp;
300 
301   if (MacroStart())
302     FirstOutputTag->NestLevel++;
303   else if (MacroEnd())
304     FirstOutputTag->NestLevel--;
305   if (FirstOutputTag->NestLevel <= -1)
306   {
307     Tmp = FirstOutputTag;
308     FirstOutputTag = Tmp->Next;
309     free(Tmp);
310   }
311 }
312 
AddWaitENDM_Processor(void)313 static void AddWaitENDM_Processor(void)
314 {
315   POutputTag Neu;
316 
317   Neu = GenerateOUTProcessor(WaitENDM_Processor, ErrNum_OpenMacro);
318   Neu->Next = FirstOutputTag;
319   FirstOutputTag = Neu;
320 }
321 
322 /*-------------------------------------------------------------------------*/
323 /* normale Makros */
324 
ComputeMacroStrings(PInputTag Tag)325 static void ComputeMacroStrings(PInputTag Tag)
326 {
327   StringRecPtr Lauf;
328 
329   /* recompute # of params */
330 
331   if (Tag->UsesNumArgs)
332     as_snprintf(Tag->NumArgs, sizeof(Tag->NumArgs), Integ32Format, Tag->ParCnt);
333 
334   /* recompute 'all string' parameter */
335 
336   if (Tag->UsesAllArgs)
337   {
338     Tag->AllArgs[0] = '\0';
339     Lauf = Tag->Params;
340     while (Lauf)
341     {
342       if (Tag->AllArgs[0] != '\0')
343         strmaxcat(Tag->AllArgs, ",", STRINGSIZE);
344       strmaxcat(Tag->AllArgs, Lauf->Content, STRINGSIZE);
345       Lauf = Lauf->Next;
346     }
347   }
348 }
349 
350 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
351 /* Diese Routine leitet die Quellcodezeilen bei der Makrodefinition in den
352    Makro-Record um */
353 
MACRO_OutProcessor(void)354 static void MACRO_OutProcessor(void)
355 {
356   POutputTag Tmp;
357   int z;
358   StringRecPtr l;
359   PMacroRec GMacro;
360   String s;
361 
362   WasMACRO = True;
363 
364   /* write preprocessed output to file ? */
365 
366   if ((MacroOutput) && (FirstOutputTag->DoExport))
367   {
368     errno = 0;
369     fprintf(MacroFile, "%s\n", OneLine);
370     ChkIO(ErrNum_FileWriteError);
371   }
372 
373   /* check for additional nested macros resp. end of definition */
374 
375   if (MacroStart())
376     FirstOutputTag->NestLevel++;
377   else if (MacroEnd())
378     FirstOutputTag->NestLevel--;
379 
380   /* still lines to put into the macro body ? */
381 
382   if (FirstOutputTag->NestLevel != -1)
383   {
384     strmaxcpy(s, OneLine, STRINGSIZE);
385     KillCtrl(s);
386 
387     /* compress into tokens */
388 
389     l = FirstOutputTag->ParamNames;
390     for (z = 1; z <= FirstOutputTag->Mac->ParamCount; z++)
391       CompressLine(GetStringListNext(&l), z, s, sizeof(s), CaseSensitive);
392 
393     /* reserved argument names are never case-sensitive */
394 
395     if (HasAttrs)
396       CompressLine(AttrName, ArgCntMax + 1, s, sizeof(s), FALSE);
397     if (CompressLine(ArgCName, ArgCntMax + 2, s, sizeof(s), FALSE) > 0)
398       FirstOutputTag->UsesNumArgs = TRUE;
399     if (CompressLine(AllArgName, ArgCntMax + 3, s, sizeof(s), FALSE) > 0)
400       FirstOutputTag->UsesAllArgs = TRUE;
401     if (FirstOutputTag->Mac->LocIntLabel)
402       CompressLine(LabelName, ArgCntMax + 4, s, sizeof(s), FALSE);
403 
404     AddStringListLast(&(FirstOutputTag->Mac->FirstLine), s);
405   }
406 
407   /* otherwise, finish definition */
408 
409   if (FirstOutputTag->NestLevel == -1)
410   {
411     if (IfAsm)
412     {
413       FirstOutputTag->Mac->UsesNumArgs = FirstOutputTag->UsesNumArgs;
414       FirstOutputTag->Mac->UsesAllArgs = FirstOutputTag->UsesAllArgs;
415       FirstOutputTag->Mac->ParamNames = FirstOutputTag->ParamNames;
416       FirstOutputTag->ParamNames = NULL;
417       FirstOutputTag->Mac->ParamDefVals = FirstOutputTag->ParamDefVals;
418       FirstOutputTag->ParamDefVals = NULL;
419       AddMacro(FirstOutputTag->Mac, FirstOutputTag->PubSect, True);
420       if ((FirstOutputTag->DoGlobCopy) && (SectionStack))
421       {
422         GMacro = (PMacroRec) malloc(sizeof(MacroRec));
423         GMacro->Name = as_strdup(FirstOutputTag->GName);
424         GMacro->ParamCount = FirstOutputTag->Mac->ParamCount;
425         GMacro->FirstLine = DuplicateStringList(FirstOutputTag->Mac->FirstLine);
426         GMacro->ParamNames = DuplicateStringList(FirstOutputTag->Mac->ParamNames);
427         GMacro->ParamDefVals = DuplicateStringList(FirstOutputTag->Mac->ParamDefVals);
428         GMacro->UsesNumArgs = FirstOutputTag->Mac->UsesNumArgs;
429         GMacro->UsesAllArgs = FirstOutputTag->Mac->UsesAllArgs;
430         AddMacro(GMacro, FirstOutputTag->GlobSect, False);
431       }
432     }
433     else
434     {
435       ClearMacroRec(&(FirstOutputTag->Mac), TRUE);
436     }
437 
438     Tmp = FirstOutputTag;
439     FirstOutputTag = Tmp->Next;
440     ClearStringList(&(Tmp->ParamNames));
441     ClearStringList(&(Tmp->ParamDefVals));
442     free(Tmp);
443   }
444 }
445 
446 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
447 /* Hierher kommen bei einem Makroaufruf die expandierten Zeilen */
448 
MACRO_Processor(PInputTag PInp,char * erg)449 Boolean MACRO_Processor(PInputTag PInp, char *erg)
450 {
451   StringRecPtr Lauf;
452   int z;
453   Boolean Result;
454 
455   Result = True;
456 
457   /* run to current line */
458 
459   Lauf = PInp->Lines;
460   for (z = 1; z <= PInp->LineZ - 1; z++)
461     Lauf = Lauf->Next;
462   strcpy(erg, Lauf->Content);
463 
464   /* process parameters */
465 
466   Lauf = PInp->Params;
467   for (z = 1; z <= PInp->ParCnt; z++)
468   {
469     ExpandLine(Lauf->Content, z, erg, STRINGSIZE);
470     Lauf = Lauf->Next;
471   }
472 
473   /* process special parameters */
474 
475   if (HasAttrs)
476     ExpandLine(PInp->SaveAttr, ArgCntMax + 1, erg, STRINGSIZE);
477   if (PInp->UsesNumArgs)
478     ExpandLine(PInp->NumArgs, ArgCntMax + 2, erg, STRINGSIZE);
479   if (PInp->UsesAllArgs)
480     ExpandLine(PInp->AllArgs, ArgCntMax + 3, erg, STRINGSIZE);
481   if (PInp->Macro->LocIntLabel)
482     ExpandLine(PInp->SaveLabel, ArgCntMax + 4, erg, STRINGSIZE);
483 
484   CurrLine = PInp->StartLine;
485   InMacroFlag = True;
486 
487   /* before the first line, start a new local symbol space */
488 
489   if ((PInp->LineZ == 1) && (!PInp->GlobalSymbols))
490     PushLocHandle(GetLocHandle());
491 
492   /* signal the end of the macro */
493 
494   if (++(PInp->LineZ) > PInp->LineCnt)
495     Result = False;
496 
497   return Result;
498 }
499 
500 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
501 /* Initialisierung des Makro-Einleseprozesses */
502 
ReadMacro_SearchArg(const char * pTest,const char * pComp,Boolean * pErg)503 static Boolean ReadMacro_SearchArg(const char *pTest, const char *pComp, Boolean *pErg)
504 {
505   if (!as_strcasecmp(pTest, pComp))
506   {
507     *pErg = True;
508     return True;
509   }
510   else if ((strlen(pTest) > 2) && (!as_strncasecmp(pTest, "NO", 2)) && (!as_strcasecmp(pTest + 2, pComp)))
511   {
512     *pErg = False;
513     return True;
514   }
515   else
516     return False;
517 }
518 
ReadMacro_SearchSect(char * Test_O,const char * Comp,Boolean * Erg,LongInt * Section)519 static Boolean ReadMacro_SearchSect(char *Test_O, const char *Comp, Boolean *Erg, LongInt *Section)
520 {
521   char *p;
522   String Test, Sect;
523 
524   strmaxcpy(Test, Test_O, STRINGSIZE); KillBlanks(Test);
525   p = strchr(Test, ':');
526   if (!p)
527     *Sect = '\0';
528   else
529   {
530     strmaxcpy(Sect, p + 1, STRINGSIZE);
531     *p = '\0';
532   }
533   if ((strlen(Test) > 2) && (!as_strncasecmp(Test, "NO", 2)) && (!as_strcasecmp(Test + 2, Comp)))
534   {
535     *Erg = False;
536     return True;
537   }
538   else if (!as_strcasecmp(Test, Comp))
539   {
540     tStrComp TmpComp;
541 
542     *Erg = True;
543     StrCompMkTemp(&TmpComp, Sect);
544     return (IdentifySection(&TmpComp, Section));
545   }
546   else
547     return False;
548 }
549 
550 typedef struct
551 {
552   String PList;
553   POutputTag pOutputTag;
554   tLstMacroExpMod LstMacroExpMod;
555   Boolean DoPublic, DoIntLabel, GlobalSymbols;
556   Boolean ErrFlag;
557   int ParamCount;
558 } tReadMacroContext;
559 
ExpandPList(String PList,const char * pArg,Boolean CtrlArg)560 static void ExpandPList(String PList, const char *pArg, Boolean CtrlArg)
561 {
562   if (!*PList)
563     strmaxcat(PList, ",", STRINGSIZE);
564   if (CtrlArg)
565     strmaxcat(PList, "{", STRINGSIZE);
566   strmaxcat(PList, pArg, STRINGSIZE);
567   if (CtrlArg)
568     strmaxcat(PList, "}", STRINGSIZE);
569 }
570 
ProcessMACROArgs(Boolean CtrlArg,const tStrComp * pArg,void * pUser)571 static void ProcessMACROArgs(Boolean CtrlArg, const tStrComp *pArg, void *pUser)
572 {
573   tReadMacroContext *pContext = (tReadMacroContext*)pUser;
574 
575   if (CtrlArg)
576   {
577     Boolean DoMacExp;
578 
579     if (ReadMacro_SearchArg(pArg->Str, "EXPORT", &(pContext->pOutputTag->DoExport)));
580     else if (ReadMacro_SearchArg(pArg->Str, "GLOBALSYMBOLS", &pContext->GlobalSymbols));
581     else if (ReadMacro_SearchArg(pArg->Str, "EXPAND", &DoMacExp))
582     {
583       if (!AddLstMacroExpMod(&pContext->LstMacroExpMod, DoMacExp, eLstMacroExpAll))
584         WrStrErrorPos(ErrNum_TooManyMacExpMod, pArg);
585       ExpandPList(pContext->PList, pArg->Str, CtrlArg);
586     }
587     else if (ReadMacro_SearchArg(pArg->Str, "EXPIF", &DoMacExp))
588     {
589       if (!AddLstMacroExpMod(&pContext->LstMacroExpMod, DoMacExp, eLstMacroExpIf))
590         WrStrErrorPos(ErrNum_TooManyMacExpMod, pArg);
591       ExpandPList(pContext->PList, pArg->Str, CtrlArg);
592     }
593     else if (ReadMacro_SearchArg(pArg->Str, "EXPMACRO", &DoMacExp))
594     {
595       if (!AddLstMacroExpMod(&pContext->LstMacroExpMod, DoMacExp, eLstMacroExpMacro))
596         WrStrErrorPos(ErrNum_TooManyMacExpMod, pArg);
597       ExpandPList(pContext->PList, pArg->Str, CtrlArg);
598     }
599     else if (ReadMacro_SearchArg(pArg->Str, "EXPREST", &DoMacExp))
600     {
601       if (!AddLstMacroExpMod(&pContext->LstMacroExpMod, DoMacExp, eLstMacroExpRest))
602         WrStrErrorPos(ErrNum_TooManyMacExpMod, pArg);
603       ExpandPList(pContext->PList, pArg->Str, CtrlArg);
604     }
605     else if (ReadMacro_SearchArg(pArg->Str, "INTLABEL", &pContext->DoIntLabel))
606     {
607       ExpandPList(pContext->PList, pArg->Str, CtrlArg);
608     }
609     else if (ReadMacro_SearchSect(pArg->Str, "GLOBAL", &(pContext->pOutputTag->DoGlobCopy), &(pContext->pOutputTag->GlobSect)));
610     else if (ReadMacro_SearchSect(pArg->Str, "PUBLIC", &pContext->DoPublic, &(pContext->pOutputTag->PubSect)));
611     else
612     {
613       WrStrErrorPos(ErrNum_UnknownMacArg, pArg);
614       pContext->ErrFlag = True;
615     }
616   }
617   else
618   {
619     char *pDefault;
620     tStrComp Arg = *pArg;
621 
622     ExpandPList(pContext->PList, Arg.Str, CtrlArg);
623     pDefault = QuotPos(Arg.Str, '=');
624     if (pDefault)
625     {
626       *pDefault++ = '\0';
627       KillPostBlanksStrComp(&Arg);
628       KillPrefBlanksStrComp(&Arg);
629     }
630     if (!ChkMacSymbName(Arg.Str))
631     {
632       WrStrErrorPos(ErrNum_InvSymName, &Arg);
633       pContext->ErrFlag = True;
634     }
635     if (!CaseSensitive)
636       UpString(Arg.Str);
637     AddStringListLast(&(pContext->pOutputTag->ParamNames), Arg.Str);
638     AddStringListLast(&(pContext->pOutputTag->ParamDefVals), pDefault ? pDefault : "");
639     pContext->ParamCount++;
640   }
641 }
642 
ReadMacro(void)643 static void ReadMacro(void)
644 {
645   PSaveSection RunSection;
646   PMacroRec OneMacro;
647   tReadMacroContext Context;
648   LongInt HSect;
649   String MacroName;
650 
651   WasMACRO = True;
652 
653   CodeLen = 0;
654   Context.ErrFlag = False;
655 
656   /* Makronamen pruefen */
657   /* Definition nur im ersten Pass */
658 
659   if (PassNo != 1)
660     Context.ErrFlag = True;
661   else if (!ExpandStrSymbol(MacroName, sizeof(MacroName), &LabPart))
662     Context.ErrFlag = True;
663   else if (!ChkSymbName(MacroName))
664   {
665     WrXError(ErrNum_InvSymName, LabPart.Str);
666     Context.ErrFlag = True;
667   }
668 
669   /* create tag */
670 
671   Context.pOutputTag = GenerateOUTProcessor(MACRO_OutProcessor, ErrNum_OpenMacro);
672   Context.pOutputTag->Next = FirstOutputTag;
673 
674   /* check arguments, sort out control directives */
675 
676   Context.LstMacroExpMod = LstMacroExpModDefault;
677   Context.DoPublic = False;
678   Context.DoIntLabel = False;
679   Context.GlobalSymbols = False;
680   *Context.PList = '\0';
681   Context.ParamCount = 0;
682   ProcessMacroArgs(ProcessMACROArgs, &Context);
683 
684   /* contradicting macro expansion? */
685 
686   if (!ChkLstMacroExpMod(&Context.LstMacroExpMod))
687   {
688     WrError(ErrNum_ConflictingMacExpMod);
689     Context.ErrFlag = True;
690   }
691 
692   /* Abbruch bei Fehler */
693 
694   if (Context.ErrFlag)
695   {
696     ClearStringList(&(Context.pOutputTag->ParamNames));
697     ClearStringList(&(Context.pOutputTag->ParamDefVals));
698     free(Context.pOutputTag);
699     AddWaitENDM_Processor();
700     return;
701   }
702 
703   /* Bei Globalisierung Namen des Extramakros ermitteln */
704 
705   if (Context.pOutputTag->DoGlobCopy)
706   {
707     strmaxcpy(Context.pOutputTag->GName, MacroName, STRINGSIZE);
708     RunSection = SectionStack;
709     HSect = MomSectionHandle;
710     while ((HSect != Context.pOutputTag->GlobSect) && (RunSection != NULL))
711     {
712       strmaxprep(Context.pOutputTag->GName, "_", STRINGSIZE);
713       strmaxprep(Context.pOutputTag->GName, GetSectionName(HSect), STRINGSIZE);
714       HSect = RunSection->Handle;
715       RunSection = RunSection->Next;
716     }
717   }
718   if (!Context.DoPublic)
719     Context.pOutputTag->PubSect = MomSectionHandle;
720 
721   /* chain in */
722 
723   OneMacro = (PMacroRec) calloc(1, sizeof(MacroRec));
724   OneMacro->FirstLine =
725   OneMacro->ParamNames =
726   OneMacro->ParamDefVals = NULL;
727   Context.pOutputTag->Mac = OneMacro;
728 
729   if ((MacroOutput) && (Context.pOutputTag->DoExport))
730   {
731     errno = 0;
732     fprintf(MacroFile, "%s MACRO %s\n",
733             Context.pOutputTag->DoGlobCopy ? Context.pOutputTag->GName : MacroName,
734             Context.PList);
735     ChkIO(ErrNum_FileWriteError);
736   }
737 
738   OneMacro->UseCounter = 0;
739   OneMacro->Name = as_strdup(MacroName);
740   OneMacro->ParamCount = Context.ParamCount;
741   OneMacro->FirstLine = NULL;
742   OneMacro->LstMacroExpMod = Context.LstMacroExpMod;
743   OneMacro->LocIntLabel = Context.DoIntLabel;
744   OneMacro->GlobalSymbols = Context.GlobalSymbols;
745 
746   FirstOutputTag = Context.pOutputTag;
747 }
748 
749 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
750 /* Beendigung der Expansion eines Makros */
751 
MACRO_Cleanup(PInputTag PInp)752 static void MACRO_Cleanup(PInputTag PInp)
753 {
754   ClearStringList(&(PInp->Params));
755 }
756 
MACRO_GetPos(PInputTag PInp,char * dest,size_t DestSize)757 static Boolean MACRO_GetPos(PInputTag PInp, char *dest, size_t DestSize)
758 {
759   String Tmp;
760 
761   as_snprintf(Tmp, sizeof(Tmp), LongIntFormat, PInp->LineZ - 1);
762   as_snprintf(dest, DestSize, "%s(%s) ", PInp->SpecName.Str, Tmp);
763   return False;
764 }
765 
MACRO_Restorer(PInputTag PInp)766 static void MACRO_Restorer(PInputTag PInp)
767 {
768   /* discard the local symbol space */
769 
770   if (!PInp->GlobalSymbols)
771     PopLocHandle();
772 
773   /* undo the recursion counter by one */
774 
775   if ((PInp->Macro) && (PInp->Macro->UseCounter > 0))
776     PInp->Macro->UseCounter--;
777 
778   /* restore list flag */
779 
780   DoLst = PInp->OrigDoLst;
781 
782   /* decrement macro nesting counter only if this actually was a macro */
783 
784   if (PInp->Processor == MACRO_Processor)
785     MacroNestLevel--;
786 }
787 
788 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
789 /* Dies initialisiert eine Makroexpansion */
790 
ExpandMacro(PMacroRec OneMacro)791 static void ExpandMacro(PMacroRec OneMacro)
792 {
793   int z1, z2;
794   StringRecPtr Lauf, pDefault, pParamName, pArg;
795   PInputTag Tag = NULL;
796   Boolean NamedArgs;
797   char *p;
798 
799   CodeLen = 0;
800 
801   if ((NestMax > 0) && (OneMacro->UseCounter > NestMax)) WrError(ErrNum_RekMacro);
802   else
803   {
804     OneMacro->UseCounter++;
805 
806     /* 1. Tag erzeugen */
807 
808     Tag = GenerateProcessor();
809     Tag->Processor = MACRO_Processor;
810     Tag->Restorer  = MACRO_Restorer;
811     Tag->Cleanup   = MACRO_Cleanup;
812     Tag->GetPos    = MACRO_GetPos;
813     Tag->Macro     = OneMacro;
814     Tag->GlobalSymbols = OneMacro->GlobalSymbols;
815     Tag->UsesNumArgs = OneMacro->UsesNumArgs;
816     Tag->UsesAllArgs = OneMacro->UsesAllArgs;
817     strmaxcpy(Tag->SpecName.Str, OneMacro->Name, STRINGSIZE);
818     strmaxcpy(Tag->SaveAttr, AttrPart.Str, STRINGSIZE);
819     if (OneMacro->LocIntLabel)
820       strmaxcpy(Tag->SaveLabel, LabPart.Str, STRINGSIZE);
821     Tag->IsMacro   = True;
822 
823     /* 2. Store special parameters - in the original form.
824           Omit this if they aren't used at all in the macro's body. */
825 
826     Tag->NumArgs[0] = '\0';
827     if (Tag->UsesNumArgs)
828       as_snprintf(Tag->NumArgs, sizeof(Tag->NumArgs), "%d", ArgCnt);
829     Tag->AllArgs[0] = '\0';
830     if (Tag->UsesAllArgs)
831     {
832       for (z1 = 1; z1 <= ArgCnt; z1++)
833       {
834         if (z1 != 1) strmaxcat(Tag->AllArgs, ",", STRINGSIZE);
835         strmaxcat(Tag->AllArgs, ArgStr[z1].Str, STRINGSIZE);
836       }
837     }
838     Tag->ParCnt = OneMacro->ParamCount;
839 
840     /* 3. generate argument list */
841 
842     /* 3a. initialize with empty defaults - order is irrelevant at this point: */
843 
844     for (z1 = OneMacro->ParamCount; z1 >= 1; z1--)
845       AddStringListFirst(&(Tag->Params), NULL);
846 
847     /* 3b. walk over given arguments */
848 
849     NamedArgs = False;
850     for (z1 = 1; z1 <= ArgCnt; z1++)
851     {
852       if (!CaseSensitive) UpString(ArgStr[z1].Str);
853 
854       /* explicit name given? */
855 
856       p = QuotPos(ArgStr[z1].Str, '=');
857 
858       /* if parameter name given... */
859 
860       if (p)
861       {
862         /* split it off */
863 
864         *p++ = '\0';
865         KillPostBlanksStrComp(&ArgStr[z1]);
866         KillPrefBlanks(p);
867 
868         /* search parameter by name */
869 
870         for (pParamName = OneMacro->ParamNames, pArg = Tag->Params;
871              pParamName; pParamName = pParamName->Next, pArg = pArg->Next)
872           if (!strcmp(ArgStr[z1].Str, pParamName->Content))
873           {
874             if (pArg->Content)
875             {
876               WrXError(ErrNum_MacArgRedef, pParamName->Content);
877               free(pArg->Content);
878             }
879             pArg->Content = as_strdup(p);
880             break;
881           }
882         if (!pParamName)
883           WrStrErrorPos(ErrNum_UndefKeyArg, &ArgStr[z1]);
884 
885         /* set flag that no unnamed args are any longer allowed */
886 
887         NamedArgs = True;
888       }
889 
890       /* do not mix unnamed with named arguments: */
891 
892       else if (NamedArgs)
893         WrError(ErrNum_NoPosArg);
894 
895       /* empty positional parameters mean using defaults - insert non-empty args here: */
896 
897       else if ((z1 <= OneMacro->ParamCount) && (strlen(ArgStr[z1].Str) > 0))
898       {
899         pArg = Tag->Params;
900         pParamName = OneMacro->ParamNames;
901         for (z2 = 0; z2 < z1 - 1; z2++)
902         {
903           pParamName = pParamName->Next;
904           pArg = pArg->Next;
905         }
906         if (pArg->Content)
907         {
908           WrXError(ErrNum_MacArgRedef, pParamName->Content);
909           free(pArg->Content);
910         }
911         pArg->Content = as_strdup(ArgStr[z1].Str);
912       }
913 
914       /* excess unnamed arguments: append at end of list */
915 
916       else if (z1 > OneMacro->ParamCount)
917         AddStringListLast(&(Tag->Params), ArgStr[z1].Str);
918     }
919 
920     /* 3c. fill in defaults */
921 
922     for (pParamName = OneMacro->ParamNames, pArg = Tag->Params, pDefault = OneMacro->ParamDefVals;
923              pParamName; pParamName = pParamName->Next, pArg = pArg->Next, pDefault = pDefault->Next)
924       if (!pArg->Content)
925         pArg->Content = as_strdup(pDefault->Content);
926 
927     /* 4. Zeilenliste anhaengen */
928 
929     Tag->Lines = OneMacro->FirstLine;
930     Tag->IsEmpty = !OneMacro->FirstLine;
931     Lauf = OneMacro->FirstLine;
932     while (Lauf)
933     {
934       Tag->LineCnt++;
935       Lauf = Lauf->Next;
936     }
937   }
938 
939   /* 5. anhaengen */
940 
941   if (Tag)
942   {
943     if (IfAsm)
944     {
945       /* override has higher prio, so apply as second */
946 
947       NextDoLst = ApplyLstMacroExpMod(DoLst, &OneMacro->LstMacroExpMod);
948       NextDoLst = ApplyLstMacroExpMod(NextDoLst, &LstMacroExpModOverride);
949       Tag->Next = FirstInputTag;
950       FirstInputTag = Tag;
951       MacroNestLevel++;
952     }
953     else
954     {
955       ClearStringList(&(Tag->Params)); free(Tag);
956     }
957   }
958 }
959 
960 /*-------------------------------------------------------------------------*/
961 /* vorzeitiger Abbruch eines Makros */
962 
ExpandEXITM(void)963 static void ExpandEXITM(void)
964 {
965   WasMACRO = True;
966 
967   if (!ChkArgCnt(0, 0));
968   else if (!FirstInputTag) WrError(ErrNum_EXITMOutsideMacro);
969   else if (!FirstInputTag->IsMacro) WrError(ErrNum_EXITMOutsideMacro);
970   else if (IfAsm)
971   {
972     FirstInputTag->Cleanup(FirstInputTag);
973     RestoreIFs(FirstInputTag->IfLevel);
974     FirstInputTag->IsEmpty = True;
975   }
976 }
977 
978 /*-------------------------------------------------------------------------*/
979 /* discard first argument */
980 
ExpandSHIFT(void)981 static void ExpandSHIFT(void)
982 {
983   PInputTag RunTag;
984 
985   WasMACRO = True;
986 
987   if (!ChkArgCnt(0, 0));
988   else if (!FirstInputTag) WrError(ErrNum_EXITMOutsideMacro);
989   else if (!FirstInputTag->IsMacro) WrError(ErrNum_EXITMOutsideMacro);
990   else if (IfAsm)
991   {
992     for (RunTag = FirstInputTag; RunTag; RunTag = RunTag->Next)
993       if (RunTag->Processor == MACRO_Processor)
994         break;
995 
996     if ((RunTag) && (RunTag->Params))
997     {
998       GetAndCutStringList(&(RunTag->Params));
999       RunTag->ParCnt--;
1000       ComputeMacroStrings(RunTag);
1001     }
1002   }
1003 }
1004 
1005 /*-------------------------------------------------------------------------*/
1006 /*--- IRP (was das bei MASM auch immer heissen mag...)
1007       Ach ja: Individual Repeat! Danke Bernhard, jetzt hab'
1008       ich's gerafft! -----------------------*/
1009 
1010 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1011 /* Diese Routine liefert bei der Expansion eines IRP-Statements die expan-
1012   dierten Zeilen */
1013 
IRP_Processor(PInputTag PInp,char * erg)1014 Boolean IRP_Processor(PInputTag PInp, char *erg)
1015 {
1016   StringRecPtr Lauf;
1017   int z;
1018   Boolean Result;
1019 
1020   Result = True;
1021 
1022   /* increment line counter only if contents came from a true file */
1023 
1024   CurrLine = PInp->StartLine;
1025   if (PInp->FromFile)
1026     CurrLine += PInp->LineZ;
1027 
1028   /* first line? Then open new symbol space and reset line pointer */
1029 
1030   if (PInp->LineZ == 1)
1031   {
1032     if (!PInp->GlobalSymbols)
1033     {
1034       if (!PInp->First) PopLocHandle();
1035       PushLocHandle(GetLocHandle());
1036     }
1037     PInp->First = False;
1038     PInp->LineRun = PInp->Lines;
1039   }
1040 
1041   /* extract line */
1042 
1043   strcpy(erg, PInp->LineRun->Content);
1044   PInp->LineRun = PInp->LineRun->Next;
1045 
1046   /* expand iteration parameter */
1047 
1048   Lauf = PInp->Params; for (z = 1; z <= PInp->ParZ - 1; z++)
1049     Lauf = Lauf->Next;
1050   ExpandLine(Lauf->Content, 1, erg, STRINGSIZE);
1051 
1052   /* end of body? then reset to line 1 and exit if this was the last iteration */
1053 
1054   if (++(PInp->LineZ) > PInp->LineCnt)
1055   {
1056     PInp->LineZ = 1;
1057     if (++(PInp->ParZ) > PInp->ParCnt)
1058       Result = False;
1059   }
1060 
1061   return Result;
1062 }
1063 
1064 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1065 /* Aufraeumroutine IRP/IRPC */
1066 
IRP_Cleanup(PInputTag PInp)1067 static void IRP_Cleanup(PInputTag PInp)
1068 {
1069   StringRecPtr Lauf;
1070 
1071   /* letzten Parameter sichern, wird evtl. noch fuer GetPos gebraucht!
1072      ... SaveAttr ist aber frei */
1073   if (PInp->Processor == IRP_Processor)
1074   {
1075     for (Lauf = PInp->Params; Lauf->Next; Lauf = Lauf->Next);
1076     strmaxcpy(PInp->SaveAttr, Lauf->Content, STRINGSIZE);
1077   }
1078 
1079   ClearStringList(&(PInp->Lines));
1080   ClearStringList(&(PInp->Params));
1081 }
1082 
1083 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1084 /* Posisionsangabe im IRP(C) fuer Fehlermeldungen */
1085 
IRP_GetPos(PInputTag PInp,char * dest,size_t DestSize)1086 static Boolean IRP_GetPos(PInputTag PInp, char *dest, size_t DestSize)
1087 {
1088   int z, ParZ = PInp->ParZ, LineZ = PInp->LineZ;
1089   const char *IRPType;
1090   char *IRPVal, tmp[10];
1091 
1092   /* LineZ/ParZ already hopped to next line - step one back: */
1093 
1094   if (--LineZ <= 0)
1095   {
1096     LineZ = PInp->LineCnt;
1097     ParZ--;
1098   }
1099 
1100   if (PInp->Processor == IRP_Processor)
1101   {
1102     IRPType = "IRP";
1103     if (*PInp->SaveAttr != '\0')
1104       IRPVal = PInp->SaveAttr;
1105     else
1106     {
1107       StringRecPtr Lauf = PInp->Params;
1108 
1109       for (z = 1; z <= ParZ - 1; z++)
1110         Lauf = Lauf->Next;
1111       IRPVal = Lauf->Content;
1112     }
1113   }
1114   else
1115   {
1116     IRPType = "IRPC";
1117     as_snprintf(tmp, sizeof(tmp), "'%c'", PInp->SpecName.Str[ParZ - 1]);
1118     IRPVal = tmp;
1119   }
1120 
1121   as_snprintf(dest, DestSize, "%s:%s(%ld) ", IRPType, IRPVal, (long)LineZ);
1122 
1123   return False;
1124 }
1125 
1126 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1127 /* Diese Routine sammelt waehrend der Definition eines IRP(C)-Statements die
1128   Quellzeilen ein */
1129 
IRP_OutProcessor(void)1130 static void IRP_OutProcessor(void)
1131 {
1132   POutputTag Tmp;
1133   StringRecPtr Dummy;
1134   String s;
1135 
1136   WasMACRO = True;
1137 
1138   /* Schachtelungen mitzaehlen */
1139 
1140   if (MacroStart())
1141     FirstOutputTag->NestLevel++;
1142   else if (MacroEnd())
1143     FirstOutputTag->NestLevel--;
1144 
1145   /* falls noch nicht zuende, weiterzaehlen */
1146 
1147   if (FirstOutputTag->NestLevel > -1)
1148   {
1149     strmaxcpy(s, OneLine, STRINGSIZE); KillCtrl(s);
1150     CompressLine(GetStringListFirst(FirstOutputTag->ParamNames, &Dummy), 1, s, sizeof(s), CaseSensitive);
1151     AddStringListLast(&(FirstOutputTag->Tag->Lines), s);
1152     FirstOutputTag->Tag->LineCnt++;
1153   }
1154 
1155   /* alles zusammen? Dann umhaengen */
1156 
1157   if (FirstOutputTag->NestLevel == -1)
1158   {
1159     Tmp = FirstOutputTag;
1160     FirstOutputTag = FirstOutputTag->Next;
1161     Tmp->Tag->IsEmpty = !Tmp->Tag->Lines;
1162     if (IfAsm)
1163     {
1164       NextDoLst = ApplyLstMacroExpMod(DoLst, &LstMacroExpModDefault);
1165       NextDoLst = ApplyLstMacroExpMod(NextDoLst, &LstMacroExpModOverride);
1166       Tmp->Tag->Next = FirstInputTag;
1167       FirstInputTag = Tmp->Tag;
1168     }
1169     else
1170     {
1171       ClearStringList(&(Tmp->Tag->Lines));
1172       ClearStringList(&(Tmp->Tag->Params));
1173       free(Tmp->Tag);
1174     }
1175     ClearStringList(&(Tmp->ParamNames));
1176     free(Tmp);
1177   }
1178 }
1179 
1180 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1181 /* Initialisierung der IRP-Bearbeitung */
1182 
1183 typedef struct
1184 {
1185   Boolean ErrFlag;
1186   Boolean GlobalSymbols;
1187   int ArgCnt;
1188   POutputTag pOutputTag;
1189   StringList Params;
1190 } tExpandIRPContext;
1191 
ProcessIRPArgs(Boolean CtrlArg,const tStrComp * pArg,void * pUser)1192 static void ProcessIRPArgs(Boolean CtrlArg, const tStrComp *pArg, void *pUser)
1193 {
1194   tExpandIRPContext *pContext = (tExpandIRPContext*)pUser;
1195 
1196   if (CtrlArg)
1197   {
1198     if (ReadMacro_SearchArg(pArg->Str, "GLOBALSYMBOLS", &pContext->GlobalSymbols));
1199     else
1200     {
1201       WrStrErrorPos(ErrNum_UnknownMacArg, pArg);
1202       pContext->ErrFlag = True;
1203     }
1204   }
1205   else
1206   {
1207     /* differentiate placeholder & arguments */
1208 
1209     if (0 == pContext->ArgCnt)
1210     {
1211       if (!ChkMacSymbName(pArg->Str))
1212       {
1213         WrStrErrorPos(ErrNum_InvSymName, pArg);
1214         pContext->ErrFlag = True;
1215       }
1216       else
1217         AddStringListFirst(&(pContext->pOutputTag->ParamNames), pArg->Str);
1218     }
1219     else
1220     {
1221       if (!CaseSensitive)
1222         UpString(pArg->Str);
1223       AddStringListLast(&(pContext->Params), pArg->Str);
1224     }
1225     pContext->ArgCnt++;
1226   }
1227 }
1228 
ExpandIRP(void)1229 static void ExpandIRP(void)
1230 {
1231   PInputTag Tag;
1232   tExpandIRPContext Context;
1233 
1234   WasMACRO = True;
1235 
1236   /* 0. terminate if conditional assembly bites */
1237 
1238   if (!IfAsm)
1239   {
1240     AddWaitENDM_Processor();
1241     return;
1242   }
1243 
1244   /* 1. Parameter pruefen */
1245 
1246   Context.ErrFlag = False;
1247   Context.GlobalSymbols = False;
1248   Context.ArgCnt = 0;
1249   Context.Params = NULL;
1250 
1251   Context.pOutputTag = GenerateOUTProcessor(IRP_OutProcessor, ErrNum_OpenIRP);
1252   Context.pOutputTag->Next      = FirstOutputTag;
1253   ProcessMacroArgs(ProcessIRPArgs, &Context);
1254 
1255   /* at least parameter & one arg */
1256 
1257   if (!ChkArgCntExt(Context.ArgCnt, 2, ArgCntMax))
1258     Context.ErrFlag = True;
1259   if (Context.ErrFlag)
1260   {
1261     ClearStringList(&(Context.pOutputTag->ParamNames));
1262     ClearStringList(&(Context.pOutputTag->ParamDefVals));
1263     ClearStringList(&(Context.Params));
1264     free(Context.pOutputTag);
1265     AddWaitENDM_Processor();
1266     return;
1267   }
1268 
1269   /* 2. Tag erzeugen */
1270 
1271   Tag = GenerateProcessor();
1272   Tag->ParCnt    = Context.ArgCnt - 1;
1273   Tag->Params    = Context.Params;
1274   Tag->Processor = IRP_Processor;
1275   Tag->Restorer  = MACRO_Restorer;
1276   Tag->Cleanup   = IRP_Cleanup;
1277   Tag->GetPos    = IRP_GetPos;
1278   Tag->GlobalSymbols = Context.GlobalSymbols;
1279   Tag->ParZ      = 1;
1280   Tag->IsMacro   = True;
1281   *Tag->SaveAttr = '\0';
1282   Context.pOutputTag->Tag = Tag;
1283 
1284   /* 4. einbetten */
1285 
1286   FirstOutputTag = Context.pOutputTag;
1287 }
1288 
1289 /*--- IRPC: dito fuer Zeichen eines Strings ---------------------------------*/
1290 
1291 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1292 /* Diese Routine liefert bei der Expansion eines IRPC-Statements die expan-
1293   dierten Zeilen */
1294 
IRPC_Processor(PInputTag PInp,char * erg)1295 Boolean IRPC_Processor(PInputTag PInp, char *erg)
1296 {
1297   Boolean Result;
1298   char tmp[5];
1299 
1300   Result = True;
1301 
1302   /* increment line counter only if contents came from a true file */
1303 
1304   CurrLine = PInp->StartLine;
1305   if (PInp->FromFile)
1306     CurrLine += PInp->LineZ;
1307 
1308   /* first line? Then open new symbol space and reset line pointer */
1309 
1310   if (PInp->LineZ == 1)
1311   {
1312     if (!PInp->GlobalSymbols)
1313     {
1314       if (!PInp->First) PopLocHandle();
1315       PushLocHandle(GetLocHandle());
1316     }
1317     PInp->First = False;
1318     PInp->LineRun = PInp->Lines;
1319   }
1320 
1321   /* extract line */
1322 
1323   strcpy(erg, PInp->LineRun->Content);
1324   PInp->LineRun = PInp->LineRun->Next;
1325 
1326   /* extract iteration parameter */
1327 
1328   *tmp = PInp->SpecName.Str[PInp->ParZ - 1];
1329   tmp[1] = '\0';
1330   ExpandLine(tmp, 1, erg, STRINGSIZE);
1331 
1332   /* end of body? then reset to line 1 and exit if this was the last iteration */
1333 
1334   if (++(PInp->LineZ) > PInp->LineCnt)
1335   {
1336     PInp->LineZ = 1;
1337     if (++(PInp->ParZ) > PInp->ParCnt)
1338       Result = False;
1339   }
1340 
1341   return Result;
1342 }
1343 
1344 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1345 /* Initialisierung der IRPC-Bearbeitung */
1346 
1347 typedef struct
1348 {
1349   Boolean ErrFlag;
1350   Boolean GlobalSymbols;
1351   int ArgCnt;
1352   POutputTag pOutputTag;
1353   String ParameterStr;
1354   tStrComp Parameter;
1355 } tExpandIRPCContext;
1356 
ProcessIRPCArgs(Boolean CtrlArg,const tStrComp * pArg,void * pUser)1357 static void ProcessIRPCArgs(Boolean CtrlArg, const tStrComp *pArg, void *pUser)
1358 {
1359   tExpandIRPCContext *pContext = (tExpandIRPCContext*)pUser;
1360 
1361   if (CtrlArg)
1362   {
1363     if (ReadMacro_SearchArg(pArg->Str, "GLOBALSYMBOLS", &pContext->GlobalSymbols));
1364     else
1365     {
1366       WrStrErrorPos(ErrNum_UnknownMacArg, pArg);
1367       pContext->ErrFlag = True;
1368     }
1369   }
1370   else
1371   {
1372     if (0 == pContext->ArgCnt)
1373     {
1374       if (!ChkMacSymbName(pArg->Str))
1375       {
1376         WrStrErrorPos(ErrNum_InvSymName, pArg);
1377         pContext->ErrFlag = True;
1378       }
1379       else
1380         AddStringListFirst(&(pContext->pOutputTag->ParamNames), pArg->Str);
1381     }
1382     else
1383     {
1384       Boolean OK;
1385 
1386       EvalStrStringExpression(pArg, &OK, pContext->Parameter.Str);
1387       pContext->Parameter.Pos = pArg->Pos;
1388       if (!OK)
1389         pContext->ErrFlag = True;
1390     }
1391     pContext->ArgCnt++;
1392   }
1393 }
1394 
ExpandIRPC(void)1395 static void ExpandIRPC(void)
1396 {
1397   PInputTag Tag;
1398   tExpandIRPCContext Context;
1399 
1400   WasMACRO = True;
1401 
1402   /* 0. terminate if conditinal assembly bites */
1403 
1404   if (!IfAsm)
1405   {
1406     AddWaitENDM_Processor();
1407     return;
1408   }
1409 
1410   /* 1.Parameter pruefen */
1411 
1412   Context.ErrFlag = False;
1413   Context.GlobalSymbols = False;
1414   Context.ArgCnt = 0;
1415   StrCompMkTemp(&Context.Parameter, Context.ParameterStr);
1416   StrCompReset(&Context.Parameter);
1417 
1418   Context.pOutputTag = GenerateOUTProcessor(IRP_OutProcessor, ErrNum_OpenIRPC);
1419   Context.pOutputTag->Next = FirstOutputTag;
1420   ProcessMacroArgs(ProcessIRPCArgs, &Context);
1421 
1422   /* parameter & string */
1423 
1424   if (!ChkArgCntExt(Context.ArgCnt, 2, ArgCntMax))
1425     Context.ErrFlag = True;
1426   if (Context.ErrFlag)
1427   {
1428     ClearStringList(&(Context.pOutputTag->ParamNames));
1429     AddWaitENDM_Processor();
1430     return;
1431   }
1432 
1433   /* 2. Tag erzeugen */
1434 
1435   Tag = GenerateProcessor();
1436   Tag->ParCnt    = strlen(Context.Parameter.Str);
1437   Tag->Processor = IRPC_Processor;
1438   Tag->Restorer  = MACRO_Restorer;
1439   Tag->Cleanup   = IRP_Cleanup;
1440   Tag->GetPos    = IRP_GetPos;
1441   Tag->GlobalSymbols = Context.GlobalSymbols;
1442   Tag->ParZ      = 1;
1443   Tag->IsMacro   = True;
1444   *Tag->SaveAttr = '\0';
1445   StrCompCopy(&Tag->SpecName, &Context.Parameter);
1446 
1447   /* 4. einbetten */
1448 
1449   Context.pOutputTag->Tag = Tag;
1450   FirstOutputTag = Context.pOutputTag;
1451 }
1452 
1453 /*--- Repetition -----------------------------------------------------------*/
1454 
REPT_Cleanup(PInputTag PInp)1455 static void REPT_Cleanup(PInputTag PInp)
1456 {
1457   ClearStringList(&(PInp->Lines));
1458 }
1459 
REPT_GetPos(PInputTag PInp,char * dest,size_t DestSize)1460 static Boolean REPT_GetPos(PInputTag PInp, char *dest, size_t DestSize)
1461 {
1462   int z1 = PInp->ParZ, z2 = PInp->LineZ;
1463 
1464   if (--z2 <= 0)
1465   {
1466     z2 = PInp->LineCnt;
1467     z1--;
1468   }
1469   as_snprintf(dest, DestSize, "REPT %ld(%ld)", (long)z1, (long)z2);
1470   return False;
1471 }
1472 
REPT_Processor(PInputTag PInp,char * erg)1473 Boolean REPT_Processor(PInputTag PInp, char *erg)
1474 {
1475   Boolean Result;
1476 
1477   Result = True;
1478 
1479   /* increment line counter only if contents came from a true file */
1480 
1481   CurrLine = PInp->StartLine;
1482   if (PInp->FromFile)
1483     CurrLine += PInp->LineZ;
1484 
1485   /* first line? Then open new symbol space and reset line pointer */
1486 
1487   if (PInp->LineZ == 1)
1488   {
1489     if (!PInp->GlobalSymbols)
1490     {
1491       if (!PInp->First) PopLocHandle();
1492       PushLocHandle(GetLocHandle());
1493     }
1494     PInp->First = False;
1495     PInp->LineRun = PInp->Lines;
1496   }
1497 
1498   /* extract line */
1499 
1500   strcpy(erg, PInp->LineRun->Content);
1501   PInp->LineRun = PInp->LineRun->Next;
1502 
1503   /* last line of body? Then increment count and stop if last iteration */
1504 
1505   if ((++PInp->LineZ) > PInp->LineCnt)
1506   {
1507     PInp->LineZ = 1;
1508     if ((++PInp->ParZ) > PInp->ParCnt)
1509       Result = False;
1510   }
1511 
1512   return Result;
1513 }
1514 
REPT_OutProcessor(void)1515 static void REPT_OutProcessor(void)
1516 {
1517   POutputTag Tmp;
1518 
1519   WasMACRO = True;
1520 
1521   /* Schachtelungen mitzaehlen */
1522 
1523   if (MacroStart())
1524     FirstOutputTag->NestLevel++;
1525   else if (MacroEnd())
1526     FirstOutputTag->NestLevel--;
1527 
1528   /* falls noch nicht zuende, weiterzaehlen */
1529 
1530   if (FirstOutputTag->NestLevel > -1)
1531   {
1532     AddStringListLast(&(FirstOutputTag->Tag->Lines), OneLine);
1533     FirstOutputTag->Tag->LineCnt++;
1534   }
1535 
1536   /* alles zusammen? Dann umhaengen */
1537 
1538   if (FirstOutputTag->NestLevel == -1)
1539   {
1540     Tmp = FirstOutputTag;
1541     FirstOutputTag = FirstOutputTag->Next;
1542     Tmp->Tag->IsEmpty = !Tmp->Tag->Lines;
1543     if ((IfAsm) && (Tmp->Tag->ParCnt > 0))
1544     {
1545       NextDoLst = ApplyLstMacroExpMod(DoLst, &LstMacroExpModDefault);
1546       NextDoLst = ApplyLstMacroExpMod(NextDoLst, &LstMacroExpModOverride);
1547       Tmp->Tag->Next = FirstInputTag;
1548       FirstInputTag = Tmp->Tag;
1549     }
1550     else
1551     {
1552       ClearStringList(&(Tmp->Tag->Lines));
1553       free(Tmp->Tag);
1554     }
1555     free(Tmp);
1556   }
1557 }
1558 
1559 typedef struct
1560 {
1561   Boolean ErrFlag;
1562   Boolean GlobalSymbols;
1563   int ArgCnt;
1564   LongInt ReptCount;
1565 } tExpandREPTContext;
1566 
ProcessREPTArgs(Boolean CtrlArg,const tStrComp * pArg,void * pUser)1567 static void ProcessREPTArgs(Boolean CtrlArg, const tStrComp *pArg, void *pUser)
1568 {
1569   tExpandREPTContext *pContext = (tExpandREPTContext*)pUser;
1570 
1571   if (CtrlArg)
1572   {
1573     if (ReadMacro_SearchArg(pArg->Str, "GLOBALSYMBOLS", &pContext->GlobalSymbols));
1574     else
1575     {
1576       WrStrErrorPos(ErrNum_UnknownMacArg, pArg);
1577       pContext->ErrFlag = True;
1578     }
1579   }
1580   else
1581   {
1582     Boolean ValOK;
1583     tSymbolFlags SymbolFlags;
1584 
1585     pContext->ReptCount = EvalStrIntExpressionWithFlags(pArg, Int32, &ValOK, &SymbolFlags);
1586     if (mFirstPassUnknown(SymbolFlags))
1587       WrStrErrorPos(ErrNum_FirstPassCalc, pArg);
1588     if (!ValOK || mFirstPassUnknown(SymbolFlags))
1589       pContext->ErrFlag = True;
1590     pContext->ArgCnt++;
1591   }
1592 }
1593 
ExpandREPT(void)1594 static void ExpandREPT(void)
1595 {
1596   PInputTag Tag;
1597   POutputTag Neu;
1598   tExpandREPTContext Context;
1599 
1600   WasMACRO = True;
1601 
1602   /* 0. skip everything when conditional assembly is off */
1603 
1604   if (!IfAsm)
1605   {
1606     AddWaitENDM_Processor();
1607     return;
1608   }
1609 
1610   /* 1. Repetitionszahl ermitteln */
1611 
1612   Context.GlobalSymbols = False;
1613   Context.ReptCount = 0;
1614   Context.ErrFlag = False;
1615   Context.ArgCnt = 0;
1616   ProcessMacroArgs(ProcessREPTArgs, &Context);
1617 
1618   /* rept count must be present only once */
1619 
1620   if (!ChkArgCntExt(Context.ArgCnt, 1, 1))
1621     Context.ErrFlag = True;
1622   if (Context.ErrFlag)
1623   {
1624     AddWaitENDM_Processor();
1625     return;
1626   }
1627 
1628   /* 2. Tag erzeugen */
1629 
1630   Tag = GenerateProcessor();
1631   Tag->ParCnt    = Context.ReptCount;
1632   Tag->Processor = REPT_Processor;
1633   Tag->Restorer  = MACRO_Restorer;
1634   Tag->Cleanup   = REPT_Cleanup;
1635   Tag->GetPos    = REPT_GetPos;
1636   Tag->GlobalSymbols = Context.GlobalSymbols;
1637   Tag->IsMacro   = True;
1638   Tag->ParZ      = 1;
1639 
1640   /* 3. einbetten */
1641 
1642   Neu = GenerateOUTProcessor(REPT_OutProcessor, ErrNum_OpenREPT);
1643   Neu->Next      = FirstOutputTag;
1644   Neu->Tag       = Tag;
1645   FirstOutputTag = Neu;
1646 }
1647 
1648 /*- bedingte Wiederholung -------------------------------------------------------*/
1649 
WHILE_Cleanup(PInputTag PInp)1650 static void WHILE_Cleanup(PInputTag PInp)
1651 {
1652   ClearStringList(&(PInp->Lines));
1653 }
1654 
WHILE_GetPos(PInputTag PInp,char * dest,size_t DestSize)1655 static Boolean WHILE_GetPos(PInputTag PInp, char *dest, size_t DestSize)
1656 {
1657   int z1 = PInp->ParZ, z2 = PInp->LineZ;
1658 
1659   if (--z2 <= 0)
1660   {
1661     z2 = PInp->LineCnt;
1662     z1--;
1663   }
1664   as_snprintf(dest, DestSize, "WHILE %ld/%ld", (long)z1, (long)z2);
1665   return False;
1666 }
1667 
WHILE_Processor(PInputTag PInp,char * erg)1668 Boolean WHILE_Processor(PInputTag PInp, char *erg)
1669 {
1670   int z;
1671   Boolean OK, Result;
1672 
1673   /* increment line counter only if this came from a true file */
1674 
1675   CurrLine = PInp->StartLine;
1676   if (PInp->FromFile)
1677     CurrLine += PInp->LineZ;
1678 
1679   /* if this is the first line of the loop body, open a new handle
1680      for macro-local symbols and drop the old one if this was not the
1681      first pass through the body. */
1682 
1683   if (PInp->LineZ == 1)
1684   {
1685     if (!PInp->GlobalSymbols)
1686     {
1687       if (!PInp->First)
1688         PopLocHandle();
1689       PushLocHandle(GetLocHandle());
1690     }
1691     PInp->First = False;
1692     PInp->LineRun = PInp->Lines;
1693   }
1694 
1695   /* evaluate condition before first line */
1696 
1697   if (PInp->LineZ == 1)
1698   {
1699     z = EvalStrIntExpression(&PInp->SpecName, Int32, &OK);
1700     Result = (OK && (z != 0));
1701   }
1702   else
1703     Result = True;
1704 
1705   if (Result)
1706   {
1707     /* get line of body */
1708 
1709     strcpy(erg, PInp->LineRun->Content);
1710     PInp->LineRun = PInp->LineRun->Next;
1711 
1712     /* in case this is the last line of the body, reset counters */
1713 
1714     if ((++PInp->LineZ) > PInp->LineCnt)
1715     {
1716       PInp->LineZ = 1;
1717       PInp->ParZ++;
1718     }
1719   }
1720 
1721   /* nasty last line... */
1722 
1723   else
1724     *erg = '\0';
1725 
1726   return Result;
1727 }
1728 
WHILE_OutProcessor(void)1729 static void WHILE_OutProcessor(void)
1730 {
1731   POutputTag Tmp;
1732   Boolean OK;
1733   tSymbolFlags SymbolFlags;
1734   LongInt Erg;
1735 
1736   WasMACRO = True;
1737 
1738   /* Schachtelungen mitzaehlen */
1739 
1740   if (MacroStart())
1741     FirstOutputTag->NestLevel++;
1742   else if (MacroEnd())
1743     FirstOutputTag->NestLevel--;
1744 
1745   /* falls noch nicht zuende, weiterzaehlen */
1746 
1747   if (FirstOutputTag->NestLevel > -1)
1748   {
1749     AddStringListLast(&(FirstOutputTag->Tag->Lines), OneLine);
1750     FirstOutputTag->Tag->LineCnt++;
1751   }
1752 
1753   /* alles zusammen? Dann umhaengen */
1754 
1755   if (FirstOutputTag->NestLevel == -1)
1756   {
1757     Tmp = FirstOutputTag;
1758     FirstOutputTag = FirstOutputTag->Next;
1759     Tmp->Tag->IsEmpty = !Tmp->Tag->Lines;
1760     Erg = EvalStrIntExpressionWithFlags(&Tmp->Tag->SpecName, Int32, &OK, &SymbolFlags);
1761     if (mFirstPassUnknown(SymbolFlags))
1762     {
1763       WrError(ErrNum_FirstPassCalc);
1764       OK = False;
1765     }
1766     OK = (OK && (Erg != 0));
1767     if (IfAsm && OK)
1768     {
1769       NextDoLst = ApplyLstMacroExpMod(DoLst, &LstMacroExpModDefault);
1770       NextDoLst = ApplyLstMacroExpMod(NextDoLst, &LstMacroExpModOverride);
1771       Tmp->Tag->Next = FirstInputTag;
1772       FirstInputTag = Tmp->Tag;
1773     }
1774     else
1775     {
1776       ClearStringList(&(Tmp->Tag->Lines));
1777       free(Tmp->Tag);
1778     }
1779     free(Tmp);
1780   }
1781 }
1782 
1783 typedef struct
1784 {
1785   Boolean ErrFlag;
1786   Boolean GlobalSymbols;
1787   int ArgCnt;
1788   String SpecNameStr;
1789   tStrComp SpecName;
1790 } tExpandWHILEContext;
1791 
ProcessWHILEArgs(Boolean CtrlArg,const tStrComp * pArg,void * pUser)1792 static void ProcessWHILEArgs(Boolean CtrlArg, const tStrComp *pArg, void *pUser)
1793 {
1794   tExpandWHILEContext *pContext = (tExpandWHILEContext*)pUser;
1795 
1796   if (CtrlArg)
1797   {
1798     if (ReadMacro_SearchArg(pArg->Str, "GLOBALSYMBOLS", &pContext->GlobalSymbols));
1799     else
1800     {
1801       WrStrErrorPos(ErrNum_UnknownMacArg, pArg);
1802       pContext->ErrFlag = True;
1803     }
1804   }
1805   else
1806   {
1807     StrCompCopy(&pContext->SpecName, pArg);
1808     pContext->ArgCnt++;
1809   }
1810 }
1811 
ExpandWHILE(void)1812 static void ExpandWHILE(void)
1813 {
1814   PInputTag Tag;
1815   POutputTag Neu;
1816   tExpandWHILEContext Context;
1817 
1818   WasMACRO = True;
1819 
1820   /* 0. turned off ? */
1821 
1822   if (!IfAsm)
1823   {
1824     AddWaitENDM_Processor();
1825     return;
1826   }
1827 
1828   /* 1. Bedingung ermitteln */
1829 
1830   Context.GlobalSymbols = False;
1831   Context.ErrFlag = False;
1832   Context.ArgCnt = 0;
1833   StrCompMkTemp(&Context.SpecName, Context.SpecNameStr);
1834   StrCompReset(&Context.SpecName);
1835   ProcessMacroArgs(ProcessWHILEArgs, &Context);
1836 
1837   /* condition must be present only once */
1838 
1839   if (!ChkArgCntExt(Context.ArgCnt, 1, 1))
1840     Context.ErrFlag = True;
1841   if (Context.ErrFlag)
1842   {
1843     AddWaitENDM_Processor();
1844     return;
1845   }
1846 
1847   /* 2. Tag erzeugen */
1848 
1849   Tag = GenerateProcessor();
1850   Tag->Processor = WHILE_Processor;
1851   Tag->Restorer  = MACRO_Restorer;
1852   Tag->Cleanup   = WHILE_Cleanup;
1853   Tag->GetPos    = WHILE_GetPos;
1854   Tag->GlobalSymbols = Context.GlobalSymbols;
1855   Tag->IsMacro   = True;
1856   Tag->ParZ      = 1;
1857   StrCompCopy(&Tag->SpecName, &Context.SpecName);
1858 
1859   /* 3. einbetten */
1860 
1861   Neu = GenerateOUTProcessor(WHILE_OutProcessor, ErrNum_OpenWHILE);
1862   Neu->Next      = FirstOutputTag;
1863   Neu->Tag       = Tag;
1864   FirstOutputTag = Neu;
1865 }
1866 
1867 /*--------------------------------------------------------------------------*/
1868 /* Einziehen von Include-Files */
1869 
INCLUDE_Cleanup(PInputTag PInp)1870 static void INCLUDE_Cleanup(PInputTag PInp)
1871 {
1872   fclose(PInp->Datei);
1873   free(PInp->Buffer);
1874   LineSum += MomLineCounter;
1875   if ((*LstName != '\0') && (!QuietMode))
1876   {
1877     String Tmp;
1878 
1879     as_snprintf(Tmp, sizeof(Tmp), "%s(", NamePart(CurrFileName));
1880     as_snprcatf(Tmp, sizeof(Tmp), LongIntFormat, CurrLine);
1881     as_snprcatf(Tmp, sizeof(Tmp), ")");
1882     WrConsoleLine(Tmp, True);
1883     fflush(stdout);
1884   }
1885   if (MakeIncludeList)
1886     PopInclude();
1887 }
1888 
INCLUDE_GetPos(PInputTag PInp,char * dest,size_t DestSize)1889 static Boolean INCLUDE_GetPos(PInputTag PInp, char *dest, size_t DestSize)
1890 {
1891   String Tmp;
1892   UNUSED(PInp);
1893 
1894   as_snprintf(Tmp, sizeof(Tmp), LongIntFormat, PInp->LineZ);
1895   as_snprintf(dest, DestSize, GNUErrors ? "%s:%s" : "%s(%s) ", NamePart(PInp->SpecName.Str), Tmp);
1896   return !GNUErrors;
1897 }
1898 
INCLUDE_Processor(PInputTag PInp,char * Erg)1899 Boolean INCLUDE_Processor(PInputTag PInp, char *Erg)
1900 {
1901   Boolean Result;
1902   int Count = 1;
1903 
1904   Result = True;
1905 
1906   if (feof(PInp->Datei))
1907     *Erg = '\0';
1908   else
1909   {
1910     Count = ReadLnCont(PInp->Datei, Erg, STRINGSIZE);
1911     /**ChkIO(ErrNum_FileReadError);**/
1912   }
1913   PInp->LineZ = CurrLine = (MomLineCounter += Count);
1914   if (feof(PInp->Datei))
1915     Result = False;
1916 
1917   return Result;
1918 }
1919 
INCLUDE_Restorer(PInputTag PInp)1920 static void INCLUDE_Restorer(PInputTag PInp)
1921 {
1922   MomLineCounter = PInp->StartLine;
1923   strmaxcpy(CurrFileName, PInp->SaveAttr, STRINGSIZE);
1924   IncDepth--;
1925 }
1926 
ExpandINCLUDE(Boolean SearchPath)1927 static void ExpandINCLUDE(Boolean SearchPath)
1928 {
1929   tStrComp FNameArg;
1930   String FNameArgStr;
1931   PInputTag Tag;
1932 
1933   if (!IfAsm)
1934     return;
1935 
1936   if (!ChkArgCnt(1, 1))
1937     return;
1938 
1939   StrCompMkTemp(&FNameArg, FNameArgStr);
1940   INCLUDE_SearchCore(&FNameArg, &ArgStr[1], SearchPath);
1941 
1942   /* Tag erzeugen */
1943 
1944   Tag = GenerateProcessor();
1945   Tag->Processor = INCLUDE_Processor;
1946   Tag->Restorer  = INCLUDE_Restorer;
1947   Tag->Cleanup   = INCLUDE_Cleanup;
1948   Tag->GetPos    = INCLUDE_GetPos;
1949   Tag->Buffer    = (void *) malloc(BufferArraySize);
1950 
1951   /* Sicherung alter Daten */
1952 
1953   Tag->StartLine = MomLineCounter;
1954   strmaxcpy(Tag->SpecName.Str, FNameArg.Str, STRINGSIZE);
1955   LineCompReset(&Tag->SpecName.Pos);
1956   strmaxcpy(Tag->SaveAttr, CurrFileName, STRINGSIZE);
1957 
1958   /* Datei oeffnen */
1959 
1960 #ifdef __CYGWIN32__
1961   DeCygwinPath(FNameArg.Str);
1962 #endif
1963   Tag->Datei = fopen(FNameArg.Str, "r");
1964   if (!Tag->Datei) ChkStrIO(ErrNum_OpeningFile, &ArgStr[1]);
1965   setvbuf(Tag->Datei, (char*)Tag->Buffer, _IOFBF, BufferArraySize);
1966 
1967   /* neu besetzen */
1968 
1969   strmaxcpy(CurrFileName, FNameArg.Str, STRINGSIZE); Tag->LineZ = MomLineCounter = 0;
1970   NextIncDepth++; AddFile(FNameArg.Str);
1971   PushInclude(FNameArg.Str);
1972 
1973   /* einhaengen */
1974 
1975   Tag->Next = FirstInputTag; FirstInputTag = Tag;
1976 }
1977 
1978 /*=========================================================================*/
1979 /* Einlieferung von Zeilen */
1980 
GetNextLine(char * Line)1981 static void GetNextLine(char *Line)
1982 {
1983   PInputTag HTag;
1984 
1985   InMacroFlag = False;
1986 
1987   while ((FirstInputTag) && (FirstInputTag->IsEmpty))
1988   {
1989     FirstInputTag->Cleanup(FirstInputTag);
1990     FirstInputTag->Restorer(FirstInputTag);
1991     HTag = FirstInputTag;
1992     FirstInputTag = HTag->Next;
1993     free(HTag);
1994   }
1995 
1996   if (!FirstInputTag)
1997   {
1998     *Line = '\0';
1999     return;
2000   }
2001 
2002   if (!FirstInputTag->Processor(FirstInputTag, Line))
2003   {
2004     FirstInputTag->IsEmpty = True;
2005   }
2006 
2007   MacLineSum++;
2008 }
2009 
2010 typedef struct
2011 {
2012   char *pStr;
2013   size_t AllocLen;
2014 } tAllocStr;
2015 
InitStr(tAllocStr * pStr)2016 static void InitStr(tAllocStr *pStr)
2017 {
2018   pStr->pStr = NULL;
2019   pStr->AllocLen = 0;
2020 }
2021 
ReallocStr(tAllocStr * pStr,unsigned NewAllocLen)2022 static void ReallocStr(tAllocStr *pStr, unsigned NewAllocLen)
2023 {
2024   if (NewAllocLen > pStr->AllocLen)
2025   {
2026     char *pNewStr;
2027 
2028     /* round up, and implicitly avoid allocating 4/8 bytes (sizeof pointer)
2029        so size check in as_vsnprcatf() does not generate false positive: */
2030 
2031     NewAllocLen = (NewAllocLen + 15) &~15;
2032     pNewStr = pStr->AllocLen
2033             ? (char*)realloc(pStr->pStr, NewAllocLen)
2034             : (char*)malloc(NewAllocLen);
2035 
2036     if (pNewStr)
2037     {
2038       pStr->pStr = pNewStr;
2039       pStr->pStr[pStr->AllocLen] = '\0';
2040       pStr->AllocLen = NewAllocLen;
2041     }
2042   }
2043 }
2044 
GetErrorPos(void)2045 char *GetErrorPos(void)
2046 {
2047   String ActPos;
2048   PInputTag RunTag;
2049   tAllocStr Str;
2050   int CurrStrLen, NewLen;
2051   Boolean Last;
2052 
2053   InitStr(&Str);
2054   CurrStrLen = 0;
2055 
2056   /* for GNU error message style: */
2057 
2058   if (GNUErrors)
2059   {
2060     PInputTag pInnerTag = NULL;
2061     const char *pMsg;
2062 
2063     /* we only honor the include positions.  First, print the upper include layers... */
2064 
2065     for (RunTag = FirstInputTag; RunTag; RunTag = RunTag->Next)
2066       if (RunTag->GetPos == INCLUDE_GetPos)
2067       {
2068         if (!pInnerTag)
2069           pInnerTag = RunTag;
2070         else
2071         {
2072           Last = RunTag->GetPos(RunTag, ActPos, sizeof(ActPos));
2073           if (!Str.AllocLen)
2074           {
2075             pMsg = getmessage(Num_GNUErrorMsg1);
2076             NewLen = strlen(pMsg) + 1 + strlen(ActPos) + 1;
2077             ReallocStr(&Str, NewLen);
2078             as_snprintf(Str.pStr, Str.AllocLen, "%s %s", pMsg, ActPos);
2079             CurrStrLen = NewLen;
2080           }
2081           else
2082           {
2083             pMsg = getmessage(Num_GNUErrorMsgN);
2084             NewLen = CurrStrLen + 2 + strlen(pMsg) + 1 + strlen(ActPos) + 1;
2085             ReallocStr(&Str, NewLen);
2086             as_snprcatf(Str.pStr, Str.AllocLen, ",\n%s %s", pMsg, ActPos);
2087             CurrStrLen = NewLen;
2088           }
2089         }
2090       }
2091 
2092     /* ...append something... */
2093 
2094     if (CurrStrLen > 0)
2095     {
2096       NewLen = CurrStrLen + 3;
2097 
2098       ReallocStr(&Str, NewLen);
2099       as_snprcatf(Str.pStr, Str.AllocLen, ":\n");
2100       CurrStrLen = NewLen;
2101     }
2102 
2103     /* ...then the innermost one */
2104 
2105     if (pInnerTag)
2106     {
2107       pInnerTag->GetPos(pInnerTag, ActPos, sizeof(ActPos));
2108       NewLen = CurrStrLen + strlen(ActPos) + 1;
2109       ReallocStr(&Str, NewLen);
2110       as_snprcatf(Str.pStr, Str.AllocLen, "%s", ActPos);
2111       CurrStrLen = NewLen;
2112     }
2113   }
2114 
2115   /* otherwise the standard AS position generator: */
2116 
2117   else
2118   {
2119     int ThisLen;
2120 
2121     for (RunTag = FirstInputTag; RunTag; RunTag = RunTag->Next)
2122     {
2123       Last = RunTag->GetPos(RunTag, ActPos, sizeof(ActPos));
2124       ThisLen = strlen(ActPos);
2125       ReallocStr(&Str, NewLen = CurrStrLen + ThisLen + 1);
2126       strmaxprep(Str.pStr, ActPos, Str.AllocLen);
2127       CurrStrLen = NewLen;
2128       if (Last)
2129         break;
2130     }
2131   }
2132 
2133   return Str.pStr;
2134 }
2135 
InputEnd(void)2136 static Boolean InputEnd(void)
2137 {
2138   PInputTag Lauf;
2139 
2140   Lauf = FirstInputTag;
2141   while (Lauf)
2142   {
2143     if (!Lauf->IsEmpty)
2144       return False;
2145     Lauf = Lauf->Next;
2146   }
2147 
2148   return True;
2149 }
2150 
2151 /*=== Eine Quelldatei ( Haupt-oder Includedatei ) bearbeiten ===============*/
2152 
2153 /*--- aus der zerlegten Zeile Code erzeugen --------------------------------*/
2154 
WriteCode(void)2155 void WriteCode(void)
2156 {
2157   unsigned z;
2158 
2159   for (z = 0; z < StopfZahl; z++)
2160   {
2161     switch (ActListGran)
2162     {
2163       case 4:
2164         DAsmCode[CodeLen >> 2] = NOPCode;
2165         break;
2166       case 2:
2167         WAsmCode[CodeLen >> 1] = NOPCode;
2168         break;
2169       case 1:
2170         BAsmCode[CodeLen] = NOPCode;
2171         break;
2172     }
2173     CodeLen += ActListGran/Granularity();
2174   }
2175 
2176   if ((ActPC != StructSeg) && (!ChkPC(PCs[ActPC] + CodeLen - 1)) && (CodeLen != 0))
2177     WrError(ErrNum_AdrOverflow);
2178   else
2179   {
2180     LargeWord NewPC = PCs[ActPC] + CodeLen;
2181 
2182     if ((!DontPrint) && (ActPC != StructSeg) && (CodeLen > 0))
2183       BookKeeping();
2184     if (ActPC == StructSeg)
2185     {
2186       if ((CodeLen != 0) && (!DontPrint)) WrError(ErrNum_NotInStruct);
2187       if (StructStack->StructRec->IsUnion)
2188       {
2189         BumpStructLength(StructStack->StructRec, CodeLen);
2190         CodeLen = 0;
2191         NewPC = 0;
2192       }
2193     }
2194     else if (CodeOutput)
2195     {
2196       PCsUsed[ActPC] = True;
2197       if (DontPrint)
2198         NewRecord(PCs[ActPC] + CodeLen);
2199       else
2200         WriteBytes();
2201     }
2202     PCs[ActPC] = NewPC;
2203   }
2204 }
2205 
Produce_Code(void)2206 static void Produce_Code(void)
2207 {
2208   PMacroRec OneMacro;
2209   PStructRec OneStruct;
2210   Boolean SearchMacros, Found, IsMacro = False, IsStruct = False;
2211 
2212   ActListGran = ListGran();
2213   WasIF = WasMACRO = False;
2214 
2215   /* Makrosuche unterdruecken ? */
2216 
2217   if (*OpPart.Str == '!')
2218   {
2219     SearchMacros = False;
2220     StrCompCutLeft(&OpPart, 1);
2221     strcpy(pLOpPart, OpPart.Str);
2222   }
2223   else
2224   {
2225     SearchMacros = True;
2226     ExpandStrSymbol(pLOpPart, STRINGSIZE, &OpPart);
2227     strcpy(OpPart.Str, pLOpPart);
2228   }
2229   NLS_UpString(OpPart.Str);
2230 
2231   /* Prozessor eingehaengt ? */
2232 
2233   if (FirstOutputTag)
2234   {
2235     FirstOutputTag->Processor();
2236     return;
2237   }
2238 
2239   /* otherwise generate code: check for macro/structs here */
2240 
2241   IsMacro = (SearchMacros) && (FoundMacro(&OneMacro));
2242   if (IsMacro)
2243     WasMACRO = True;
2244   if (!IsMacro)
2245     IsStruct = FoundStruct(&OneStruct, pLOpPart);
2246 
2247   /* no longer at an address right after a BSR? */
2248 
2249   if (EProgCounter() != AfterBSRAddr)
2250     AfterBSRAddr = 0;
2251 
2252   /* evtl. voranstehendes Label ablegen */
2253 
2254   if ((IfAsm) && ((!IsMacro) || (!OneMacro->LocIntLabel)))
2255   {
2256     if (LabelPresent())
2257       LabelHandle(&LabPart, EProgCounter());
2258   }
2259 
2260   Found = False;
2261   switch (*OpPart.Str)
2262   {
2263     case 'I':
2264       /* Makroliste ? */
2265       Found = True;
2266       if (Memo("IRP")) ExpandIRP();
2267       else if (Memo("IRPC")) ExpandIRPC();
2268       else Found = False;
2269       break;
2270     case 'R':
2271       /* Repetition ? */
2272       Found = True;
2273       if (Memo("REPT")) ExpandREPT();
2274       else Found = False;
2275       break;
2276     case 'W':
2277       /* bedingte Repetition ? */
2278       Found = True;
2279       if (Memo("WHILE")) ExpandWHILE();
2280       else Found = False;
2281       break;
2282   }
2283 
2284   /* bedingte Assemblierung ? */
2285 
2286   if (!Found)
2287     WasIF = Found = CodeIFs();
2288 
2289   if (!Found)
2290     switch (*OpPart.Str)
2291     {
2292       case 'M':
2293         /* Makrodefinition ? */
2294         Found = True;
2295         if (Memo("MACRO")) ReadMacro();
2296         else Found = False;
2297         break;
2298       case 'E':
2299         /* Abbruch Makroexpansion ? */
2300         Found = True;
2301         if (Memo("EXITM")) ExpandEXITM();
2302         else Found = False;
2303         break;
2304       case 'S':
2305         /* shift macro arguments ? */
2306         Found = True;
2307         if (Memo(ShiftIsOccupied ? "SHFT" : "SHIFT")) ExpandSHIFT();
2308         else Found = False;
2309         break;
2310       case 'I':
2311         /* Includefile? */
2312         Found = True;
2313         if (Memo("INCLUDE"))
2314         {
2315           ExpandINCLUDE(True);
2316           MasterFile = False;
2317         }
2318         else Found = False;
2319         break;
2320     }
2321 
2322   if (Found);
2323 
2324   /* Makroaufruf ? */
2325 
2326   else if (IsMacro)
2327   {
2328     if (IfAsm)
2329     {
2330       ExpandMacro(OneMacro);
2331       if ((MacroNestLevel > 1) && (MacroNestLevel < 100))
2332         as_snprintf(ListLine, STRINGSIZE, "%*s(MACRO-%u)", MacroNestLevel - 1, "", MacroNestLevel);
2333       else
2334         strmaxcpy(ListLine, "(MACRO)", STRINGSIZE);
2335 
2336       /* Macro call itself must not appear in expanded output.  However, a label
2337          in the same line that is not consumed by the macro must.  In this case,
2338          dump the source line with the OpPart (macro's name) muted out. */
2339 
2340       if (MacProOutput && (LabPart.Pos.StartCol >= 0) && !OneMacro->LocIntLabel)
2341         PrintOneLineMuted(MacProFile, OneLine, &OpPart.Pos, &ArgPart.Pos);
2342     }
2343   }
2344 
2345   else
2346   {
2347     StopfZahl = 0;
2348     CodeLen = 0;
2349     DontPrint = False;
2350 
2351 #ifdef PROFILE_MEMO
2352     NumMemo = 0;
2353 #endif
2354 
2355     if (IfAsm)
2356     {
2357       /* structure declaration ? */
2358 
2359       if (IsStruct)
2360       {
2361         ExpandStruct(OneStruct);
2362         strmaxcpy(ListLine, OneStruct->IsUnion ? "(UNION)" : "(STRUCT)", STRINGSIZE);
2363       }
2364       else
2365       {
2366         AttrPartOpSize = eSymbolSizeUnknown;
2367         if (DecodeAttrPart ? DecodeAttrPart() : True)
2368         {
2369           if (!CodeGlobalPseudo())
2370           MakeCode();
2371         }
2372       }
2373       if (MacProOutput && ((*OpPart.Str != '\0') || (*LabPart.Str != '\0') || (*CommPart.Str != '\0')))
2374       {
2375         errno = 0;
2376         fprintf(MacProFile, "%s\n", OneLine);
2377         ChkIO(ErrNum_ListWrError);
2378       }
2379     }
2380 
2381 #ifdef PROFILE_MEMO
2382     NumMemoSum += NumMemo;
2383     NumMemoCnt++;
2384 #endif
2385 
2386     WriteCode();
2387   }
2388 
2389   /* reset memory about previous label if it is a non-empty instruction */
2390 
2391   if (*OpPart.Str)
2392     LabelReset();
2393 
2394   /* dies ueberprueft implizit, ob von der letzten Eval...-Operation noch
2395      externe Referenzen liegengeblieben sind. */
2396 
2397   SetRelocs(NULL);
2398 }
2399 
2400 /*--- Zeile in Listing zerteilen -------------------------------------------*/
2401 
SplitLine(void)2402 static void SplitLine(void)
2403 {
2404   const char *pRun, *pEnd, *pPos;
2405 
2406   Retracted = False;
2407 
2408   /* run preprocessor */
2409 
2410   ExpandDefines(OneLine);
2411   pRun = OneLine;
2412   pEnd = pRun + strlen(pRun);
2413 
2414   /* If comment is present, ignore everything after it: */
2415 
2416   pPos = QuotPosQualify(pRun, ';', QualifyQuote);
2417   if (pPos)
2418   {
2419     CommPart.Pos.StartCol = pPos - OneLine;
2420     CommPart.Pos.Len = strmemcpy(CommPart.Str, STRINGSIZE, pPos, pEnd - pPos);
2421     pEnd = pPos;
2422   }
2423   else
2424     StrCompReset(&CommPart);
2425 
2426   /* Non-blank character in first column is always label: */
2427 
2428   if ((pRun < pEnd) && (*pRun) && (!as_isspace(*pRun)))
2429   {
2430     for (pPos = pRun; pPos < pEnd; pPos++)
2431       if ((as_isspace(*pPos)) || (*pPos == ':'))
2432         break;
2433     LabPart.Pos.StartCol = pRun - OneLine;
2434     if (pPos >= pEnd)
2435     {
2436       LabPart.Pos.Len = strmemcpy(LabPart.Str, STRINGSIZE, pRun, pEnd - pRun);
2437       pRun = pEnd;
2438     }
2439     else
2440     {
2441       LabPart.Pos.Len = strmemcpy(LabPart.Str, STRINGSIZE, pRun, pPos - pRun);
2442       pRun = pPos + 1;
2443     }
2444     if ((LabPart.Pos.Len > 0) && (LabPart.Str[LabPart.Pos.Len - 1] == ':')) /* needed? */
2445       LabPart.Str[--LabPart.Pos.Len] = '\0';
2446   }
2447   else
2448     StrCompReset(&LabPart);
2449 
2450   /* Opcode & Argument trennen */
2451 
2452   while (True)
2453   {
2454     for (; (pRun < pEnd) && as_isspace(*pRun); pRun++);
2455     for (pPos = pRun; (pPos < pEnd) && !as_isspace(*pPos); pPos++);
2456 
2457     /* If potential OpPart starts with argument divider,
2458        OpPart is empty and rest of line is all-arguments: */
2459 
2460     if (strchr(DivideChars, *pRun))
2461     {
2462       StrCompReset(&OpPart);
2463       ArgPart.Pos.StartCol = pRun - OneLine;
2464       ArgPart.Pos.Len = strmemcpy(ArgPart.Str, STRINGSIZE, pRun, pEnd - pRun);
2465     }
2466     else
2467     {
2468       /* copy out OpPart */
2469 
2470       OpPart.Pos.StartCol = pRun - OneLine;
2471       OpPart.Pos.Len = strmemcpy(OpPart.Str, STRINGSIZE, pRun, pPos - pRun);
2472 
2473       /* continue after OpPart separator */
2474 
2475       pRun = (pPos < pEnd) ? pPos + 1 : pEnd;
2476 
2477       /* Falls noch kein Label da war, kann es auch ein Label sein */
2478 
2479       if ((*LabPart.Str == '\0') && OpPart.Pos.Len && (OpPart.Str[OpPart.Pos.Len - 1] == ':'))
2480       {
2481         OpPart.Str[--OpPart.Pos.Len] = '\0';
2482         StrCompCopy(&LabPart, &OpPart);
2483         continue; /* -> retry finding opcode */
2484       }
2485 
2486       /* save remainder to ArgPart */
2487 
2488       ArgPart.Pos.StartCol = pRun - OneLine;
2489       ArgPart.Pos.Len = strmemcpy(ArgPart.Str, STRINGSIZE, pRun, pEnd - pRun);
2490     }
2491     break;
2492   }
2493 
2494   ArgCnt = 0;
2495 
2496   /* trailing separator on OpPart means we have to push in another empty argument */
2497 
2498   if (OpPart.Pos.Len && strchr(DivideChars, OpPart.Str[OpPart.Pos.Len - 1]))
2499   {
2500     OpPart.Str[--OpPart.Pos.Len] = '\0';
2501     IncArgCnt();
2502     strcpy(ArgStr[ArgCnt].Str, "");
2503     ArgStr[ArgCnt].Pos = ArgPart.Pos;
2504   }
2505 
2506   /* Attribut abspalten */
2507 
2508   if (HasAttrs)
2509   {
2510     const char *pActAttrChar;
2511     char *pAttrPos, *pActAttrPos;
2512     int Tries = 0;
2513 
2514 again:
2515     pAttrPos = NULL; AttrSplit = ' ';
2516     for (pActAttrChar = AttrChars; *pActAttrChar; pActAttrChar++)
2517     {
2518       pActAttrPos = strchr(OpPart.Str, *pActAttrChar);
2519       if (pActAttrPos && ((!pAttrPos) || (pActAttrPos < pAttrPos)))
2520         pAttrPos = pActAttrPos;
2521     }
2522     if (pAttrPos)
2523     {
2524       AttrSplit = (*pAttrPos);
2525       AttrPart.Pos.StartCol = OpPart.Pos.StartCol + (pAttrPos + 1 - OpPart.Str);
2526       AttrPart.Pos.Len = strmemcpy(AttrPart.Str, STRINGSIZE, pAttrPos + 1, strlen(pAttrPos + 1));
2527       *pAttrPos = '\0';
2528 
2529       /* The dot-prefixed OpPart may itself contain an attribute (.instr.attr).  So reiterate
2530          splitting off attribute, but only once ;-) */
2531 
2532       if ((*OpPart.Str == '\0') && (*AttrPart.Str != '\0'))
2533       {
2534         StrCompCopy(&OpPart, &AttrPart);
2535         StrCompReset(&AttrPart);
2536         if (++Tries < 2)
2537           goto again;
2538       }
2539     }
2540     else
2541       StrCompReset(&AttrPart);
2542   }
2543   else
2544     StrCompReset(&AttrPart);
2545 
2546   KillPostBlanksStrComp(&ArgPart);
2547 
2548   /* Argumente zerteilen: Da alles aus einem String kommt und die Teile alle auch
2549      so lang sind, koennen wir uns Laengenabfragen sparen */
2550 
2551   if (*ArgPart.Str)
2552   {
2553     const char *pDivPos, *pActDiv, *pActDivPos;
2554 
2555     pRun = ArgPart.Str;
2556     pEnd = pRun + strlen(pRun);
2557     pActDivPos = NULL;
2558 
2559     /* A separator found in the previous iteration forces another argument,
2560        even if it will be empty because the separator is right at the end: */
2561 
2562     while ((pRun < pEnd) || pActDivPos)
2563     {
2564       while (*pRun && as_isspace(*pRun))
2565         pRun++;
2566 #if 0 /* should work, but doesn't yet */
2567       pDivPos = QuotMultPosFixup(pRun, DivideChars, NULL);
2568       if (!pDivPos)
2569         pDivPos = pEnd;
2570 #endif
2571       pDivPos = pEnd;
2572       for (pActDiv = DivideChars; *pActDiv; pActDiv++)
2573       {
2574         pActDivPos = QuotPosQualify(pRun, *pActDiv, QualifyQuote);
2575         if (pActDivPos && (pActDivPos < pDivPos))
2576           pDivPos = pActDivPos;
2577       }
2578       if (ArgCnt >= ArgCntMax)
2579       {
2580         WrError(ErrNum_TooManyArgs);
2581         break;
2582       }
2583       IncArgCnt();
2584       ArgStr[ArgCnt].Pos.Len = strmemcpy(ArgStr[ArgCnt].Str, STRINGSIZE, pRun, pDivPos - pRun);
2585       ArgStr[ArgCnt].Pos.StartCol = ArgPart.Pos.StartCol + (pRun - ArgPart.Str);
2586       KillPostBlanksStrComp(&ArgStr[ArgCnt]);
2587       pRun = (pDivPos < pEnd) ? pDivPos + 1 : pEnd;
2588     }
2589   }
2590 }
2591 
2592 /*------------------------------------------------------------------------*/
2593 
ProcessFile(String FileName)2594 static void ProcessFile(String FileName)
2595 {
2596   long NxtTime, ListTime;
2597   const char *Name;
2598   char *Run;
2599 
2600   dbgentry("ProcessFile");
2601 
2602   as_snprintf(OneLine, STRINGSIZE, " INCLUDE \"%s\"", FileName);
2603   MasterFile = False;
2604   NextIncDepth = IncDepth;
2605   SplitLine();
2606   Produce_Code();
2607   IncDepth = NextIncDepth;
2608 
2609   ListTime = GTime();
2610 
2611   while ((!InputEnd()) && (!ENDOccured))
2612   {
2613     /* Zeile lesen */
2614 
2615     GetNextLine(OneLine);
2616 
2617     /* Ergebnisfelder vorinitialisieren */
2618 
2619     DontPrint = False;
2620     CodeLen = 0;
2621     *ListLine = '\0';
2622 
2623     NextDoLst = DoLst;
2624     NextIncDepth = IncDepth;
2625 
2626     for (Run = OneLine; *Run != '\0'; Run++)
2627       if (!as_isspace(*Run))
2628         break;
2629     if (*Run == '#')
2630       Preprocess();
2631     else
2632     {
2633       SplitLine();
2634       Produce_Code();
2635     }
2636 
2637     MakeList(OneLine);
2638     DoLst = NextDoLst;
2639     IncDepth = NextIncDepth;
2640 
2641     /* Zeilenzaehler */
2642 
2643     if (!QuietMode)
2644     {
2645       NxtTime = GTime();
2646       if (((!ListToStdout) || ((ListMask&1) == 0)) && (DTime(ListTime, NxtTime) > 50))
2647       {
2648         String Num;
2649 
2650         Name = NamePart(CurrFileName);
2651         as_snprintf(Num, sizeof(Num), "%s(", Name);
2652         as_snprcatf(Num, sizeof(Num), LongIntFormat, MomLineCounter);
2653         as_snprcatf(Num, sizeof(Num), ")");
2654         WrConsoleLine(Num, False);
2655         fflush(stdout);
2656         ListTime = NxtTime;
2657       }
2658     }
2659 
2660     /* bei Ende Makroprozessor ausraeumen
2661       OK - das ist eine Hauruckmethode... */
2662 
2663     if (ENDOccured)
2664       while (FirstInputTag)
2665         GetNextLine(OneLine);
2666   }
2667 
2668   while (FirstInputTag)
2669     GetNextLine(OneLine);
2670 
2671   /* irgendeine Makrodefinition nicht abgeschlossen ? */
2672 
2673   if (FirstOutputTag)
2674   {
2675     WrError(FirstOutputTag->OpenErrMsg);
2676   }
2677 
2678   dbgexit("ProcessFile");
2679 }
2680 
2681 /****************************************************************************/
2682 
TWrite_Plur(int n)2683 static const char *TWrite_Plur(int n)
2684 {
2685   return (n != 1) ? getmessage(Num_ListPlurName) : "";
2686 }
2687 
TWrite(long DTime,char * dest,size_t DestSize)2688 static void TWrite(long DTime, char *dest, size_t DestSize)
2689 {
2690   int h;
2691 
2692   *dest = '\0';
2693   h = DTime / 360000;
2694   DTime %= 360000;
2695   if (h > 0)
2696     as_snprcatf(dest, DestSize, "%d%s%s, ", h, getmessage(Num_ListHourName), TWrite_Plur(h));
2697 
2698   h = DTime / 6000;
2699   DTime %= 6000;
2700   if (h > 0)
2701     as_snprcatf(dest, DestSize, "%d%s%s, ", h, getmessage(Num_ListMinuName), TWrite_Plur(h));
2702 
2703   h = DTime / 100;
2704   DTime %= 100;
2705   as_snprcatf(dest, DestSize, "%d.%02d%s%s", h, (int)DTime, getmessage(Num_ListSecoName), TWrite_Plur(h));
2706 }
2707 
2708 /*--------------------------------------------------------------------------*/
2709 
AssembleFile_InitPass(void)2710 static void AssembleFile_InitPass(void)
2711 {
2712   static char DateS[31], TimeS[31];
2713   int z;
2714   String ArchVal;
2715 
2716   String TmpCompStr;
2717   tStrComp TmpComp;
2718   StrCompMkTemp(&TmpComp, TmpCompStr);
2719 
2720   dbgentry("AssembleFile_InitPass");
2721 
2722   FirstInputTag = NULL;
2723   FirstOutputTag = NULL;
2724 
2725   MomLineCounter = 0;
2726   MomLocHandle = -1;
2727   LocHandleCnt = 0;
2728   SectSymbolCounter = 0;
2729 
2730   SectionStack = NULL;
2731   FirstIfSave = NULL;
2732   FirstSaveState = NULL;
2733   StructStack =
2734   pInnermostNamedStruct = NULL;
2735   for (z = 0; z < PCMax; z++)
2736     pPhaseStacks[z] = NULL;
2737 
2738   InitPass();
2739   AsmLabelPassInit();
2740 
2741   ActPC = SegCode;
2742   PCs[ActPC] = 0;
2743   RelSegs = False;
2744   ENDOccured = False;
2745   ErrorCount = 0;
2746   WarnCount = 0;
2747   LineSum = 0;
2748   MacLineSum = 0;
2749   for (z = 1; z <= StructSeg; z++)
2750   {
2751     PCsUsed[z] = FALSE;
2752     Phases[z] = 0;
2753     InitChunk(SegChunks + z);
2754   }
2755 
2756   TransTables =
2757   CurrTransTable = (PTransTable) malloc(sizeof(TTransTable));
2758   CurrTransTable->Next = NULL;
2759   CurrTransTable->Name = as_strdup("STANDARD");
2760   CurrTransTable->Table = (unsigned char *) malloc(256 * sizeof(char));
2761   for (z = 0; z < 256; z++)
2762     CurrTransTable->Table[z] = z;
2763 
2764   EnumSegment = SegNone;
2765   EnumIncrement = 1;
2766   EnumCurrentValue = 0;
2767 
2768   strmaxcpy(CurrFileName, "INTERNAL", STRINGSIZE);
2769   AddFile(CurrFileName);
2770   CurrLine = 0;
2771 
2772   IncDepth = -1;
2773   DoLst = eLstMacroExpAll;
2774 
2775   /* Pseudovariablen initialisieren */
2776 
2777   ResetSymbolDefines();
2778   ResetMacroDefines();
2779   ResetStructDefines();
2780   strmaxcpy(TmpCompStr, FlagTrueName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, 1, 0, True);
2781   strmaxcpy(TmpCompStr, FlagFalseName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, 0, 0, True);
2782   strmaxcpy(TmpCompStr, PiName, sizeof(TmpCompStr)); EnterFloatSymbol(&TmpComp, 4.0 * atan(1.0), True);
2783   strmaxcpy(TmpCompStr, VerName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, VerNo, 0, True);
2784   as_snprintf(ArchVal, sizeof(ArchVal), "%s-%s", ARCHPRNAME, ARCHSYSNAME);
2785   strmaxcpy(TmpCompStr, ArchName, sizeof(TmpCompStr)); EnterStringSymbol(&TmpComp, ArchVal, True);
2786   strmaxcpy(TmpCompStr, Has64Name, sizeof(TmpCompStr));
2787 #ifdef HAS64
2788   EnterIntSymbol(&TmpComp, 1, 0, True);
2789 #else
2790   EnterIntSymbol(&TmpComp, 0, 0, True);
2791 #endif
2792   strmaxcpy(TmpCompStr, CaseSensName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, Ord(CaseSensitive), 0, True);
2793   if (PassNo == 0)
2794   {
2795     NLS_CurrDateString(DateS, sizeof(DateS));
2796     NLS_CurrTimeString(False, TimeS, sizeof(TimeS));
2797   }
2798   if (!FindDefSymbol(DateName))
2799   {
2800     strmaxcpy(TmpCompStr, DateName, sizeof(TmpCompStr));
2801     EnterStringSymbol(&TmpComp, DateS, True);
2802   }
2803   if (!FindDefSymbol(TimeName))
2804   {
2805     strmaxcpy(TmpCompStr, TimeName, sizeof(TmpCompStr));
2806     EnterStringSymbol(&TmpComp, TimeS, True);
2807   }
2808 
2809   SetFlag(&DoPadding, DoPaddingName, True);
2810 
2811   if (*DefCPU == '\0')
2812     SetCPUByType(0, NULL);
2813   else
2814   {
2815     tStrComp TmpComp2;
2816 
2817     StrCompMkTemp(&TmpComp2, DefCPU);
2818     if (!SetCPUByName(&TmpComp2))
2819       SetCPUByType(0, NULL);
2820   }
2821 
2822   SetFlag(&SupAllowed, SupAllowedName, False);
2823   SetFlag(&FPUAvail, FPUAvailName, False);
2824   SetFlag(&Maximum, MaximumName, False);
2825   SetFlag(&DoBranchExt, BranchExtName, False);
2826   strmaxcpy(TmpCompStr, ListOnName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, ListOn = 1, SegNone, True);
2827   SetLstMacroExp(eLstMacroExpAll);
2828   InitLstMacroExpMod(&LstMacroExpModOverride);
2829   InitLstMacroExpMod(&LstMacroExpModDefault);
2830   SetFlag(&RelaxedMode, RelaxedName, DefRelaxedMode);
2831   strmaxcpy(TmpCompStr, NestMaxName, sizeof(TmpCompStr)); EnterIntSymbol(&TmpComp, NestMax = DEF_NESTMAX, SegNone, True);
2832   CopyDefSymbols();
2833 
2834   /* initialize counter for temp symbols here after implicit symbols
2835      have been defined, so counter starts at a value as low as possible */
2836 
2837   InitTmpSymbols();
2838 
2839   ResetPageCounter();
2840 
2841   StartAdrPresent = False;
2842 
2843   AfterBSRAddr = 0;
2844 
2845   Repass = False;
2846   PassNo++;
2847 
2848 #ifdef PROFILE_MEMO
2849   NumMemoSum = 0;
2850   NumMemoCnt = 0;
2851 #endif
2852 
2853   dbgexit("AssembleFile_InitPass");
2854 }
2855 
AssembleFile_ExitPass(void)2856 static void AssembleFile_ExitPass(void)
2857 {
2858   tSavePhase *pSavePhase;
2859   int z;
2860 
2861   if (SwitchFrom)
2862   {
2863     SwitchFrom();
2864     SwitchFrom = NULL;
2865   }
2866   ClearLocStack();
2867   ClearStacks();
2868   AsmErrPassExit();
2869   for (z = 0; z < PCMax; z++)
2870     while (pPhaseStacks[z])
2871     {
2872       pSavePhase = pPhaseStacks[z];
2873       pPhaseStacks[z] = pSavePhase->pNext;
2874       free(pSavePhase);
2875     }
2876   if (FirstIfSave)
2877     WrError(ErrNum_MissEndif);
2878   if (FirstSaveState)
2879     WrError(ErrNum_NoRestoreFrame);
2880   if (SectionStack)
2881     WrError(ErrNum_MissingEndSect);
2882   if (StructStack)
2883     WrXError(ErrNum_OpenStruct, StructStack->Name);
2884 }
2885 
AssembleFile_WrSummary(const char * pStr)2886 static void AssembleFile_WrSummary(const char *pStr)
2887 {
2888   if (!QuietMode)
2889     WrConsoleLine(pStr, True);
2890   if (ListMode == 2)
2891     WrLstLine(pStr);
2892 }
2893 
AssembleFile(char * Name)2894 static void AssembleFile(char *Name)
2895 {
2896   String s, Tmp;
2897 
2898   dbgentry("AssembleFile");
2899 
2900   strmaxcpy(SourceFile, Name, STRINGSIZE);
2901   if (MakeDebug)
2902     fprintf(Debug, "File %s\n", SourceFile);
2903 
2904   /* Untermodule initialisieren */
2905 
2906   AsmDefInit();
2907   AsmParsInit();
2908   AsmIFInit();
2909   InitFileList();
2910   ResetStack();
2911 
2912   /* Kommandozeilenoptionen verarbeiten */
2913 
2914   strmaxcpy(OutName, GetFromOutList(), STRINGSIZE);
2915   if (OutName[0] == '\0')
2916   {
2917     strmaxcpy(OutName, SourceFile, STRINGSIZE);
2918     KillSuffix(OutName);
2919     AddSuffix(OutName, PrgSuffix);
2920   }
2921 
2922   if (*ErrorPath == '\0')
2923   {
2924     strmaxcpy(ErrorName, SourceFile, STRINGSIZE);
2925     KillSuffix(ErrorName);
2926     AddSuffix(ErrorName, LogSuffix);
2927     unlink(ErrorName);
2928   }
2929 
2930   switch (ListMode)
2931   {
2932     case 0:
2933       strmaxcpy(LstName, NULLDEV, STRINGSIZE);
2934       break;
2935     case 1:
2936       strmaxcpy(LstName, "!1", STRINGSIZE);
2937       break;
2938     case 2:
2939       strmaxcpy(LstName, GetFromListOutList(), STRINGSIZE);
2940       if (*LstName == '\0')
2941       {
2942         strmaxcpy(LstName, SourceFile, STRINGSIZE);
2943         KillSuffix(LstName);
2944         AddSuffix(LstName, LstSuffix);
2945       }
2946       break;
2947   }
2948   ListToStdout = !strcmp(LstName, "!1");
2949   ListToNull = !strcmp(LstName, NULLDEV);
2950 
2951   if (ShareMode != 0)
2952   {
2953     strmaxcpy(ShareName, GetFromShareOutList(), STRINGSIZE);
2954     if (*ShareName == '\0')
2955     {
2956       strmaxcpy(ShareName, SourceFile, STRINGSIZE);
2957       KillSuffix(ShareName);
2958       switch (ShareMode)
2959       {
2960         case 1:
2961           AddSuffix(ShareName, ".inc");
2962           break;
2963         case 2:
2964           AddSuffix(ShareName, ".h");
2965           break;
2966         case 3:
2967           AddSuffix(ShareName, IncSuffix);
2968           break;
2969       }
2970     }
2971   }
2972 
2973   if (MacProOutput)
2974   {
2975     strmaxcpy(MacProName, SourceFile, STRINGSIZE);
2976     KillSuffix(MacProName);
2977     AddSuffix(MacProName, PreSuffix);
2978   }
2979 
2980   if (MacroOutput)
2981   {
2982     strmaxcpy(MacroName, SourceFile, STRINGSIZE);
2983     KillSuffix(MacroName);
2984     AddSuffix(MacroName, MacSuffix);
2985   }
2986 
2987   ClearIncludeList();
2988 
2989   if (DebugMode != DebugNone)
2990     InitLineInfo();
2991 
2992   /* Variablen initialisieren */
2993 
2994   StartTime = GTime();
2995 
2996   PassNo = 0;
2997   MomLineCounter = 0;
2998 
2999   /* Listdatei eroeffnen */
3000 
3001   if (!QuietMode)
3002     printf("%s%s\n", getmessage(Num_InfoMessAssembling), SourceFile);
3003 
3004   do
3005   {
3006     /* Durchlauf initialisieren */
3007 
3008     AssembleFile_InitPass();
3009     AsmSubPassInit();
3010     AsmErrPassInit();
3011     if (!QuietMode)
3012     {
3013       as_snprintf(Tmp, sizeof(Tmp), "%s", getmessage(Num_InfoMessPass));
3014       as_snprcatf(Tmp, sizeof(Tmp), IntegerFormat, PassNo);
3015       WrConsoleLine(Tmp, True);
3016     }
3017 
3018     /* Dateien oeffnen */
3019 
3020     if (CodeOutput)
3021       OpenFile();
3022 
3023     if (ShareMode != 0)
3024     {
3025       ShareFile = fopen(ShareName, "w");
3026       if (!ShareFile)
3027         ChkIO(ErrNum_OpeningFile);
3028       errno = 0;
3029       switch (ShareMode)
3030       {
3031         case 1:
3032           fprintf(ShareFile, "(* %s-Include File for CONST Section *)\n", SourceFile);
3033           break;
3034         case 2:
3035           fprintf(ShareFile, "/* %s-Include File for C Program */\n", SourceFile);
3036           break;
3037         case 3:
3038           fprintf(ShareFile, "; %s-Include File for Assembler Program\n", SourceFile);
3039           break;
3040       }
3041       ChkIO(ErrNum_ListWrError);
3042     }
3043 
3044     if (MacProOutput)
3045     {
3046       MacProFile = fopen(MacProName, "w");
3047       if (!MacProFile)
3048         ChkIO(ErrNum_OpeningFile);
3049     }
3050 
3051     if ((MacroOutput) && (PassNo == 1))
3052     {
3053       MacroFile = fopen(MacroName, "w");
3054       if (!MacroFile)
3055         ChkIO(ErrNum_OpeningFile);
3056     }
3057 
3058     /* Listdatei oeffnen */
3059 
3060     OpenWithStandard(&LstFile, LstName);
3061     if (!LstFile)
3062       ChkIO(ErrNum_OpeningFile);
3063     if (!ListToNull)
3064     {
3065       errno = 0;
3066       fprintf(LstFile, "%s", PrtInitString);
3067       ChkIO(ErrNum_ListWrError);
3068     }
3069     if ((ListMask & 1) != 0)
3070       NewPage(0, False);
3071 
3072     /* assemblieren */
3073 
3074     ProcessFile(SourceFile);
3075     AssembleFile_ExitPass();
3076 
3077     /* Dateien schliessen */
3078 
3079     if (CodeOutput)
3080       CloseFile();
3081 
3082     if (ShareMode != 0)
3083     {
3084       errno = 0;
3085       switch (ShareMode)
3086       {
3087         case 1:
3088           fprintf(ShareFile, "(* Ende Include File for CONST Section *)\n");
3089           break;
3090         case 2:
3091           fprintf(ShareFile, "/* Ende Include File for C Program */\n");
3092           break;
3093         case 3:
3094           fprintf(ShareFile, "; Ende Include File for Assembler Program\n");
3095           break;
3096       }
3097       ChkIO(ErrNum_ListWrError);
3098       CloseIfOpen(&ShareFile);
3099     }
3100 
3101     if (MacProOutput)
3102       CloseIfOpen(&MacProFile);
3103     if (MacroOutput && (PassNo == 1))
3104       CloseIfOpen(&MacroFile);
3105 
3106     /* evtl. fuer naechsten Durchlauf aufraeumen */
3107 
3108     if ((ErrorCount == 0) && (Repass))
3109     {
3110       CloseIfOpen(&LstFile);
3111       if (CodeOutput)
3112         unlink(OutName);
3113       ClearCodepages();
3114       if (MakeUseList)
3115         ClearUseList();
3116       if (MakeCrossList)
3117         ClearCrossList();
3118       ClearDefineList();
3119       if (DebugMode != DebugNone)
3120         ClearLineInfo();
3121       ClearIncludeList();
3122       if (DebugMode != DebugNone)
3123       {
3124         ResetAddressRanges();
3125         ClearSectionUsage();
3126       }
3127     }
3128   }
3129   while ((ErrorCount == 0) && (Repass));
3130 
3131   /* bei Fehlern loeschen */
3132 
3133   if (ErrorCount != 0)
3134   {
3135     if (CodeOutput)
3136       unlink(OutName);
3137     if (MacProOutput)
3138       unlink(MacProName);
3139     if ((MacroOutput) && (PassNo == 1))
3140       unlink(MacroName);
3141     if (ShareMode != 0)
3142       unlink(ShareName);
3143     GlobErrFlag = True;
3144   }
3145 
3146   /* Debug-Ausgabe muss VOR die Symbollistenausgabe, weil letztere die
3147      Symbolliste loescht */
3148 
3149   if (DebugMode != DebugNone)
3150   {
3151     if (ErrorCount == 0)
3152       DumpDebugInfo();
3153     ClearLineInfo();
3154   }
3155 
3156   /* Listdatei abschliessen */
3157 
3158   if  (strcmp(LstName, NULLDEV))
3159   {
3160     if (ListMask & 2)
3161       PrintSymbolList();
3162 
3163     if (ListMask & 64)
3164       PrintRegDefs();
3165 
3166     if (ListMask & 4)
3167       PrintMacroList();
3168 
3169     if (ListMask & 256)
3170       PrintStructList();
3171 
3172     if (ListMask & 8)
3173       PrintFunctionList();
3174 
3175     if (ListMask & 32)
3176       PrintDefineList();
3177 
3178     if (ListMask & 128)
3179       PrintCodepages();
3180 
3181     if (MakeUseList)
3182     {
3183       NewPage(ChapDepth, True);
3184       PrintUseList();
3185     }
3186 
3187     if (MakeCrossList)
3188     {
3189       NewPage(ChapDepth, True);
3190       PrintCrossList();
3191     }
3192 
3193     if (MakeSectionList)
3194       PrintSectionList();
3195 
3196     if (MakeIncludeList)
3197       PrintIncludeList();
3198 
3199     if (!ListToNull)
3200     {
3201       errno = 0;
3202       fprintf(LstFile, "%s", PrtExitString);
3203       ChkIO(ErrNum_ListWrError);
3204     }
3205   }
3206 
3207   if (MakeUseList)
3208     ClearUseList();
3209 
3210   if (MakeCrossList)
3211     ClearCrossList();
3212 
3213   ClearSectionList();
3214 
3215   ClearIncludeList();
3216 
3217   if (!*ErrorPath)
3218     CloseIfOpen(&ErrorFile);
3219 
3220   ClearUp();
3221 
3222   /* Statistik ausgeben */
3223 
3224   StopTime = GTime();
3225   TWrite(DTime(StartTime, StopTime), s, sizeof(s));
3226   strmaxcat(s, getmessage(Num_InfoMessAssTime), STRINGSIZE);
3227   if (!QuietMode)
3228   {
3229     WrConsoleLine("", True);
3230     WrConsoleLine(s, True);
3231     WrConsoleLine("", True);
3232   }
3233   if (ListMode == 2)
3234   {
3235     WrLstLine("");
3236     WrLstLine(s);
3237     WrLstLine("");
3238   }
3239 
3240   as_snprintf(s, sizeof(s), "%7" PRILongInt "%s", LineSum,
3241               getmessage((LineSum == 1) ? Num_InfoMessAssLine : Num_InfoMessAssLines), STRINGSIZE);
3242   AssembleFile_WrSummary(s);
3243 
3244   if (LineSum != MacLineSum)
3245   {
3246     as_snprintf(s, sizeof(s), "%7" PRILongInt "%s", MacLineSum,
3247                 getmessage((MacLineSum == 1) ? Num_InfoMessMacAssLine : Num_InfoMessMacAssLines), STRINGSIZE);
3248     AssembleFile_WrSummary(s);
3249   }
3250 
3251   as_snprintf(s, sizeof(s), "%7d%s", (int)PassNo,
3252               getmessage((PassNo == 1) ? Num_InfoMessPassCnt : Num_InfoMessPPassCnt), STRINGSIZE);
3253   AssembleFile_WrSummary(s);
3254 
3255   if ((ErrorCount > 0) && (Repass) && (ListMode != 0))
3256     WrLstLine(getmessage(Num_InfoMessNoPass));
3257 
3258 #ifdef __TURBOC__
3259   as_snprintf(s, sizeof(s), "%7lu%s", coreleft() >> 10,
3260               getmessage(Num_InfoMessRemainMem));
3261   AssembleFile_WrSummary(s);
3262 
3263   as_snprintf(s, sizeof(s), "%7lu%s", (unsigned long)StackRes(),
3264               getmessage(Num_InfoMessRemainStack));
3265   AssembleFile_WrSummary(s);
3266 #endif
3267 
3268   as_snprintf(s, sizeof(s), "%7u%s%s", (unsigned)ErrorCount,
3269               getmessage(Num_InfoMessErrCnt),
3270               (ErrorCount == 1) ? "" : getmessage(Num_InfoMessErrPCnt));
3271   AssembleFile_WrSummary(s);
3272 
3273   as_snprintf(s, sizeof(s), "%7u%s%s", (unsigned)WarnCount,
3274               getmessage(Num_InfoMessWarnCnt),
3275               (WarnCount == 1) ? "" : getmessage(Num_InfoMessWarnPCnt));
3276   AssembleFile_WrSummary(s);
3277 
3278 #ifdef PROFILE_MEMO
3279   {
3280     unsigned long Sum = (NumMemoSum * 100) / NumMemoCnt;
3281 
3282     as_snprintf(s, sizeof(s), "%4lu.%02lu%s", Sum / 100, Sum % 100, " Oppart Compares");
3283     if (!QuietMode)
3284       WrConsoleLine(s, True);
3285     if (ListMode == 2)
3286       WrLstLine(s);
3287   }
3288 #endif
3289 
3290   CloseIfOpen(&LstFile);
3291 
3292   /* verstecktes */
3293 
3294   if (MakeDebug)
3295     PrintSymbolDepth();
3296 
3297   /* Speicher freigeben */
3298 
3299   ClearSymbolList();
3300   ClearCodepages();
3301   ClearMacroList();
3302   ClearFunctionList();
3303   ClearDefineList();
3304   ClearFileList();
3305   ClearStructList();
3306 
3307   dbgentry("AssembleFile");
3308 }
3309 
AssembleGroup(void)3310 static void AssembleGroup(void)
3311 {
3312   AddSuffix(FileMask, SrcSuffix);
3313   if (!DirScan(FileMask, AssembleFile))
3314     fprintf(stderr, "%s%s\n", FileMask, getmessage(Num_InfoMessNFilesFound));
3315 }
3316 
3317 /*-------------------------------------------------------------------------*/
3318 
CMD_SharePascal(Boolean Negate,const char * Arg)3319 static CMDResult CMD_SharePascal(Boolean Negate, const char *Arg)
3320 {
3321   UNUSED(Arg);
3322 
3323   if (!Negate)
3324     ShareMode = 1;
3325   else if (ShareMode == 1)
3326     ShareMode = 0;
3327   return CMDOK;
3328 }
3329 
CMD_ShareC(Boolean Negate,const char * Arg)3330 static CMDResult CMD_ShareC(Boolean Negate, const char *Arg)
3331 {
3332   UNUSED(Arg);
3333 
3334   if (!Negate)
3335     ShareMode = 2;
3336   else if (ShareMode == 2)
3337     ShareMode = 0;
3338   return CMDOK;
3339 }
3340 
CMD_ShareAssembler(Boolean Negate,const char * Arg)3341 static CMDResult CMD_ShareAssembler(Boolean Negate, const char *Arg)
3342 {
3343   UNUSED(Arg);
3344 
3345   if (!Negate)
3346     ShareMode = 3;
3347   else if (ShareMode == 3)
3348     ShareMode = 0;
3349   return CMDOK;
3350 }
3351 
CMD_DebugMode(Boolean Negate,const char * pArg)3352 static CMDResult CMD_DebugMode(Boolean Negate, const char *pArg)
3353 {
3354   String Arg;
3355 
3356   strmaxcpy(Arg, pArg, STRINGSIZE);
3357   UpString(Arg);
3358 
3359   if (Negate)
3360   {
3361     if (Arg[0] != '\0')
3362       return CMDErr;
3363     else
3364     {
3365       DebugMode = DebugNone;
3366       return CMDOK;
3367     }
3368   }
3369   else if (!strcmp(Arg, ""))
3370   {
3371     DebugMode = DebugMAP;
3372     return CMDOK;
3373   }
3374   else if (!strcmp(Arg, "ATMEL"))
3375   {
3376     DebugMode = DebugAtmel;
3377     return CMDArg;
3378   }
3379   else if (!strcmp(Arg, "MAP"))
3380   {
3381     DebugMode = DebugMAP;
3382     return CMDArg;
3383   }
3384   else if (!strcmp(Arg, "NOICE"))
3385   {
3386     DebugMode = DebugNoICE;
3387     return CMDArg;
3388   }
3389 #if 0
3390   else if (!strcmp(Arg, "A.OUT"))
3391   {
3392     DebugMode = DebugAOUT;
3393     return CMDArg;
3394   }
3395   else if (!strcmp(Arg, "COFF"))
3396   {
3397     DebugMode = DebugCOFF;
3398     return CMDArg;
3399   }
3400   else if (!strcmp(Arg, "ELF"))
3401   {
3402     DebugMode = DebugELF;
3403     return CMDArg;
3404   }
3405 #endif
3406   else
3407     return CMDErr;
3408 
3409 #if 0
3410   if (Negate)
3411     DebugMode = DebugNone;
3412   else
3413     DebugMode = DebugMAP;
3414   return CMDOK;
3415 #endif
3416 }
3417 
CMD_ListConsole(Boolean Negate,const char * Arg)3418 static CMDResult CMD_ListConsole(Boolean Negate, const char *Arg)
3419 {
3420   UNUSED(Arg);
3421 
3422   if (!Negate)
3423     ListMode = 1;
3424   else if (ListMode == 1)
3425     ListMode = 0;
3426   return CMDOK;
3427 }
3428 
CMD_ListRadix(Boolean Negate,const char * Arg)3429 static CMDResult CMD_ListRadix(Boolean Negate, const char *Arg)
3430 {
3431   Boolean OK;
3432   LargeWord NewListRadixBase;
3433 
3434   UNUSED(Arg);
3435 
3436   if (Negate)
3437   {
3438     ListRadixBase = 16;
3439     return CMDOK;
3440   }
3441   NewListRadixBase = ConstLongInt(Arg, &OK, 10);
3442   if (!OK || (NewListRadixBase < 2) || (NewListRadixBase > 36))
3443     return CMDErr;
3444   ListRadixBase = NewListRadixBase;
3445   return CMDArg;
3446 }
3447 
CMD_ListFile(Boolean Negate,const char * Arg)3448 static CMDResult CMD_ListFile(Boolean Negate, const char *Arg)
3449 {
3450   UNUSED(Arg);
3451 
3452   if (!Negate)
3453     ListMode = 2;
3454   else if (ListMode == 2)
3455     ListMode = 0;
3456   return CMDOK;
3457 }
3458 
CMD_SuppWarns(Boolean Negate,const char * Arg)3459 static CMDResult CMD_SuppWarns(Boolean Negate, const char *Arg)
3460 {
3461   UNUSED(Arg);
3462 
3463   SuppWarns = !Negate;
3464   return CMDOK;
3465 }
3466 
CMD_UseList(Boolean Negate,const char * Arg)3467 static CMDResult CMD_UseList(Boolean Negate, const char *Arg)
3468 {
3469   UNUSED(Arg);
3470 
3471   MakeUseList = !Negate;
3472   return CMDOK;
3473 }
3474 
CMD_CrossList(Boolean Negate,const char * Arg)3475 static CMDResult CMD_CrossList(Boolean Negate, const char *Arg)
3476 {
3477   UNUSED(Arg);
3478 
3479   MakeCrossList = !Negate;
3480   return CMDOK;
3481 }
3482 
CMD_SectionList(Boolean Negate,const char * Arg)3483 static CMDResult CMD_SectionList(Boolean Negate, const char *Arg)
3484 {
3485   UNUSED(Arg);
3486 
3487   MakeSectionList = !Negate;
3488   return CMDOK;
3489 }
3490 
CMD_BalanceTree(Boolean Negate,const char * Arg)3491 static CMDResult CMD_BalanceTree(Boolean Negate, const char *Arg)
3492 {
3493   UNUSED(Arg);
3494 
3495   BalanceTrees = !Negate;
3496   return CMDOK;
3497 }
3498 
CMD_MakeDebug(Boolean Negate,const char * Arg)3499 static CMDResult CMD_MakeDebug(Boolean Negate, const char *Arg)
3500 {
3501   UNUSED(Arg);
3502 
3503   if (!Negate)
3504   {
3505     MakeDebug = True;
3506     errno = 0;
3507     Debug = fopen("as.deb", "w");
3508     if (!Debug)
3509       ChkIO(ErrNum_ListWrError);
3510   }
3511   else if (MakeDebug)
3512   {
3513     MakeDebug = False;
3514     CloseIfOpen(&Debug);
3515   }
3516   return CMDOK;
3517 }
3518 
CMD_MacProOutput(Boolean Negate,const char * Arg)3519 static CMDResult CMD_MacProOutput(Boolean Negate, const char *Arg)
3520 {
3521   UNUSED(Arg);
3522 
3523   MacProOutput = !Negate;
3524   return CMDOK;
3525 }
3526 
CMD_MacroOutput(Boolean Negate,const char * Arg)3527 static CMDResult CMD_MacroOutput(Boolean Negate, const char *Arg)
3528 {
3529   UNUSED(Arg);
3530 
3531   MacroOutput = !Negate;
3532   return CMDOK;
3533 }
3534 
CMD_MakeIncludeList(Boolean Negate,const char * Arg)3535 static CMDResult CMD_MakeIncludeList(Boolean Negate, const char *Arg)
3536 {
3537   UNUSED(Arg);
3538 
3539   MakeIncludeList = !Negate;
3540   return CMDOK;
3541 }
3542 
CMD_CodeOutput(Boolean Negate,const char * Arg)3543 static CMDResult CMD_CodeOutput(Boolean Negate, const char *Arg)
3544 {
3545   UNUSED(Arg);
3546 
3547   CodeOutput = !Negate;
3548   return CMDOK;
3549 }
3550 
CMD_MsgIfRepass(Boolean Negate,const char * Arg)3551 static CMDResult CMD_MsgIfRepass(Boolean Negate, const char *Arg)
3552 {
3553   Boolean OK;
3554   UNUSED(Arg);
3555 
3556   MsgIfRepass = !Negate;
3557   if (MsgIfRepass)
3558   {
3559     if (Arg[0] == '\0')
3560     {
3561       PassNoForMessage = 1;
3562       return CMDOK;
3563     }
3564     else
3565     {
3566       PassNoForMessage = ConstLongInt(Arg, &OK, 10);
3567       if (!OK)
3568       {
3569         PassNoForMessage = 1;
3570         return CMDOK;
3571       }
3572       else if (PassNoForMessage < 1)
3573         return CMDErr;
3574       else
3575         return CMDArg;
3576     }
3577   }
3578   else
3579     return CMDOK;
3580 }
3581 
CMD_Relaxed(Boolean Negate,const char * pArg)3582 static CMDResult CMD_Relaxed(Boolean Negate, const char *pArg)
3583 {
3584   UNUSED(pArg);
3585 
3586   DefRelaxedMode = !Negate;
3587   return CMDOK;
3588 }
3589 
CMD_ExtendErrors(Boolean Negate,const char * Arg)3590 static CMDResult CMD_ExtendErrors(Boolean Negate, const char *Arg)
3591 {
3592   UNUSED(Arg);
3593 
3594   if ((Negate) && (ExtendErrors > 0))
3595     ExtendErrors--;
3596   else if ((!Negate) && (ExtendErrors < 2))
3597     ExtendErrors++;
3598 
3599   return CMDOK;
3600 }
3601 
CMD_NumericErrors(Boolean Negate,const char * Arg)3602 static CMDResult CMD_NumericErrors(Boolean Negate, const char *Arg)
3603 {
3604   UNUSED(Arg);
3605 
3606   NumericErrors = !Negate;
3607   return CMDOK;
3608 }
3609 
CMD_HexLowerCase(Boolean Negate,const char * Arg)3610 static CMDResult CMD_HexLowerCase(Boolean Negate, const char *Arg)
3611 {
3612   UNUSED(Arg);
3613 
3614   HexStartCharacter = Negate ? 'A' : 'a';
3615   return CMDOK;
3616 }
3617 
CMD_QuietMode(Boolean Negate,const char * Arg)3618 static CMDResult CMD_QuietMode(Boolean Negate, const char *Arg)
3619 {
3620   UNUSED(Arg);
3621 
3622   QuietMode = !Negate;
3623   return CMDOK;
3624 }
3625 
CMD_ThrowErrors(Boolean Negate,const char * Arg)3626 static CMDResult CMD_ThrowErrors(Boolean Negate, const char *Arg)
3627 {
3628   UNUSED(Arg);
3629 
3630   ThrowErrors = !Negate;
3631   return CMDOK;
3632 }
3633 
CMD_CaseSensitive(Boolean Negate,const char * Arg)3634 static CMDResult CMD_CaseSensitive(Boolean Negate, const char *Arg)
3635 {
3636   UNUSED(Arg);
3637 
3638   CaseSensitive = !Negate;
3639   return CMDOK;
3640 }
3641 
CMD_GNUErrors(Boolean Negate,const char * Arg)3642 static CMDResult CMD_GNUErrors(Boolean Negate, const char *Arg)
3643 {
3644   UNUSED(Arg);
3645 
3646   GNUErrors  =  !Negate;
3647   return CMDOK;
3648 }
3649 
CMD_IncludeList(Boolean Negate,const char * Arg)3650 static CMDResult CMD_IncludeList(Boolean Negate, const char *Arg)
3651 {
3652   char *p;
3653   String Copy, part;
3654 
3655   if (*Arg == '\0') return CMDErr;
3656   else
3657   {
3658     strmaxcpy(Copy, Arg, STRINGSIZE);
3659     do
3660     {
3661       p = strrchr(Copy, DIRSEP);
3662       if (!p)
3663       {
3664         strmaxcpy(part, Copy, STRINGSIZE);
3665         *Copy = '\0';
3666       }
3667       else
3668       {
3669         *p = '\0';
3670         strmaxcpy(part, p + 1, STRINGSIZE);
3671       }
3672       if (Negate)
3673         RemoveIncludeList(part);
3674       else
3675         AddIncludeList(part);
3676     }
3677     while (Copy[0] != '\0');
3678     return CMDArg;
3679   }
3680 }
3681 
CMD_ListMask(Boolean Negate,const char * Arg)3682 static CMDResult CMD_ListMask(Boolean Negate, const char *Arg)
3683 {
3684   Word erg;
3685   Boolean OK;
3686 
3687   if (Arg[0] == '\0')
3688     return CMDErr;
3689   else
3690   {
3691     erg = ConstLongInt(Arg, &OK, 10);
3692     if ((!OK) || (erg > 511))
3693       return CMDErr;
3694     else
3695     {
3696       ListMask = Negate ? (ListMask & ~erg) : (ListMask | erg);
3697       return CMDArg;
3698     }
3699   }
3700 }
3701 
CMD_DefSymbol(Boolean Negate,const char * Arg)3702 static CMDResult CMD_DefSymbol(Boolean Negate, const char *Arg)
3703 {
3704   String Copy, Part, Name;
3705   char *p;
3706   TempResult t;
3707 
3708   if (Arg[0] == '\0')
3709     return CMDErr;
3710 
3711   strmaxcpy(Copy, Arg, STRINGSIZE);
3712   do
3713   {
3714     p = QuotPos(Copy, ',');
3715     if (!p)
3716     {
3717       strmaxcpy(Part, Copy, STRINGSIZE);
3718       Copy[0] = '\0';
3719     }
3720     else
3721     {
3722       *p = '\0';
3723       strmaxcpy(Part, Copy, STRINGSIZE);
3724       strmov(Copy, p + 1);
3725     }
3726    if (!CaseSensitive)
3727      UpString(Part);
3728    p = QuotPos(Part, '=');
3729    if (!p)
3730    {
3731      strmaxcpy(Name, Part, STRINGSIZE);
3732      Part[0] = '\0';
3733    }
3734    else
3735    {
3736      *p = '\0';
3737      strmaxcpy(Name, Part, STRINGSIZE);
3738      strmov(Part, p + 1);
3739    }
3740    if (!ChkSymbName(Name))
3741      return CMDErr;
3742    if (Negate)
3743      RemoveDefSymbol(Name);
3744    else
3745    {
3746      AsmParsInit();
3747      if (Part[0] != '\0')
3748      {
3749        EvalExpression(Part, &t);
3750        if ((t.Typ == TempNone) || mFirstPassUnknown(t.Flags))
3751          return CMDErr;
3752      }
3753      else
3754      {
3755        t.Typ = TempInt;
3756        t.Contents.Int = 1;
3757      }
3758      AddDefSymbol(Name, &t);
3759    }
3760   }
3761   while (Copy[0] != '\0');
3762 
3763   return CMDArg;
3764 }
3765 
CMD_ErrorPath(Boolean Negate,const char * Arg)3766 static CMDResult CMD_ErrorPath(Boolean Negate, const char *Arg)
3767 {
3768   if (Negate)
3769     return CMDErr;
3770   else if (Arg[0] == '\0')
3771   {
3772     ErrorPath[0] = '\0';
3773     return CMDOK;
3774   }
3775   else
3776   {
3777     strmaxcpy(ErrorPath, Arg, STRINGSIZE);
3778     return CMDArg;
3779   }
3780 }
3781 
CMD_HardRanges(Boolean Negate,const char * Arg)3782 static CMDResult CMD_HardRanges(Boolean Negate, const char *Arg)
3783 {
3784   UNUSED(Arg);
3785 
3786   HardRanges = Negate;
3787   return CMDOK;
3788 }
3789 
CMD_OutFile(Boolean Negate,const char * Arg)3790 static CMDResult CMD_OutFile(Boolean Negate, const char *Arg)
3791 {
3792   if (Arg[0] == '\0')
3793   {
3794     if (Negate)
3795     {
3796       ClearOutList();
3797       return CMDOK;
3798     }
3799     else
3800       return CMDErr;
3801   }
3802   else
3803   {
3804     if (Negate)
3805       RemoveFromOutList(Arg);
3806     else
3807       AddToOutList(Arg);
3808     return CMDArg;
3809   }
3810 }
3811 
CMD_ShareOutFile(Boolean Negate,const char * Arg)3812 static CMDResult CMD_ShareOutFile(Boolean Negate, const char *Arg)
3813 {
3814   if (Arg[0] == '\0')
3815   {
3816     if (Negate)
3817     {
3818       ClearShareOutList();
3819       return CMDOK;
3820     }
3821     else
3822       return CMDErr;
3823   }
3824   else
3825   {
3826     if (Negate)
3827       RemoveFromShareOutList(Arg);
3828     else
3829       AddToShareOutList(Arg);
3830     return CMDArg;
3831   }
3832 }
3833 
CMD_ListOutFile(Boolean Negate,const char * Arg)3834 static CMDResult CMD_ListOutFile(Boolean Negate, const char *Arg)
3835 {
3836   if (Arg[0] == '\0')
3837   {
3838     if (Negate)
3839     {
3840       ClearListOutList();
3841       return CMDOK;
3842     }
3843     else
3844       return CMDErr;
3845   }
3846   else
3847   {
3848     if (Negate)
3849       RemoveFromListOutList(Arg);
3850     else
3851       AddToListOutList(Arg);
3852     return CMDArg;
3853   }
3854 }
3855 
CMD_CPUAlias_ChkCPUName(char * s)3856 static Boolean CMD_CPUAlias_ChkCPUName(char *s)
3857 {
3858   int z;
3859 
3860   for (z = 0; z < (int)strlen(s); z++)
3861     if (!isalnum((unsigned int) s[z]))
3862       return False;
3863   return True;
3864 }
3865 
CMD_CPUAlias(Boolean Negate,const char * Arg)3866 static CMDResult CMD_CPUAlias(Boolean Negate, const char *Arg)
3867 {
3868   const char *p;
3869   String s1, s2;
3870 
3871   if (Negate)
3872     return CMDErr;
3873   else if (Arg[0] == '\0')
3874     return CMDErr;
3875   else
3876   {
3877     p = strchr(Arg, '=');
3878     if (!p)
3879       return CMDErr;
3880     else
3881     {
3882       strmemcpy(s1, STRINGSIZE, Arg, p - Arg);
3883       UpString(s1);
3884       strmaxcpy(s2, p + 1, STRINGSIZE);
3885       UpString(s2);
3886       if (!(CMD_CPUAlias_ChkCPUName(s1) && CMD_CPUAlias_ChkCPUName(s2)))
3887         return CMDErr;
3888       else if (!AddCPUAlias(s2, s1))
3889         return CMDErr;
3890       else
3891         return CMDArg;
3892     }
3893   }
3894 }
3895 
CMD_SetCPU(Boolean Negate,const char * Arg)3896 static CMDResult CMD_SetCPU(Boolean Negate, const char *Arg)
3897 {
3898   if (Negate)
3899   {
3900     *DefCPU = '\0';
3901     return CMDOK;
3902   }
3903   else
3904   {
3905     if (*Arg == '\0')
3906       return CMDErr;
3907 
3908     strmaxcpy(DefCPU, Arg, sizeof(DefCPU) - 1);
3909     NLS_UpString(DefCPU);
3910 
3911     if (!LookupCPUDefByName(DefCPU))
3912     {
3913       *DefCPU = '\0';
3914       return CMDErr;
3915     }
3916     return CMDArg;
3917   }
3918 }
3919 
CMD_NoICEMask(Boolean Negate,const char * Arg)3920 static CMDResult CMD_NoICEMask(Boolean Negate, const char *Arg)
3921 {
3922   Word erg;
3923   Boolean OK;
3924 
3925   if (Negate)
3926   {
3927     NoICEMask = 1 << SegCode;
3928     return CMDOK;
3929   }
3930   else if (Arg[0] == '\0')
3931     return CMDErr;
3932   else
3933   {
3934     erg = ConstLongInt(Arg, &OK, 10);
3935     if ((!OK) || (erg > (1 << PCMax)))
3936       return CMDErr;
3937     else
3938     {
3939       NoICEMask = erg;
3940       return CMDArg;
3941     }
3942   }
3943 }
3944 
CMD_MaxErrors(Boolean Negate,const char * Arg)3945 static CMDResult CMD_MaxErrors(Boolean Negate, const char *Arg)
3946 {
3947   if (Negate)
3948   {
3949     MaxErrors = 0;
3950     return CMDOK;
3951   }
3952   else if (Arg[0] == '\0')
3953     return CMDErr;
3954   else
3955   {
3956     Boolean OK;
3957     LongWord NewMaxErrors = ConstLongInt(Arg, &OK, 10);
3958 
3959     if (!OK)
3960       return CMDErr;
3961     MaxErrors = NewMaxErrors;
3962     return CMDArg;
3963   }
3964 }
3965 
CMD_TreatWarningsAsErrors(Boolean Negate,const char * Arg)3966 static CMDResult CMD_TreatWarningsAsErrors(Boolean Negate, const char *Arg)
3967 {
3968   UNUSED(Arg);
3969 
3970   TreatWarningsAsErrors = !Negate;
3971   return CMDOK;
3972 }
3973 
ParamError(Boolean InEnv,char * Arg)3974 static void ParamError(Boolean InEnv, char *Arg)
3975 {
3976   printf("%s%s\n", getmessage((InEnv) ? Num_ErrMsgInvEnvParam : Num_ErrMsgInvParam), Arg);
3977   exit(4);
3978 }
3979 
3980 #define ASParamCnt (sizeof(ASParams) / sizeof(*ASParams))
3981 
3982 static CMDRec ASParams[] =
3983 {
3984   { "A"             , CMD_BalanceTree     },
3985   { "ALIAS"         , CMD_CPUAlias        },
3986   { "a"             , CMD_ShareAssembler  },
3987   { "C"             , CMD_CrossList       },
3988   { "c"             , CMD_ShareC          },
3989   { "CPU"           , CMD_SetCPU          },
3990   { "D"             , CMD_DefSymbol       },
3991   { "E"             , CMD_ErrorPath       },
3992   { "g"             , CMD_DebugMode       },
3993   { "G"             , CMD_CodeOutput      },
3994   { "GNUERRORS"     , CMD_GNUErrors       },
3995   { "h"             , CMD_HexLowerCase    },
3996   { "i"             , CMD_IncludeList     },
3997   { "I"             , CMD_MakeIncludeList },
3998   { "L"             , CMD_ListFile        },
3999   { "l"             , CMD_ListConsole     },
4000   { "LISTRADIX"     , CMD_ListRadix       },
4001   { "M"             , CMD_MacroOutput     },
4002   { "MAXERRORS"     , CMD_MaxErrors       },
4003   { "n"             , CMD_NumericErrors   },
4004   { "NOICEMASK"     , CMD_NoICEMask       },
4005   { "o"             , CMD_OutFile         },
4006   { "P"             , CMD_MacProOutput    },
4007   { "p"             , CMD_SharePascal     },
4008   { "q"             , CMD_QuietMode       },
4009   { "QUIET"         , CMD_QuietMode       },
4010   { "r"             , CMD_MsgIfRepass     },
4011   { "RELAXED"       , CMD_Relaxed         },
4012   { "s"             , CMD_SectionList     },
4013   { "SHAREOUT"      , CMD_ShareOutFile    },
4014   { "OLIST"         , CMD_ListOutFile     },
4015   { "t"             , CMD_ListMask        },
4016   { "u"             , CMD_UseList         },
4017   { "U"             , CMD_CaseSensitive   },
4018   { "w"             , CMD_SuppWarns       },
4019   { "WARNRANGES"    , CMD_HardRanges      },
4020   { "WERROR"        , CMD_TreatWarningsAsErrors },
4021   { "x"             , CMD_ExtendErrors    },
4022   { "X"             , CMD_MakeDebug       },
4023   { "Y"             , CMD_ThrowErrors     }
4024 };
4025 
4026 /*--------------------------------------------------------------------------*/
4027 
4028 #ifdef __sunos__
4029 
4030 extern void on_exit(void (*procp)(int status, caddr_t arg),caddr_t arg);
4031 
GlobExitProc(int status,caddr_t arg)4032 static void GlobExitProc(int status, caddr_t arg)
4033 {
4034   if (MakeDebug)
4035     CloseIfOpen(&Debug);
4036 }
4037 
4038 #else
4039 
4040 /* Might no longer need this with newer TCC versions: */
4041 
4042 #ifdef __TINYC__
4043 void * __dso_handle __attribute((visibility("hidden"))) = &__dso_handle;
4044 #endif
4045 
GlobExitProc(void)4046 static void GlobExitProc(void)
4047 {
4048   if (MakeDebug)
4049     CloseIfOpen(&Debug);
4050 }
4051 
4052 #endif
4053 
4054 static int LineZ;
4055 
NxtLine(void)4056 static void NxtLine(void)
4057 {
4058   if (++LineZ == 23)
4059   {
4060     LineZ = 0;
4061     if (Redirected != NoRedir)
4062       return;
4063     WrConsoleLine(getmessage(Num_KeyWaitMsg), False);
4064     fflush(stdout);
4065     while (getchar() != '\n');
4066     printf("%s", CursUp);
4067   }
4068 }
4069 
WrHead(void)4070 static void WrHead(void)
4071 {
4072   if (!QuietMode)
4073   {
4074     String Tmp;
4075 
4076     as_snprintf(Tmp, sizeof(Tmp), "%s%s", getmessage(Num_InfoMessMacroAss), Version);
4077     WrConsoleLine(Tmp, True); NxtLine();
4078     as_snprintf(Tmp, sizeof(Tmp), "(%s-%s)", ARCHPRNAME, ARCHSYSNAME);
4079     WrConsoleLine(Tmp, True); NxtLine();
4080     WrConsoleLine(InfoMessCopyright, True); NxtLine();
4081     WriteCopyrights(NxtLine);
4082     WrConsoleLine("\n", True); NxtLine();
4083   }
4084 }
4085 
main(int argc,char ** argv)4086 int main(int argc, char **argv)
4087 {
4088   char *Env, *ph1, *ph2;
4089   String Dummy;
4090   static Boolean First = TRUE;
4091   CMDProcessed ParUnprocessed;     /* bearbeitete Kommandozeilenparameter */
4092 
4093   FileMask = (char*)malloc(sizeof(char) * STRINGSIZE);
4094 
4095   if (First)
4096   {
4097     endian_init();
4098     nls_init();
4099     bpemu_init();
4100     stdhandl_init();
4101     strutil_init();
4102     chunks_init();
4103     if (!NLS_Initialize(&argc, argv))
4104       exit(4);
4105 
4106     nlmessages_init("as.msg", *argv, MsgId1, MsgId2);
4107     ioerrs_init(*argv);
4108     cmdarg_init(*argv);
4109 
4110     asmfnums_init();
4111     asminclist_init();
4112     asmitree_init();
4113 
4114     asmdef_init();
4115     cpulist_init();
4116     asmsub_init();
4117     asmpars_init();
4118 
4119     asmmac_init();
4120     asmstruct_init();
4121     asmif_init();
4122     asmcode_init();
4123     asmlabel_init();
4124     asmdebug_init();
4125 
4126     codeallg_init();
4127 
4128     code68k_init();
4129     code56k_init();
4130     code601_init();
4131     codemcore_init();
4132     codexgate_init();
4133     code68_init();
4134     code6805_init();
4135     code6809_init();
4136     code6812_init();
4137     codes12z_init();
4138     code6816_init();
4139     code68rs08_init();
4140     codeh8_3_init();
4141     codeh8_5_init();
4142     code7000_init();
4143     code65_init();
4144     codeh16_init();
4145     code7700_init();
4146     codehmcs400_init();
4147     code4500_init();
4148     codem16_init();
4149     codem16c_init();
4150     code4004_init();
4151     code8008_init();
4152     code48_init();
4153     code51_init();
4154     code96_init();
4155     code85_init();
4156     code86_init();
4157     code960_init();
4158     code8x30x_init();
4159     code2650_init();
4160     codexa_init();
4161     codeavr_init();
4162     code29k_init();
4163     code166_init();
4164     codez80_init();
4165     codez8_init();
4166     codekcpsm_init();
4167     codekcpsm3_init();
4168     codemico8_init();
4169     code96c141_init();
4170     code90c141_init();
4171     code87c800_init();
4172     code870c_init();
4173     code47c00_init();
4174     code97c241_init();
4175     code9331_init();
4176     code16c5x_init();
4177     code16c8x_init();
4178     code17c4x_init();
4179     codesx20_init();
4180     codest6_init();
4181     codest7_init();
4182     codest9_init();
4183     code6804_init();
4184     code3201x_init();
4185     code3202x_init();
4186     code3203x_init();
4187     code3205x_init();
4188     code32054x_init();
4189     code3206x_init();
4190     code9900_init();
4191     codetms7_init();
4192     code370_init();
4193     codemsp_init();
4194     codetms1_init();
4195     code78c10_init();
4196     code75xx_init();
4197     code75k0_init();
4198     code78k0_init();
4199     code78k2_init();
4200     code78k3_init();
4201     code78k4_init();
4202     code7720_init();
4203     code77230_init();
4204     codescmp_init();
4205     code807x_init();
4206     codecop4_init();
4207     codecop8_init();
4208     codesc14xxx_init();
4209     codeace_init();
4210     codef8_init();
4211     code53c8xx_init();
4212     codef2mc8_init();
4213     codef2mc16_init();
4214     codemn1610_init();
4215     codemn2610_init();
4216     codeolms40_init();
4217     codeolms50_init();
4218     code1802_init();
4219     codevector_init();
4220     codexcore_init();
4221     code1750_init();
4222     codekenbak_init();
4223     First = FALSE;
4224   }
4225 
4226 #ifdef __sunos__
4227   on_exit(GlobExitProc, (caddr_t) NULL);
4228 #else
4229 # ifndef __MUNIX__
4230   atexit(GlobExitProc);
4231 # endif
4232 #endif
4233 
4234   *CursUp = '\0';
4235   switch (Redirected)
4236   {
4237     case NoRedir:
4238       Env = getenv("USEANSI");
4239       strmaxcpy(Dummy, Env ? Env : "Y", STRINGSIZE);
4240       if (as_toupper(Dummy[0]) == 'N')
4241       {
4242       }
4243       else
4244       {
4245         strcpy(CursUp, " [A"); CursUp[0] = Char_ESC;
4246       }
4247       break;
4248     case RedirToDevice:
4249       break;
4250     case RedirToFile:
4251       break;
4252   }
4253 
4254   ShareMode = 0;
4255   ListMode = 0;
4256   IncludeList[0] = '\0';
4257   SuppWarns = False;
4258   MakeUseList = False;
4259   MakeCrossList = False;
4260   MakeSectionList = False;
4261   MakeIncludeList = False;
4262   ListMask = 0x1ff;
4263   MakeDebug = False;
4264   ExtendErrors = 0;
4265   DefRelaxedMode = False;
4266   MacroOutput = False;
4267   MacProOutput = False;
4268   CodeOutput = True;
4269   strcpy(ErrorPath,  "!2");
4270   MsgIfRepass = False;
4271   QuietMode = False;
4272   NumericErrors = False;
4273   DebugMode = DebugNone;
4274   CaseSensitive = False;
4275   ThrowErrors = False;
4276   HardRanges = True;
4277   NoICEMask = 1 << SegCode;
4278   GNUErrors = False;
4279   MaxErrors = 0;
4280   TreatWarningsAsErrors = False;
4281   ListRadixBase = 16;
4282 
4283   LineZ = 0;
4284 
4285   if (argc <= 1)
4286   {
4287     WrHead();
4288     printf("%s%s%s\n", getmessage(Num_InfoMessHead1), GetEXEName(argv[0]), getmessage(Num_InfoMessHead2));
4289     NxtLine();
4290     for (ph1 = getmessage(Num_InfoMessHelp), ph2 = strchr(ph1, '\n'); ph2; ph1 = ph2 + 1, ph2 = strchr(ph1, '\n'))
4291     {
4292       *ph2 = '\0';
4293       printf("%s\n", ph1);
4294       NxtLine();
4295       *ph2 = '\n';
4296     }
4297     PrintCPUList(NxtLine);
4298     ClearCPUList();
4299     exit(1);
4300   }
4301 
4302 #if defined(INCDIR)
4303   CMD_IncludeList(False, INCDIR);
4304 #endif
4305   ProcessCMD(argc, argv, ASParams, ASParamCnt, ParUnprocessed, EnvName, ParamError);
4306 
4307   /* wegen QuietMode dahinter */
4308 
4309   WrHead();
4310 
4311   /* ListRadixBase must have been set */
4312 
4313   asmlist_init();
4314 
4315   GlobErrFlag = False;
4316   if (ErrorPath[0] != '\0')
4317   {
4318     strcpy(ErrorName, ErrorPath);
4319     unlink(ErrorName);
4320   }
4321 
4322   if (StringListEmpty(FileArgList))
4323   {
4324     printf("%s [%s] ", getmessage(Num_InvMsgSource), SrcSuffix);
4325     fflush(stdout);
4326     if (!fgets(FileMask, STRINGSIZE, stdin))
4327       return 0;
4328     if ((*FileMask) && (FileMask[strlen(FileMask) - 1] == '\n'))
4329       FileMask[strlen(FileMask) - 1] = '\0';
4330     AssembleGroup();
4331   }
4332   else
4333   {
4334     StringRecPtr Lauf;
4335     const char *pFile;
4336 
4337     pFile = GetStringListFirst(FileArgList, &Lauf);
4338     while ((pFile) && (*pFile))
4339     {
4340       strmaxcpy(FileMask, pFile, STRINGSIZE);
4341       AssembleGroup();
4342       pFile = GetStringListNext(&Lauf);
4343     }
4344   }
4345 
4346   if (*ErrorPath)
4347     CloseIfOpen(&ErrorFile);
4348 
4349   ClearCPUList();
4350 
4351   return GlobErrFlag ? 2 : 0;
4352 }
4353