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
|
-V Print the compiler version number
|
||||||
-W [-+]warning[,...] Control warnings ('-' disables, '+' enables)
|
-W [-+]warning[,...] Control warnings ('-' disables, '+' enables)
|
||||||
-d Debug mode
|
-d Debug mode
|
||||||
|
-dM Output all user macros (needs -E)
|
||||||
|
-dP Output all predefined macros (needs -E)
|
||||||
-g Add debug info to object file
|
-g Add debug info to object file
|
||||||
-h Help (this text)
|
-h Help (this text)
|
||||||
-j Default characters are signed
|
-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.
|
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>
|
<tag><tt>--debug-tables name</tt></tag>
|
||||||
|
|
||||||
Writes symbol table information to a file, which includes details on structs, unions
|
Writes symbol table information to a file, which includes details on structs, unions
|
||||||
|
|||||||
@@ -496,6 +496,14 @@ void Compile (const char* FileName)
|
|||||||
while (PreprocessNextLine ())
|
while (PreprocessNextLine ())
|
||||||
{ /* Nothing */ }
|
{ /* Nothing */ }
|
||||||
|
|
||||||
|
/* Output macros if requested by the user */
|
||||||
|
if (DumpPredefMacros) {
|
||||||
|
OutputPredefMacros ();
|
||||||
|
}
|
||||||
|
if (DumpUserMacros) {
|
||||||
|
OutputUserMacros ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Close the output file */
|
/* Close the output file */
|
||||||
CloseOutputFile ();
|
CloseOutputFile ();
|
||||||
|
|
||||||
|
|||||||
@@ -44,12 +44,14 @@
|
|||||||
|
|
||||||
|
|
||||||
unsigned char AddSource = 0; /* Add source lines as comments */
|
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 AutoCDecl = 0; /* Make functions default to __cdecl__ */
|
||||||
unsigned char DebugInfo = 0; /* Add debug info to the obj */
|
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 PreprocessOnly = 0; /* Just preprocess the input */
|
||||||
unsigned char DebugOptOutput = 0; /* Output debug stuff */
|
unsigned char DebugOptOutput = 0; /* Output debug stuff */
|
||||||
unsigned RegisterSpace = 6; /* Space available for register vars */
|
unsigned RegisterSpace = 6; /* Space available for register vars */
|
||||||
unsigned AllowNewComments = 0; /* Allow new style comments in C89 mode */
|
|
||||||
|
|
||||||
/* Stackable options */
|
/* Stackable options */
|
||||||
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
|
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
|
||||||
|
|||||||
@@ -52,12 +52,14 @@
|
|||||||
|
|
||||||
/* Options */
|
/* Options */
|
||||||
extern unsigned char AddSource; /* Add source lines as comments */
|
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 AutoCDecl; /* Make functions default to __cdecl__ */
|
||||||
extern unsigned char DebugInfo; /* Add debug info to the obj */
|
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 PreprocessOnly; /* Just preprocess the input */
|
||||||
extern unsigned char DebugOptOutput; /* Output debug stuff */
|
extern unsigned char DebugOptOutput; /* Output debug stuff */
|
||||||
extern unsigned RegisterSpace; /* Space available for register vars */
|
extern unsigned RegisterSpace; /* Space available for register vars */
|
||||||
extern unsigned AllowNewComments; /* Allow new style comments in C89 mode */
|
|
||||||
|
|
||||||
/* Stackable options */
|
/* Stackable options */
|
||||||
extern IntStack WritableStrings; /* Literal strings are r/w */
|
extern IntStack WritableStrings; /* Literal strings are r/w */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*****************************************************************************/
|
|
||||||
/* */
|
/* */
|
||||||
/* macrotab.h */
|
/* macrotab.h */
|
||||||
/* */
|
/* */
|
||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "output.h"
|
||||||
#include "preproc.h"
|
#include "preproc.h"
|
||||||
#include "macrotab.h"
|
#include "macrotab.h"
|
||||||
|
|
||||||
@@ -60,6 +61,70 @@ static Macro* MacroTab[MACRO_TAB_SIZE];
|
|||||||
/* The undefined macros list head */
|
/* The undefined macros list head */
|
||||||
static Macro* UndefinedMacrosListHead;
|
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
|
/* Allocate a macro structure with the given name. The structure is not
|
||||||
** inserted into the macro table.
|
** inserted into the macro table.
|
||||||
*/
|
*/
|
||||||
@@ -84,6 +149,7 @@ Macro* NewMacro (const char* Name)
|
|||||||
M->ParamCount = -1; /* Flag: Not a function-like macro */
|
M->ParamCount = -1; /* Flag: Not a function-like macro */
|
||||||
InitCollection (&M->Params);
|
InitCollection (&M->Params);
|
||||||
SB_Init (&M->Replacement);
|
SB_Init (&M->Replacement);
|
||||||
|
M->Predefined = Predefined;
|
||||||
M->Variadic = 0;
|
M->Variadic = 0;
|
||||||
memcpy (M->Name, Name, Len+1);
|
memcpy (M->Name, Name, Len+1);
|
||||||
|
|
||||||
@@ -116,7 +182,7 @@ Macro* CloneMacro (const Macro* M)
|
|||||||
** Use FreeMacro for that.
|
** Use FreeMacro for that.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Macro* New = NewMacro (M->Name);
|
Macro* New = NewMacro (M->Name, M->Predefined);
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
for (I = 0; I < CollCount (&M->Params); ++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)
|
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];
|
char Buf[64];
|
||||||
|
|
||||||
@@ -148,10 +214,10 @@ void DefineNumericMacro (const char* Name, long Val)
|
|||||||
|
|
||||||
|
|
||||||
void DefineTextMacro (const char* Name, const char* 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 */
|
/* Create a new macro */
|
||||||
Macro* M = NewMacro (Name);
|
Macro* M = NewMacro (Name, 1);
|
||||||
|
|
||||||
/* Set the value as replacement text */
|
/* Set the value as replacement text */
|
||||||
SB_CopyStr (&M->Replacement, Val);
|
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 */
|
int ParamCount; /* Number of parameters, -1 = no parens */
|
||||||
Collection Params; /* Parameter list (char*) */
|
Collection Params; /* Parameter list (char*) */
|
||||||
StrBuf Replacement; /* Replacement text */
|
StrBuf Replacement; /* Replacement text */
|
||||||
|
unsigned char Predefined; /* True if this is a predefined macro */
|
||||||
unsigned char Variadic; /* C99 variadic macro */
|
unsigned char Variadic; /* C99 variadic macro */
|
||||||
char Name[1]; /* Name, dynamically allocated */
|
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
|
/* Allocate a macro structure with the given name. The structure is not
|
||||||
** inserted into the macro table.
|
** inserted into the macro table.
|
||||||
*/
|
*/
|
||||||
@@ -87,10 +88,10 @@ Macro* CloneMacro (const Macro* M);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void DefineNumericMacro (const char* Name, long Val);
|
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);
|
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);
|
void InsertMacro (Macro* M);
|
||||||
/* Insert the given macro into the macro table. */
|
/* Insert the given macro into the macro table. */
|
||||||
@@ -132,6 +133,12 @@ int MacroCmp (const Macro* M1, const Macro* M2);
|
|||||||
void PrintMacroStats (FILE* F);
|
void PrintMacroStats (FILE* F);
|
||||||
/* Print macro statistics to the given text file. */
|
/* 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 */
|
/* End of macrotab.h */
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ static void Usage (void)
|
|||||||
" -V\t\t\t\tPrint the compiler version number\n"
|
" -V\t\t\t\tPrint the compiler version number\n"
|
||||||
" -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n"
|
" -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n"
|
||||||
" -d\t\t\t\tDebug mode\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"
|
" -g\t\t\t\tAdd debug info to object file\n"
|
||||||
" -h\t\t\t\tHelp (this text)\n"
|
" -h\t\t\t\tHelp (this text)\n"
|
||||||
" -j\t\t\t\tDefault characters are signed\n"
|
" -j\t\t\t\tDefault characters are signed\n"
|
||||||
@@ -1026,7 +1028,25 @@ int main (int argc, char* argv[])
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
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;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
@@ -1138,6 +1158,11 @@ int main (int argc, char* argv[])
|
|||||||
AbEnd ("No input files");
|
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. */
|
/* Add the default include search paths. */
|
||||||
FinishIncludePaths ();
|
FinishIncludePaths ();
|
||||||
|
|
||||||
|
|||||||
@@ -2575,7 +2575,7 @@ static void DoDefine (void)
|
|||||||
CheckForBadIdent (Ident, Std, 0);
|
CheckForBadIdent (Ident, Std, 0);
|
||||||
|
|
||||||
/* Create a new macro definition */
|
/* Create a new macro definition */
|
||||||
M = NewMacro (Ident);
|
M = NewMacro (Ident, 0);
|
||||||
|
|
||||||
/* Check if this is a function-like macro */
|
/* Check if this is a function-like macro */
|
||||||
if (CurC == '(') {
|
if (CurC == '(') {
|
||||||
|
|||||||
Reference in New Issue
Block a user