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