Blame |
Last modification |
View Log
| Download
| RSS feed
| ?url?
/* asmmac.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Unterroutinen des Makroprozessors */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "nls.h"
#include "nlmessages.h"
#include "as.rsc"
#include "stringlists.h"
#include "strutil.h"
#include "chunks.h"
#include "trees.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmif.h"
#include "asmmac.h"
PInputTag FirstInputTag
;
POutputTag FirstOutputTag
;
/*=== Praeprozessor =======================================================*/
/*-------------------------------------------------------------------------*/
/* Verwaltung define-Symbole */
static void FreeDefine
(PDefinement P
)
{
free(P
->TransFrom
);
free(P
->TransTo
);
free(P
);
}
static void EnterDefine
(char *Name
, char *Definition
)
{
PDefinement Neu
;
int z
, l
;
if (!ChkSymbName
(Name
))
{
WrXError
(ErrNum_InvSymName
, Name
);
return;
};
Neu
= FirstDefine
;
while (Neu
)
{
if (!strcmp(Neu
->TransFrom
, Name
))
{
if (PassNo
== 1)
WrXError
(ErrNum_DoubleDef
, Name
);
return;
}
Neu
= Neu
->Next
;
}
Neu
= (PDefinement
) malloc(sizeof(TDefinement
));
Neu
->Next
= FirstDefine
;
Neu
->TransFrom
= as_strdup
(Name
);
if (!CaseSensitive
)
NLS_UpString
(Neu
->TransFrom
);
Neu
->TransTo
= as_strdup
(Definition
);
l
= strlen(Name
);
for (z
= 0; z
< 256; Neu
->Compiled
[z
++] = l
);
for (z
= 0; z
< l
- 1; z
++)
Neu
->Compiled
[(unsigned int)Neu
->TransFrom
[z
]] = l
- (z
+ 1);
FirstDefine
= Neu
;
}
static void RemoveDefine
(char *Name_O
)
{
PDefinement Lauf
, Del
;
String Name
;
strmaxcpy
(Name
, Name_O
, STRINGSIZE
);
if (!CaseSensitive
)
NLS_UpString
(Name
);
Del
= NULL
;
if (FirstDefine
)
{
if (!strcmp(FirstDefine
->TransFrom
, Name
))
{
Del
= FirstDefine
;
FirstDefine
= FirstDefine
->Next
;
}
else
{
Lauf
= FirstDefine
;
while ((Lauf
->Next
) && (strcmp(Lauf
->Next
->TransFrom
, Name
)))
Lauf
= Lauf
->Next
;
if (Lauf
->Next
)
{
Del
= Lauf
->Next
;
Lauf
->Next
= Del
->Next
;
}
}
}
if (!Del
)
WrXError
(ErrNum_SymbolUndef
, Name
);
else
FreeDefine
(Del
);
}
void PrintDefineList
(void)
{
PDefinement Lauf
;
String OneS
;
if (!FirstDefine
)
return;
NewPage
(ChapDepth
, True
);
WrLstLine
(getmessage
(Num_ListDefListHead1
));
WrLstLine
(getmessage
(Num_ListDefListHead2
));
WrLstLine
("");
Lauf
= FirstDefine
;
while (Lauf
)
{
strmaxcpy
(OneS
, Lauf
->TransFrom
, STRINGSIZE
);
strmaxcat
(OneS
, Blanks
(10 - (strlen(Lauf
->TransFrom
)%10)), STRINGSIZE
);
strmaxcat
(OneS
, " = ", STRINGSIZE
);
strmaxcat
(OneS
, Lauf
->TransTo
, STRINGSIZE
);
WrLstLine
(OneS
);
Lauf
= Lauf
->Next
;
}
WrLstLine
("");
}
void ClearDefineList
(void)
{
PDefinement Temp
;
while (FirstDefine
)
{
Temp
= FirstDefine
;
FirstDefine
= FirstDefine
->Next
;
FreeDefine
(Temp
);
}
}
/*------------------------------------------------------------------------*/
/* Interface */
void Preprocess
(void)
{
String h
, Cmd
, Arg
;
char *p
;
p
= strchr(OneLine.
p_str, '#') + 1;
strmaxcpy
(h
, p
, STRINGSIZE
);
p
= FirstBlank
(h
);
if (!p
)
{
strmaxcpy
(Cmd
, h
, STRINGSIZE
);
*h
= '\0';
}
else
SplitString
(h
, Cmd
, h
, p
);
KillPrefBlanks
(h
);
KillPostBlanks
(h
);
if (!IfAsm
)
return;
if (!as_strcasecmp
(Cmd
, "DEFINE"))
{
p
= FirstBlank
(h
);
if (p
)
{
SplitString
(h
, Arg
, h
, p
);
KillPrefBlanks
(h
);
EnterDefine
(Arg
, h
);
}
}
else if (!as_strcasecmp
(Cmd
, "UNDEF"))
RemoveDefine
(h
);
else
WrXError
(ErrNum_InvalidPrepDir
, Cmd
);
CodeLen
= 0;
}
#define t_toupper(ch) ((CaseSensitive) ? (ch) : (as_toupper(ch)))
void ExpandDefines
(char *Line
)
{
PDefinement Lauf
;
sint LPos
, Diff
, p
, p2
, p3
, z
, z2
, FromLen
, ToLen
, LineLen
;
Lauf
= FirstDefine
;
while (Lauf
)
{
LPos
= 0;
FromLen
= strlen(Lauf
->TransFrom
);
ToLen
= strlen(Lauf
->TransTo
);
Diff
= ToLen
- FromLen
;
do
{
/* Stelle, ab der verbatim, suchen -->p */
p
= LPos
;
while ((p
< (int)strlen(Line
)) && (Line
[p
] != '\'') && (Line
[p
] != '"'))
p
++;
/* nach Quellstring suchen, ersetzen, bis keine Treffer mehr */
p2
= LPos
;
do
{
z2
= 0;
while ((z2
>= 0) && (p2
<= p
- FromLen
))
{
z2
= FromLen
- 1;
z
= p2
+ z2
;
while ((z2
>= 0) && (t_toupper
(Line
[z
]) == Lauf
->TransFrom
[z2
]))
{
z2
--;
z
--;
}
if (z2
>= 0)
p2
+= Lauf
->Compiled
[(unsigned int)t_toupper
(Line
[p2
+ FromLen
- 1])];
}
if (z2
== -1)
{
if (((p2
== 0) || !ChkMacSymbChar
(Line
[p2
- 1]))
&& ((p2
+ FromLen
== p
) || !ChkMacSymbChar
(Line
[p2
+ FromLen
])))
{
if (Diff
!= 0)
memmove(Line
+ p2
+ ToLen
, Line
+ p2
+ FromLen
, strlen(Line
) - p2
- FromLen
+ 1);
memcpy(Line
+ p2
, Lauf
->TransTo
, ToLen
);
p
+= Diff
; /* !!! */
p2
+= ToLen
;
}
else
p2
+= FromLen
;
}
}
while (z2
== -1);
/* Endposition verbatim suchen */
p3
= p
+ 1;
LineLen
= strlen(Line
);
while ((p3
< LineLen
) && (Line
[p3
] != Line
[p
]))
p3
++;
/* Zaehler entsprechend herauf */
LPos
= p3
+ 1;
}
while (LPos
<= LineLen
- FromLen
);
Lauf
= Lauf
->Next
;
}
}
/*=== Makrolistenverwaltung ===============================================*/
typedef struct sMacroNode
{
TTree Tree
;
Boolean Defined
;
PMacroRec Contents
;
} TMacroNode
, *PMacroNode
;
static PMacroNode MacroRoot
;
static Boolean MacroAdder
(PTree
*PDest
, PTree Neu
, void *pData
)
{
PMacroNode NewNode
= (PMacroNode
) Neu
, *Node
;
Boolean Protest
= *((Boolean
*)pData
), Result
= False
;
if (!PDest
)
{
NewNode
->Defined
= TRUE
;
return True
;
}
Node
= (PMacroNode
*) PDest
;
if ((*Node
)->Defined
)
{
if (Protest
) WrXError
(ErrNum_DoubleMacro
, Neu
->Name
);
else
{
ClearMacroRec
(&((*Node
)->Contents
), TRUE
);
(*Node
)->Contents
= NewNode
->Contents
;
}
}
else
{
ClearMacroRec
(&((*Node
)->Contents
), TRUE
);
(*Node
)->Contents
= NewNode
->Contents
;
(*Node
)->Defined
= True
;
return True
;
}
return Result
;
}
void AddMacro
(PMacroRec Neu
, LongInt DefSect
, Boolean Protest
)
{
PMacroNode NewNode
;
PTree TreeRoot
;
if (!CaseSensitive
)
NLS_UpString
(Neu
->Name
);
NewNode
= (PMacroNode
) malloc(sizeof(TMacroNode
));
NewNode
->Tree.
Left = NULL
;
NewNode
->Tree.
Right = NULL
;
NewNode
->Tree.
Name = as_strdup
(Neu
->Name
);
NewNode
->Tree.
Attribute = DefSect
;
NewNode
->Contents
= Neu
;
TreeRoot
= &(MacroRoot
->Tree
);
EnterTree
(&TreeRoot
, &(NewNode
->Tree
), MacroAdder
, &Protest
);
MacroRoot
= (PMacroNode
)TreeRoot
;
}
static PMacroRec FoundMacro_FNode
(LongInt Handle
, char *Part
)
{
PMacroNode Lauf
;
PMacroRec Result
= NULL
;
Lauf
= (PMacroNode
) SearchTree
((PTree
)MacroRoot
, Part
, Handle
);
if (Lauf
)
Result
= Lauf
->Contents
;
return Result
;
}
Boolean FoundMacro
(PMacroRec
*Erg
, const tStrComp
*p_name
)
{
PSaveSection Lauf
;
*Erg
= FoundMacro_FNode
(MomSectionHandle
, p_name
->str.
p_str);
if (*Erg
)
return True
;
Lauf
= SectionStack
;
while (Lauf
)
{
*Erg
= FoundMacro_FNode
(Lauf
->Handle
, p_name
->str.
p_str);
if (*Erg
)
return True
;
Lauf
= Lauf
->Next
;
}
return False
;
}
static void ClearMacroList_ClearNode
(PTree Tree
, void *pData
)
{
PMacroNode Node
= (PMacroNode
) Tree
;
UNUSED
(pData
);
ClearMacroRec
(&(Node
->Contents
), TRUE
);
}
void ClearMacroList
(void)
{
PTree TreeRoot
;
TreeRoot
= &(MacroRoot
->Tree
);
MacroRoot
= NULL
;
DestroyTree
(&TreeRoot
, ClearMacroList_ClearNode
, NULL
);
}
static void ResetMacroDefines_ResetNode
(PTree Tree
, void *pData
)
{
PMacroNode Node
= (PMacroNode
)Tree
;
UNUSED
(pData
);
Node
->Defined
= False
;
}
void ResetMacroDefines
(void)
{
IterTree
((PTree
)MacroRoot
, ResetMacroDefines_ResetNode
, NULL
);
}
void ClearMacroRec
(PMacroRec
*Alt
, Boolean Complete
)
{
if ((*Alt
)->Name
)
{
free((*Alt
)->Name
);
(*Alt
)->Name
= NULL
;
}
ClearStringList
(&((*Alt
)->FirstLine
));
ClearStringList
(&((*Alt
)->ParamNames
));
ClearStringList
(&((*Alt
)->ParamDefVals
));
if (Complete
)
{
free(*Alt
);
*Alt
= NULL
;
}
}
typedef struct
{
LongInt Sum
;
Boolean cnt
;
String OneS
;
} TMacroListContext
;
static void PrintMacroList_PNode
(PTree Tree
, void *pData
)
{
PMacroNode Node
= (PMacroNode
)Tree
;
TMacroListContext
*pContext
= (TMacroListContext
*) pData
;
String h
;
strmaxcpy
(h
, Node
->Contents
->Name
, STRINGSIZE
);
if (Node
->Tree.
Attribute != -1)
{
strmaxcat
(h
, "[", STRINGSIZE
);
strmaxcat
(h
, GetSectionName
(Node
->Tree.
Attribute), STRINGSIZE
);
strmaxcat
(h
, "]", STRINGSIZE
);
}
if (Node
->Contents
->LstMacroExpMod.
Count)
{
strmaxcat
(h
, "{", STRINGSIZE
);
DumpLstMacroExpMod
(&Node
->Contents
->LstMacroExpMod
, h
+ strlen(h
), sizeof(h
) - strlen(h
));
strmaxcat
(h
, "}", STRINGSIZE
);
}
strmaxcat
(pContext
->OneS
, h
, STRINGSIZE
);
if (strlen(h
) < 37)
strmaxcat
(pContext
->OneS
, Blanks
(37 - strlen(h
)), STRINGSIZE
);
if (!(pContext
->cnt
))
strmaxcat
(pContext
->OneS
, " | ", STRINGSIZE
);
else
{
WrLstLine
(pContext
->OneS
);
pContext
->OneS
[0] = '\0';
}
pContext
->cnt
= !pContext
->cnt
;
pContext
->Sum
++;
}
void PrintMacroList
(void)
{
TMacroListContext Context
;
if (!MacroRoot
)
return;
NewPage
(ChapDepth
, True
);
WrLstLine
(getmessage
(Num_ListMacListHead1
));
WrLstLine
(getmessage
(Num_ListMacListHead2
));
WrLstLine
("");
Context.
OneS[0] = '\0';
Context.
cnt = False
;
Context.
Sum = 0;
IterTree
((PTree
)MacroRoot
, PrintMacroList_PNode
, &Context
);
if (Context.
cnt)
{
Context.
OneS[strlen(Context.
OneS) - 1] = '\0';
WrLstLine
(Context.
OneS);
}
WrLstLine
("");
as_snprintf
(Context.
OneS, sizeof(Context.
OneS), "%7lu%s",
(unsigned long)Context.
Sum,
getmessage
((Context.
Sum == 1) ? Num_ListMacSumMsg
: Num_ListMacSumsMsg
));
WrLstLine
(Context.
OneS);
WrLstLine
("");
}
/*=== Eingabefilter Makroprozessor ========================================*/
void asmmac_init
(void)
{
MacroRoot
= NULL
;
}