Merge pull request #2698 from kugelfuhr/kugelfuhr/fix-1640
Implement -dD, -dM and -dN command line switches to output macro definitions
This commit is contained in:
@@ -63,6 +63,8 @@ Short options:
|
||||
-V Print the compiler version number
|
||||
-W [-+]warning[,...] Control warnings ('-' disables, '+' enables)
|
||||
-d Debug mode
|
||||
-dM Output all user macros (needs -E)
|
||||
-dP Output all predefined macros (needs -E)
|
||||
-g Add debug info to object file
|
||||
-h Help (this text)
|
||||
-j Default characters are signed
|
||||
@@ -199,6 +201,28 @@ Here is a description of all the command line options:
|
||||
Enables debug mode, for debugging the behavior of cc65.
|
||||
|
||||
|
||||
|
||||
<label id="option-dM">
|
||||
<tag><tt>-dM</tt></tag>
|
||||
|
||||
When used with -E, will output <tt>#define</tt> directives for all the user
|
||||
macros defined during execution of the preprocessor. This does not include
|
||||
macros defined by the compiler.
|
||||
|
||||
Note: Can be combined with <tt/<ref id="option-dP" name="-dP">/ by using
|
||||
<tt/-dMP/.
|
||||
|
||||
|
||||
<label id="option-dP">
|
||||
<tag><tt>-dP</tt></tag>
|
||||
|
||||
When used with -E, will output <tt>#define</tt> directives for all the macros
|
||||
defined by the compiler itself. This does not include any user defined macros.
|
||||
|
||||
Note: Can be combined with <tt/<ref id="option-dM" name="-dM">/ by using
|
||||
<tt/-dMP/.
|
||||
|
||||
|
||||
<tag><tt>--debug-tables name</tt></tag>
|
||||
|
||||
Writes symbol table information to a file, which includes details on structs, unions
|
||||
|
||||
@@ -496,6 +496,14 @@ void Compile (const char* FileName)
|
||||
while (PreprocessNextLine ())
|
||||
{ /* Nothing */ }
|
||||
|
||||
/* Output macros if requested by the user */
|
||||
if (DumpPredefMacros) {
|
||||
OutputPredefMacros ();
|
||||
}
|
||||
if (DumpUserMacros) {
|
||||
OutputUserMacros ();
|
||||
}
|
||||
|
||||
/* Close the output file */
|
||||
CloseOutputFile ();
|
||||
|
||||
|
||||
@@ -44,12 +44,14 @@
|
||||
|
||||
|
||||
unsigned char AddSource = 0; /* Add source lines as comments */
|
||||
unsigned char AllowNewComments = 0; /* Allow new style comments in C89 mode */
|
||||
unsigned char AutoCDecl = 0; /* Make functions default to __cdecl__ */
|
||||
unsigned char DebugInfo = 0; /* Add debug info to the obj */
|
||||
unsigned char DumpPredefMacros = 0; /* Output predefined macros */
|
||||
unsigned char DumpUserMacros = 0; /* Output user macros */
|
||||
unsigned char PreprocessOnly = 0; /* Just preprocess the input */
|
||||
unsigned char DebugOptOutput = 0; /* Output debug stuff */
|
||||
unsigned RegisterSpace = 6; /* Space available for register vars */
|
||||
unsigned AllowNewComments = 0; /* Allow new style comments in C89 mode */
|
||||
|
||||
/* Stackable options */
|
||||
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
|
||||
|
||||
@@ -52,12 +52,14 @@
|
||||
|
||||
/* Options */
|
||||
extern unsigned char AddSource; /* Add source lines as comments */
|
||||
extern unsigned char AllowNewComments; /* Allow new style comments in C89 mode */
|
||||
extern unsigned char AutoCDecl; /* Make functions default to __cdecl__ */
|
||||
extern unsigned char DebugInfo; /* Add debug info to the obj */
|
||||
extern unsigned char DumpPredefMacros; /* Output predefined macros */
|
||||
extern unsigned char DumpUserMacros; /* Output user macros */
|
||||
extern unsigned char PreprocessOnly; /* Just preprocess the input */
|
||||
extern unsigned char DebugOptOutput; /* Output debug stuff */
|
||||
extern unsigned RegisterSpace; /* Space available for register vars */
|
||||
extern unsigned AllowNewComments; /* Allow new style comments in C89 mode */
|
||||
|
||||
/* Stackable options */
|
||||
extern IntStack WritableStrings; /* Literal strings are r/w */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
/* */
|
||||
/* macrotab.h */
|
||||
/* */
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
/* cc65 */
|
||||
#include "error.h"
|
||||
#include "output.h"
|
||||
#include "preproc.h"
|
||||
#include "macrotab.h"
|
||||
|
||||
@@ -60,6 +61,70 @@ static Macro* MacroTab[MACRO_TAB_SIZE];
|
||||
/* The undefined macros list head */
|
||||
static Macro* UndefinedMacrosListHead;
|
||||
|
||||
/* Some defines for better readability when calling OutputMacros() */
|
||||
#define USER_MACROS 0
|
||||
#define PREDEF_MACROS 1
|
||||
#define NAME_ONLY 0
|
||||
#define FULL_DEFINITION 1
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* helpers */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static void OutputMacro (const Macro* M, int Full)
|
||||
/* Output one macro. If Full is true, the replacement is also output. */
|
||||
{
|
||||
WriteOutput ("#define %s", M->Name);
|
||||
int ParamCount = M->ParamCount;
|
||||
if (M->ParamCount >= 0) {
|
||||
int I;
|
||||
if (M->Variadic) {
|
||||
CHECK (ParamCount > 0);
|
||||
--ParamCount;
|
||||
}
|
||||
WriteOutput ("(");
|
||||
for (I = 0; I < ParamCount; ++I) {
|
||||
const char* Name = CollConstAt (&M->Params, I);
|
||||
WriteOutput ("%s%s", (I == 0)? "" : ",", Name);
|
||||
}
|
||||
if (M->Variadic) {
|
||||
WriteOutput ("%s...", (ParamCount == 0)? "" : ",");
|
||||
}
|
||||
WriteOutput (")");
|
||||
}
|
||||
WriteOutput (" ");
|
||||
if (Full) {
|
||||
WriteOutput ("%.*s",
|
||||
SB_GetLen (&M->Replacement),
|
||||
SB_GetConstBuf (&M->Replacement));
|
||||
}
|
||||
WriteOutput ("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OutputMacros (int Predefined, int Full)
|
||||
/* Output macros to the output file depending on the flags given. */
|
||||
{
|
||||
/* Note: The Full flag is currently not used by any callers but is left in
|
||||
** place for possible future changes.
|
||||
*/
|
||||
unsigned I;
|
||||
for (I = 0; I < MACRO_TAB_SIZE; ++I) {
|
||||
const Macro* M = MacroTab [I];
|
||||
while (M) {
|
||||
if ((Predefined != 0) == (M->Predefined != 0)) {
|
||||
OutputMacro (M, Full);
|
||||
}
|
||||
M = M->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -68,7 +133,7 @@ static Macro* UndefinedMacrosListHead;
|
||||
|
||||
|
||||
|
||||
Macro* NewMacro (const char* Name)
|
||||
Macro* NewMacro (const char* Name, unsigned char Predefined)
|
||||
/* Allocate a macro structure with the given name. The structure is not
|
||||
** inserted into the macro table.
|
||||
*/
|
||||
@@ -84,6 +149,7 @@ Macro* NewMacro (const char* Name)
|
||||
M->ParamCount = -1; /* Flag: Not a function-like macro */
|
||||
InitCollection (&M->Params);
|
||||
SB_Init (&M->Replacement);
|
||||
M->Predefined = Predefined;
|
||||
M->Variadic = 0;
|
||||
memcpy (M->Name, Name, Len+1);
|
||||
|
||||
@@ -116,7 +182,7 @@ Macro* CloneMacro (const Macro* M)
|
||||
** Use FreeMacro for that.
|
||||
*/
|
||||
{
|
||||
Macro* New = NewMacro (M->Name);
|
||||
Macro* New = NewMacro (M->Name, M->Predefined);
|
||||
unsigned I;
|
||||
|
||||
for (I = 0; I < CollCount (&M->Params); ++I) {
|
||||
@@ -134,7 +200,7 @@ Macro* CloneMacro (const Macro* M)
|
||||
|
||||
|
||||
void DefineNumericMacro (const char* Name, long Val)
|
||||
/* Define a macro for a numeric constant */
|
||||
/* Define a predefined macro for a numeric constant */
|
||||
{
|
||||
char Buf[64];
|
||||
|
||||
@@ -148,10 +214,10 @@ void DefineNumericMacro (const char* Name, long Val)
|
||||
|
||||
|
||||
void DefineTextMacro (const char* Name, const char* Val)
|
||||
/* Define a macro for a textual constant */
|
||||
/* Define a predefined macro for a textual constant */
|
||||
{
|
||||
/* Create a new macro */
|
||||
Macro* M = NewMacro (Name);
|
||||
Macro* M = NewMacro (Name, 1);
|
||||
|
||||
/* Set the value as replacement text */
|
||||
SB_CopyStr (&M->Replacement, Val);
|
||||
@@ -350,3 +416,19 @@ void PrintMacroStats (FILE* F)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OutputPredefMacros (void)
|
||||
/* Output all predefined macros to the output file */
|
||||
{
|
||||
OutputMacros (PREDEF_MACROS, FULL_DEFINITION);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OutputUserMacros (void)
|
||||
/* Output all user defined macros to the output file */
|
||||
{
|
||||
OutputMacros (USER_MACROS, FULL_DEFINITION);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ struct Macro {
|
||||
int ParamCount; /* Number of parameters, -1 = no parens */
|
||||
Collection Params; /* Parameter list (char*) */
|
||||
StrBuf Replacement; /* Replacement text */
|
||||
unsigned char Predefined; /* True if this is a predefined macro */
|
||||
unsigned char Variadic; /* C99 variadic macro */
|
||||
char Name[1]; /* Name, dynamically allocated */
|
||||
};
|
||||
@@ -70,7 +71,7 @@ struct Macro {
|
||||
|
||||
|
||||
|
||||
Macro* NewMacro (const char* Name);
|
||||
Macro* NewMacro (const char* Name, unsigned char Predefined);
|
||||
/* Allocate a macro structure with the given name. The structure is not
|
||||
** inserted into the macro table.
|
||||
*/
|
||||
@@ -87,10 +88,10 @@ Macro* CloneMacro (const Macro* M);
|
||||
*/
|
||||
|
||||
void DefineNumericMacro (const char* Name, long Val);
|
||||
/* Define a macro for a numeric constant */
|
||||
/* Define a predefined macro for a numeric constant */
|
||||
|
||||
void DefineTextMacro (const char* Name, const char* Val);
|
||||
/* Define a macro for a textual constant */
|
||||
/* Define a predefined macro for a textual constant */
|
||||
|
||||
void InsertMacro (Macro* M);
|
||||
/* Insert the given macro into the macro table. */
|
||||
@@ -132,6 +133,12 @@ int MacroCmp (const Macro* M1, const Macro* M2);
|
||||
void PrintMacroStats (FILE* F);
|
||||
/* Print macro statistics to the given text file. */
|
||||
|
||||
void OutputPredefMacros (void);
|
||||
/* Output all predefined macros to the output file */
|
||||
|
||||
void OutputUserMacros (void);
|
||||
/* Output all user defined macros to the output file */
|
||||
|
||||
|
||||
|
||||
/* End of macrotab.h */
|
||||
|
||||
@@ -93,6 +93,8 @@ static void Usage (void)
|
||||
" -V\t\t\t\tPrint the compiler version number\n"
|
||||
" -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n"
|
||||
" -d\t\t\t\tDebug mode\n"
|
||||
" -dM\t\t\t\tOutput all user macros (needs -E)\n"
|
||||
" -dP\t\t\t\tOutput all predefined macros (needs -E)\n"
|
||||
" -g\t\t\t\tAdd debug info to object file\n"
|
||||
" -h\t\t\t\tHelp (this text)\n"
|
||||
" -j\t\t\t\tDefault characters are signed\n"
|
||||
@@ -1026,7 +1028,25 @@ int main (int argc, char* argv[])
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
OptDebug (Arg, 0);
|
||||
P = Arg + 2;
|
||||
if (*P == '\0') {
|
||||
OptDebug (Arg, 0);
|
||||
} else {
|
||||
while (*P) {
|
||||
switch (*P) {
|
||||
case 'M':
|
||||
DumpUserMacros = 1;
|
||||
break;
|
||||
case 'P':
|
||||
DumpPredefMacros = 1;
|
||||
break;
|
||||
default:
|
||||
UnknownOption (Arg);
|
||||
break;
|
||||
}
|
||||
++P;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
@@ -1138,6 +1158,11 @@ int main (int argc, char* argv[])
|
||||
AbEnd ("No input files");
|
||||
}
|
||||
|
||||
/* The options to output macros can only be used with -E */
|
||||
if ((DumpPredefMacros || DumpUserMacros) && !PreprocessOnly) {
|
||||
AbEnd ("Preprocessor macro output can only be used together with -E");
|
||||
}
|
||||
|
||||
/* Add the default include search paths. */
|
||||
FinishIncludePaths ();
|
||||
|
||||
|
||||
@@ -2575,7 +2575,7 @@ static void DoDefine (void)
|
||||
CheckForBadIdent (Ident, Std, 0);
|
||||
|
||||
/* Create a new macro definition */
|
||||
M = NewMacro (Ident);
|
||||
M = NewMacro (Ident, 0);
|
||||
|
||||
/* Check if this is a function-like macro */
|
||||
if (CurC == '(') {
|
||||
|
||||
Reference in New Issue
Block a user