Subversion Repositories pentevo

Rev

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

  1. /* asmmac.c  */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Unterroutinen des Makroprozessors                                         */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "nlmessages.h"
  17. #include "as.rsc"
  18. #include "stringlists.h"
  19. #include "strutil.h"
  20. #include "chunks.h"
  21. #include "trees.h"
  22. #include "asmdef.h"
  23. #include "asmsub.h"
  24. #include "asmpars.h"
  25. #include "asmif.h"
  26.  
  27. #include "asmmac.h"
  28.  
  29.  
  30. PInputTag FirstInputTag;
  31. POutputTag FirstOutputTag;
  32.  
  33. /*=== Praeprozessor =======================================================*/
  34.  
  35. /*-------------------------------------------------------------------------*/
  36. /* Verwaltung define-Symbole */
  37.  
  38. static void FreeDefine(PDefinement P)
  39. {
  40.   free(P->TransFrom);
  41.   free(P->TransTo);
  42.   free(P);
  43. }
  44.  
  45. static void EnterDefine(char *Name, char *Definition)
  46. {
  47.   PDefinement Neu;
  48.   int z, l;
  49.  
  50.   if (!ChkSymbName(Name))
  51.   {
  52.     WrXError(ErrNum_InvSymName, Name);
  53.     return;
  54.   };
  55.  
  56.   Neu = FirstDefine;
  57.   while (Neu)
  58.   {
  59.     if (!strcmp(Neu->TransFrom, Name))
  60.     {
  61.       if (PassNo == 1)
  62.         WrXError(ErrNum_DoubleDef, Name);
  63.       return;
  64.     }
  65.     Neu = Neu->Next;
  66.   }
  67.  
  68.   Neu = (PDefinement) malloc(sizeof(TDefinement));
  69.   Neu->Next = FirstDefine;
  70.   Neu->TransFrom = as_strdup(Name);
  71.   if (!CaseSensitive)
  72.     NLS_UpString(Neu->TransFrom);
  73.   Neu->TransTo = as_strdup(Definition);
  74.   l = strlen(Name);
  75.   for (z = 0; z < 256; Neu->Compiled[z++] = l);
  76.   for (z = 0; z < l - 1; z++)
  77.     Neu->Compiled[(unsigned int)Neu->TransFrom[z]] = l - (z + 1);
  78.   FirstDefine = Neu;
  79. }
  80.  
  81. static void RemoveDefine(char *Name_O)
  82. {
  83.   PDefinement Lauf, Del;
  84.   String Name;
  85.  
  86.   strmaxcpy(Name, Name_O, STRINGSIZE);
  87.   if (!CaseSensitive)
  88.     NLS_UpString(Name);
  89.  
  90.   Del = NULL;
  91.  
  92.   if (FirstDefine)
  93.   {
  94.     if (!strcmp(FirstDefine->TransFrom, Name))
  95.     {
  96.       Del = FirstDefine;
  97.       FirstDefine = FirstDefine->Next;
  98.     }
  99.     else
  100.     {
  101.       Lauf = FirstDefine;
  102.       while ((Lauf->Next) && (strcmp(Lauf->Next->TransFrom, Name)))
  103.         Lauf = Lauf->Next;
  104.       if (Lauf->Next)
  105.       {
  106.         Del = Lauf->Next;
  107.         Lauf->Next = Del->Next;
  108.       }
  109.     }
  110.    }
  111.  
  112.    if (!Del)
  113.      WrXError(ErrNum_SymbolUndef, Name);
  114.    else
  115.      FreeDefine(Del);
  116. }
  117.  
  118. void PrintDefineList(void)
  119. {
  120.   PDefinement Lauf;
  121.   String OneS;
  122.  
  123.   if (!FirstDefine)
  124.     return;
  125.  
  126.   NewPage(ChapDepth, True);
  127.   WrLstLine(getmessage(Num_ListDefListHead1));
  128.   WrLstLine(getmessage(Num_ListDefListHead2));
  129.   WrLstLine("");
  130.  
  131.   Lauf = FirstDefine;
  132.   while (Lauf)
  133.   {
  134.     strmaxcpy(OneS, Lauf->TransFrom, STRINGSIZE);
  135.     strmaxcat(OneS, Blanks(10 - (strlen(Lauf->TransFrom)%10)), STRINGSIZE);
  136.     strmaxcat(OneS, " = ", STRINGSIZE);
  137.     strmaxcat(OneS, Lauf->TransTo, STRINGSIZE);
  138.     WrLstLine(OneS);
  139.     Lauf = Lauf->Next;
  140.   }
  141.   WrLstLine("");
  142. }
  143.  
  144. void ClearDefineList(void)
  145. {
  146.   PDefinement Temp;
  147.  
  148.   while (FirstDefine)
  149.   {
  150.     Temp = FirstDefine;
  151.     FirstDefine = FirstDefine->Next;
  152.     FreeDefine(Temp);
  153.   }
  154. }
  155.  
  156. /*------------------------------------------------------------------------*/
  157. /* Interface */
  158.  
  159. void Preprocess(void)
  160. {
  161.   String h, Cmd, Arg;
  162.   char *p;
  163.  
  164.   p = strchr(OneLine.p_str, '#') + 1;
  165.   strmaxcpy(h, p, STRINGSIZE);
  166.   p = FirstBlank(h);
  167.   if (!p)
  168.   {
  169.     strmaxcpy(Cmd, h, STRINGSIZE);
  170.     *h = '\0';
  171.   }
  172.   else
  173.     SplitString(h, Cmd, h, p);
  174.  
  175.   KillPrefBlanks(h);
  176.   KillPostBlanks(h);
  177.  
  178.   if (!IfAsm)
  179.     return;
  180.  
  181.   if (!as_strcasecmp(Cmd, "DEFINE"))
  182.   {
  183.     p = FirstBlank(h);
  184.     if (p)
  185.     {
  186.       SplitString(h, Arg, h, p);
  187.       KillPrefBlanks(h);
  188.       EnterDefine(Arg, h);
  189.     }
  190.   }
  191.   else if (!as_strcasecmp(Cmd, "UNDEF"))
  192.     RemoveDefine(h);
  193.   else
  194.     WrXError(ErrNum_InvalidPrepDir, Cmd);
  195.  
  196.   CodeLen = 0;
  197. }
  198.  
  199. #define t_toupper(ch) ((CaseSensitive) ? (ch) : (as_toupper(ch)))
  200.  
  201. void ExpandDefines(char *Line)
  202. {
  203.   PDefinement Lauf;
  204.   sint LPos, Diff, p, p2, p3, z, z2, FromLen, ToLen, LineLen;
  205.  
  206.   Lauf = FirstDefine;
  207.   while (Lauf)
  208.   {
  209.     LPos = 0;
  210.     FromLen = strlen(Lauf->TransFrom);
  211.     ToLen = strlen(Lauf->TransTo);
  212.     Diff = ToLen - FromLen;
  213.     do
  214.     {
  215.       /* Stelle, ab der verbatim, suchen -->p */
  216.       p = LPos;
  217.       while ((p < (int)strlen(Line)) && (Line[p] != '\'') && (Line[p] != '"'))
  218.         p++;
  219.       /* nach Quellstring suchen, ersetzen, bis keine Treffer mehr */
  220.       p2 = LPos;
  221.       do
  222.       {
  223.         z2 = 0;
  224.         while ((z2 >= 0) && (p2 <= p - FromLen))
  225.         {
  226.           z2 = FromLen - 1;
  227.           z = p2 + z2;
  228.           while ((z2 >= 0) && (t_toupper(Line[z]) == Lauf->TransFrom[z2]))
  229.           {
  230.             z2--;
  231.             z--;
  232.           }
  233.           if (z2 >= 0)
  234.             p2 += Lauf->Compiled[(unsigned int)t_toupper(Line[p2 + FromLen - 1])];
  235.         }
  236.         if (z2 == -1)
  237.         {
  238.           if (((p2 == 0) || !ChkMacSymbChar(Line[p2 - 1]))
  239.            && ((p2 + FromLen == p) || !ChkMacSymbChar(Line[p2 + FromLen])))
  240.           {
  241.             if (Diff != 0)
  242.               memmove(Line + p2 + ToLen, Line + p2 + FromLen, strlen(Line) - p2 - FromLen + 1);
  243.             memcpy(Line + p2, Lauf->TransTo, ToLen);
  244.             p += Diff; /* !!! */
  245.             p2 += ToLen;
  246.           }
  247.           else
  248.             p2 += FromLen;
  249.         }
  250.       }
  251.       while (z2 == -1);
  252.  
  253.       /* Endposition verbatim suchen */
  254.  
  255.       p3 = p + 1;
  256.       LineLen = strlen(Line);
  257.       while ((p3 < LineLen) && (Line[p3] != Line[p]))
  258.         p3++;
  259.       /* Zaehler entsprechend herauf */
  260.       LPos = p3 + 1;
  261.     }
  262.     while (LPos <= LineLen - FromLen);
  263.     Lauf = Lauf->Next;
  264.   }
  265. }
  266.  
  267. /*=== Makrolistenverwaltung ===============================================*/
  268.  
  269. typedef struct sMacroNode
  270. {
  271.   TTree Tree;
  272.   Boolean Defined;
  273.   PMacroRec Contents;
  274. } TMacroNode, *PMacroNode;
  275.  
  276. static PMacroNode MacroRoot;
  277.  
  278. static Boolean MacroAdder(PTree *PDest, PTree Neu, void *pData)
  279. {
  280.   PMacroNode NewNode = (PMacroNode) Neu, *Node;
  281.   Boolean Protest = *((Boolean*)pData), Result = False;
  282.  
  283.   if (!PDest)
  284.   {
  285.     NewNode->Defined = TRUE;
  286.     return True;
  287.   }
  288.  
  289.   Node = (PMacroNode*) PDest;
  290.   if ((*Node)->Defined)
  291.   {
  292.     if (Protest) WrXError(ErrNum_DoubleMacro, Neu->Name);
  293.     else
  294.     {
  295.       ClearMacroRec(&((*Node)->Contents), TRUE);
  296.      (*Node)->Contents = NewNode->Contents;
  297.     }
  298.   }
  299.   else
  300.   {
  301.     ClearMacroRec(&((*Node)->Contents), TRUE);
  302.     (*Node)->Contents = NewNode->Contents;
  303.     (*Node)->Defined = True;
  304.     return True;
  305.   }
  306.   return Result;
  307. }
  308.  
  309. void AddMacro(PMacroRec Neu, LongInt DefSect, Boolean Protest)
  310. {
  311.   PMacroNode NewNode;
  312.   PTree TreeRoot;
  313.  
  314.   if (!CaseSensitive)
  315.     NLS_UpString(Neu->Name);
  316.   NewNode = (PMacroNode) malloc(sizeof(TMacroNode));
  317.   NewNode->Tree.Left = NULL;
  318.   NewNode->Tree.Right = NULL;
  319.   NewNode->Tree.Name = as_strdup(Neu->Name);
  320.   NewNode->Tree.Attribute = DefSect;
  321.   NewNode->Contents = Neu;
  322.  
  323.   TreeRoot = &(MacroRoot->Tree);
  324.   EnterTree(&TreeRoot, &(NewNode->Tree), MacroAdder, &Protest);
  325.   MacroRoot = (PMacroNode)TreeRoot;
  326. }
  327.  
  328. static PMacroRec FoundMacro_FNode(LongInt Handle, char *Part)
  329. {
  330.   PMacroNode Lauf;
  331.   PMacroRec Result = NULL;
  332.  
  333.   Lauf = (PMacroNode) SearchTree((PTree)MacroRoot, Part, Handle);
  334.   if (Lauf)
  335.     Result = Lauf->Contents;
  336.   return Result;
  337. }
  338.  
  339. Boolean FoundMacro(PMacroRec *Erg, const tStrComp *p_name)
  340. {
  341.   PSaveSection Lauf;
  342.  
  343.   *Erg = FoundMacro_FNode(MomSectionHandle, p_name->str.p_str);
  344.   if (*Erg)
  345.     return True;
  346.   Lauf = SectionStack;
  347.   while (Lauf)
  348.   {
  349.     *Erg = FoundMacro_FNode(Lauf->Handle, p_name->str.p_str);
  350.     if (*Erg)
  351.       return True;
  352.     Lauf = Lauf->Next;
  353.   }
  354.   return False;
  355. }
  356.  
  357. static void ClearMacroList_ClearNode(PTree Tree, void *pData)
  358. {
  359.   PMacroNode Node = (PMacroNode) Tree;
  360.   UNUSED(pData);
  361.  
  362.   ClearMacroRec(&(Node->Contents), TRUE);
  363. }
  364.  
  365. void ClearMacroList(void)
  366. {
  367.   PTree TreeRoot;
  368.  
  369.   TreeRoot = &(MacroRoot->Tree);
  370.    MacroRoot = NULL;
  371.   DestroyTree(&TreeRoot, ClearMacroList_ClearNode, NULL);
  372. }
  373.  
  374. static void ResetMacroDefines_ResetNode(PTree Tree, void *pData)
  375. {
  376.   PMacroNode Node = (PMacroNode)Tree;
  377.   UNUSED(pData);
  378.  
  379.   Node->Defined = False;
  380. }
  381.  
  382. void ResetMacroDefines(void)
  383. {
  384.   IterTree((PTree)MacroRoot, ResetMacroDefines_ResetNode, NULL);
  385. }
  386.  
  387. void ClearMacroRec(PMacroRec *Alt, Boolean Complete)
  388. {
  389.   if ((*Alt)->Name)
  390.   {
  391.     free((*Alt)->Name);
  392.     (*Alt)->Name = NULL;
  393.   }
  394.   ClearStringList(&((*Alt)->FirstLine));
  395.   ClearStringList(&((*Alt)->ParamNames));
  396.   ClearStringList(&((*Alt)->ParamDefVals));
  397.  
  398.   if (Complete)
  399.   {
  400.     free(*Alt);
  401.     *Alt = NULL;
  402.   }
  403. }
  404.  
  405. typedef struct
  406. {
  407.   LongInt Sum;
  408.   Boolean cnt;
  409.   String OneS;
  410. } TMacroListContext;
  411.  
  412. static void PrintMacroList_PNode(PTree Tree, void *pData)
  413. {
  414.   PMacroNode Node = (PMacroNode)Tree;
  415.   TMacroListContext *pContext = (TMacroListContext*) pData;
  416.   String h;
  417.  
  418.   strmaxcpy(h, Node->Contents->Name, STRINGSIZE);
  419.   if (Node->Tree.Attribute != -1)
  420.   {
  421.     strmaxcat(h, "[", STRINGSIZE);
  422.     strmaxcat(h, GetSectionName(Node->Tree.Attribute), STRINGSIZE);
  423.     strmaxcat(h, "]", STRINGSIZE);
  424.   }
  425.   if (Node->Contents->LstMacroExpMod.Count)
  426.   {
  427.     strmaxcat(h, "{", STRINGSIZE);
  428.     DumpLstMacroExpMod(&Node->Contents->LstMacroExpMod, h + strlen(h), sizeof(h) - strlen(h));
  429.     strmaxcat(h, "}", STRINGSIZE);
  430.   }
  431.   strmaxcat(pContext->OneS, h, STRINGSIZE);
  432.   if (strlen(h) < 37)
  433.     strmaxcat(pContext->OneS, Blanks(37 - strlen(h)), STRINGSIZE);
  434.   if (!(pContext->cnt))
  435.     strmaxcat(pContext->OneS, " | ", STRINGSIZE);
  436.   else
  437.   {
  438.     WrLstLine(pContext->OneS);
  439.     pContext->OneS[0] = '\0';
  440.   }
  441.   pContext->cnt = !pContext->cnt;
  442.   pContext->Sum++;
  443. }
  444.  
  445. void PrintMacroList(void)
  446. {
  447.   TMacroListContext Context;
  448.  
  449.   if (!MacroRoot)
  450.     return;
  451.  
  452.   NewPage(ChapDepth, True);
  453.   WrLstLine(getmessage(Num_ListMacListHead1));
  454.   WrLstLine(getmessage(Num_ListMacListHead2));
  455.   WrLstLine("");
  456.  
  457.   Context.OneS[0] = '\0';
  458.   Context.cnt = False;
  459.   Context.Sum = 0;
  460.   IterTree((PTree)MacroRoot, PrintMacroList_PNode, &Context);
  461.   if (Context.cnt)
  462.   {
  463.     Context.OneS[strlen(Context.OneS) - 1] = '\0';
  464.     WrLstLine(Context.OneS);
  465.   }
  466.   WrLstLine("");
  467.   as_snprintf(Context.OneS, sizeof(Context.OneS), "%7lu%s",
  468.               (unsigned long)Context.Sum,
  469.               getmessage((Context.Sum == 1) ? Num_ListMacSumMsg : Num_ListMacSumsMsg));
  470.   WrLstLine(Context.OneS);
  471.   WrLstLine("");
  472. }
  473.  
  474. /*=== Eingabefilter Makroprozessor ========================================*/
  475.  
  476. void asmmac_init(void)
  477. {
  478.   MacroRoot = NULL;
  479. }
  480.