Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

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