diff mbox series

[7/9] pre-process: add the -dM option to dump macro definitions

Message ID 2ee1506a-5e42-5736-5577-230e5f365fb5@ramsayjones.plus.com (mailing list archive)
State Mainlined, archived
Headers show
Series misc sparse patches | expand

Commit Message

Ramsay Jones Nov. 19, 2018, 8:52 p.m. UTC
The current -dD option outputs the macro definitions, in addition to the
pre-processed text. In contrast, the -dM option outputs only the macro
definitions.

Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
---
 lib.c                                      | 41 +++++++++++++++++-----
 lib.h                                      |  1 +
 validation/preprocessor/dump-macros-only.c | 36 +++++++++++++++++++
 validation/preprocessor/dump-macros.c      |  6 ++++
 4 files changed, 75 insertions(+), 9 deletions(-)
 create mode 100644 validation/preprocessor/dump-macros-only.c

Comments

Luc Van Oostenryck Nov. 20, 2018, 12:18 a.m. UTC | #1
On Mon, Nov 19, 2018 at 08:52:42PM +0000, Ramsay Jones wrote:
> 
> The current -dD option outputs the macro definitions, in addition to the
> pre-processed text. In contrast, the -dM option outputs only the macro
> definitions.
> 
> Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
> ---
>  lib.c                                      | 41 +++++++++++++++++-----
>  lib.h                                      |  1 +
>  validation/preprocessor/dump-macros-only.c | 36 +++++++++++++++++++
>  validation/preprocessor/dump-macros.c      |  6 ++++
>  4 files changed, 75 insertions(+), 9 deletions(-)
>  create mode 100644 validation/preprocessor/dump-macros-only.c
> 
> diff --git a/lib.c b/lib.c
> index 07a5b9c..23c3d27 100644
> --- a/lib.c
> +++ b/lib.c
> @@ -287,6 +287,7 @@ int Wunknown_attribute = 0;
>  int Wvla = 1;
>  
>  int dump_macro_defs = 0;
> +int dump_macros_only = 0;
>  
>  int dbg_compound = 0;
>  int dbg_dead = 0;
> @@ -794,16 +795,34 @@ static char **handle_switch_v(char *arg, char **next)
>  	return next;
>  }
>  
> -static struct flag dumps[] = {
> -	{ "D", &dump_macro_defs},
> -};
> -
>  static char **handle_switch_d(char *arg, char **next)
>  {
> -	char ** ret = handle_onoff_switch(arg, next, dumps, ARRAY_SIZE(dumps));
> -	if (ret)
> -		return ret;
> +	char *arg_char = arg + 1;
>  
> +	/*
> +	 * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded
> +	 * by a space. If you specify characters whose behaviour conflicts,
> +	 * the result is undefined.
> +	 */
> +	while (*arg_char) {
> +		switch (*arg_char) {
> +		case 'M': /* dump just the macro definitions */
> +			dump_macros_only = 1;
> +			dump_macro_defs = 0;

I prefer a small change in the logic to have dump_macro_defs set
here too.

> +			break;
> +		case 'D': /* like 'M', but also output pre-processed text */
> +			dump_macro_defs = 1;
> +			dump_macros_only = 0;
> +			break;


> +		case 'N': /* like 'D', but only output macro names not bodies */
> +			break;
> +		case 'I': /* like 'D', but also output #include directives */
> +			break;
> +		case 'U': /* like 'D', but only output expanded macros */
> +			break;

Do you have a specific reason to add those three too?
Now if someone use 'gcc -d[NIU] ...' will silently succeed, right?
Just asking, since I'm not sure yet if it is a good thing or not.

Kind regards,
-- Luc
Ramsay Jones Nov. 20, 2018, 12:49 a.m. UTC | #2
On 20/11/2018 00:18, Luc Van Oostenryck wrote:
> On Mon, Nov 19, 2018 at 08:52:42PM +0000, Ramsay Jones wrote:
>>
>> The current -dD option outputs the macro definitions, in addition to the
>> pre-processed text. In contrast, the -dM option outputs only the macro
>> definitions.
>>
>> Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
>> ---
>>  lib.c                                      | 41 +++++++++++++++++-----
>>  lib.h                                      |  1 +
>>  validation/preprocessor/dump-macros-only.c | 36 +++++++++++++++++++
>>  validation/preprocessor/dump-macros.c      |  6 ++++
>>  4 files changed, 75 insertions(+), 9 deletions(-)
>>  create mode 100644 validation/preprocessor/dump-macros-only.c
>>
>> diff --git a/lib.c b/lib.c
>> index 07a5b9c..23c3d27 100644
>> --- a/lib.c
>> +++ b/lib.c
>> @@ -287,6 +287,7 @@ int Wunknown_attribute = 0;
>>  int Wvla = 1;
>>  
>>  int dump_macro_defs = 0;
>> +int dump_macros_only = 0;
>>  
>>  int dbg_compound = 0;
>>  int dbg_dead = 0;
>> @@ -794,16 +795,34 @@ static char **handle_switch_v(char *arg, char **next)
>>  	return next;
>>  }
>>  
>> -static struct flag dumps[] = {
>> -	{ "D", &dump_macro_defs},
>> -};
>> -
>>  static char **handle_switch_d(char *arg, char **next)
>>  {
>> -	char ** ret = handle_onoff_switch(arg, next, dumps, ARRAY_SIZE(dumps));
>> -	if (ret)
>> -		return ret;
>> +	char *arg_char = arg + 1;
>>  
>> +	/*
>> +	 * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded
>> +	 * by a space. If you specify characters whose behaviour conflicts,
>> +	 * the result is undefined.
>> +	 */
>> +	while (*arg_char) {
>> +		switch (*arg_char) {
>> +		case 'M': /* dump just the macro definitions */
>> +			dump_macros_only = 1;
>> +			dump_macro_defs = 0;
> 
> I prefer a small change in the logic to have dump_macro_defs set
> here too.

Hmm, I don't quite follow.

> 
>> +			break;
>> +		case 'D': /* like 'M', but also output pre-processed text */
>> +			dump_macro_defs = 1;
>> +			dump_macros_only = 0;
>> +			break;
> 
> 
>> +		case 'N': /* like 'D', but only output macro names not bodies */
>> +			break;
>> +		case 'I': /* like 'D', but also output #include directives */
>> +			break;
>> +		case 'U': /* like 'D', but only output expanded macros */
>> +			break;
> 
> Do you have a specific reason to add those three too?
> Now if someone use 'gcc -d[NIU] ...' will silently succeed, right?

Heh, yeah, I was going to see how much effort it would take to
implement all of the options that gcc provides, so I put these
here as a reminder/place-holder ... but didn't get back to it! :-D

> Just asking, since I'm not sure yet if it is a good thing or not.

Yep, they should probably error out.

ATB,
Ramsay Jones
Luc Van Oostenryck Nov. 22, 2018, 2:58 a.m. UTC | #3
On Tue, Nov 20, 2018 at 12:49:36AM +0000, Ramsay Jones wrote:
> 
> 
> On 20/11/2018 00:18, Luc Van Oostenryck wrote:
> > On Mon, Nov 19, 2018 at 08:52:42PM +0000, Ramsay Jones wrote:
> >>
> >> The current -dD option outputs the macro definitions, in addition to the
> >> pre-processed text. In contrast, the -dM option outputs only the macro
> >> definitions.
> >>
> >> Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
> >> ---
> >>  lib.c                                      | 41 +++++++++++++++++-----
> >>  lib.h                                      |  1 +
> >>  validation/preprocessor/dump-macros-only.c | 36 +++++++++++++++++++
> >>  validation/preprocessor/dump-macros.c      |  6 ++++
> >>  4 files changed, 75 insertions(+), 9 deletions(-)
> >>  create mode 100644 validation/preprocessor/dump-macros-only.c
> >>
> >> diff --git a/lib.c b/lib.c
> >> index 07a5b9c..23c3d27 100644
> >> --- a/lib.c
> >> +++ b/lib.c
> >> @@ -287,6 +287,7 @@ int Wunknown_attribute = 0;
> >>  int Wvla = 1;
> >>  
> >>  int dump_macro_defs = 0;
> >> +int dump_macros_only = 0;
> >>  
> >>  int dbg_compound = 0;
> >>  int dbg_dead = 0;
> >> @@ -794,16 +795,34 @@ static char **handle_switch_v(char *arg, char **next)
> >>  	return next;
> >>  }
> >>  
> >> -static struct flag dumps[] = {
> >> -	{ "D", &dump_macro_defs},
> >> -};
> >> -
> >>  static char **handle_switch_d(char *arg, char **next)
> >>  {
> >> -	char ** ret = handle_onoff_switch(arg, next, dumps, ARRAY_SIZE(dumps));
> >> -	if (ret)
> >> -		return ret;
> >> +	char *arg_char = arg + 1;
> >>  
> >> +	/*
> >> +	 * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded
> >> +	 * by a space. If you specify characters whose behaviour conflicts,
> >> +	 * the result is undefined.
> >> +	 */
> >> +	while (*arg_char) {
> >> +		switch (*arg_char) {
> >> +		case 'M': /* dump just the macro definitions */
> >> +			dump_macros_only = 1;
> >> +			dump_macro_defs = 0;
> > 
> > I prefer a small change in the logic to have dump_macro_defs set
> > here too.
> 
> Hmm, I don't quite follow.

Sorry, I didn't saw this mail yesterday.

I just meant that I would prefer to let dump_macro_defs set to 1 here
and then later the test can just be:
	if (dump_macro_defs) {
		...
	}

> > 
> >> +			break;
> >> +		case 'D': /* like 'M', but also output pre-processed text */
> >> +			dump_macro_defs = 1;
> >> +			dump_macros_only = 0;
> >> +			break;
> > 
> > 
> >> +		case 'N': /* like 'D', but only output macro names not bodies */
> >> +			break;
> >> +		case 'I': /* like 'D', but also output #include directives */
> >> +			break;
> >> +		case 'U': /* like 'D', but only output expanded macros */
> >> +			break;
> > 
> > Do you have a specific reason to add those three too?
> > Now if someone use 'gcc -d[NIU] ...' will silently succeed, right?
> 
> Heh, yeah, I was going to see how much effort it would take to
> implement all of the options that gcc provides, so I put these
> here as a reminder/place-holder ... but didn't get back to it! :-D

Yes :) -dN should be easy to add but -dI and -dU would need much
more work.
 
Best regards,
-- Luc
diff mbox series

Patch

diff --git a/lib.c b/lib.c
index 07a5b9c..23c3d27 100644
--- a/lib.c
+++ b/lib.c
@@ -287,6 +287,7 @@  int Wunknown_attribute = 0;
 int Wvla = 1;
 
 int dump_macro_defs = 0;
+int dump_macros_only = 0;
 
 int dbg_compound = 0;
 int dbg_dead = 0;
@@ -794,16 +795,34 @@  static char **handle_switch_v(char *arg, char **next)
 	return next;
 }
 
-static struct flag dumps[] = {
-	{ "D", &dump_macro_defs},
-};
-
 static char **handle_switch_d(char *arg, char **next)
 {
-	char ** ret = handle_onoff_switch(arg, next, dumps, ARRAY_SIZE(dumps));
-	if (ret)
-		return ret;
+	char *arg_char = arg + 1;
 
+	/*
+	 * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded
+	 * by a space. If you specify characters whose behaviour conflicts,
+	 * the result is undefined.
+	 */
+	while (*arg_char) {
+		switch (*arg_char) {
+		case 'M': /* dump just the macro definitions */
+			dump_macros_only = 1;
+			dump_macro_defs = 0;
+			break;
+		case 'D': /* like 'M', but also output pre-processed text */
+			dump_macro_defs = 1;
+			dump_macros_only = 0;
+			break;
+		case 'N': /* like 'D', but only output macro names not bodies */
+			break;
+		case 'I': /* like 'D', but also output #include directives */
+			break;
+		case 'U': /* like 'D', but only output expanded macros */
+			break;
+		}
+		arg_char++;
+	}
 	return next;
 }
 
@@ -1311,8 +1330,12 @@  static struct symbol_list *sparse_tokenstream(struct token *token)
 	// Preprocess the stream
 	token = preprocess(token);
 
-	if (dump_macro_defs && !builtin)
-		dump_macro_definitions();
+	if (dump_macro_defs || dump_macros_only) {
+		if (!builtin)
+			dump_macro_definitions();
+		if (dump_macros_only)
+			return NULL;
+	}
 
 	if (preprocess_only) {
 		while (!eof_token(token)) {
diff --git a/lib.h b/lib.h
index cd1af9c..ae0e981 100644
--- a/lib.h
+++ b/lib.h
@@ -177,6 +177,7 @@  extern int Wunknown_attribute;
 extern int Wvla;
 
 extern int dump_macro_defs;
+extern int dump_macros_only;
 
 extern int dbg_compound;
 extern int dbg_dead;
diff --git a/validation/preprocessor/dump-macros-only.c b/validation/preprocessor/dump-macros-only.c
new file mode 100644
index 0000000..cee6f87
--- /dev/null
+++ b/validation/preprocessor/dump-macros-only.c
@@ -0,0 +1,36 @@ 
+
+#define ABC abc
+#undef ABC
+
+#define	DEF def
+#undef DEF
+#define DEF xyz
+
+#define NYDEF ydef
+
+#define STRING(x) #x
+#define CONCAT(x,y) x ## y
+
+#define unlocks(...) annotate(unlock_func(__VA_ARGS__))
+#define apply(x,...) x(__VA_ARGS__)
+
+int main(int argc, char *argv[])
+{
+	return 0;
+}
+/*
+ * check-name: dump-macros only -dM
+ * check-command: sparse -E -dM -DIJK=ijk -UNDEF -UNYDEF $file
+ *
+ * check-output-ignore
+check-output-pattern(1): #define __CHECKER__ 1
+check-output-contains: #define IJK ijk
+check-output-contains: #define DEF xyz
+check-output-contains: #define NYDEF ydef
+check-output-contains: #define STRING(x) #x
+check-output-contains: #define CONCAT(x,y) x ## y
+check-output-contains: #define unlocks(...) annotate(unlock_func(__VA_ARGS__))
+check-output-contains: #define apply(x,...) x(__VA_ARGS__)
+check-output-excludes: int main(int argc, char \\*argv\\[\\])
+check-output-excludes: ^\\[^#]
+ */
diff --git a/validation/preprocessor/dump-macros.c b/validation/preprocessor/dump-macros.c
index 6940a20..dc2d7d1 100644
--- a/validation/preprocessor/dump-macros.c
+++ b/validation/preprocessor/dump-macros.c
@@ -12,6 +12,11 @@ 
 
 #define unlocks(...) annotate(unlock_func(__VA_ARGS__))
 #define apply(x,...) x(__VA_ARGS__)
+
+int main(int argc, char *argv[])
+{
+	return 0;
+}
 /*
  * check-name: dump-macros
  * check-command: sparse -E -dD -DIJK=ijk -UNDEF -UNYDEF $file
@@ -25,4 +30,5 @@  check-output-contains: #define STRING(x) #x
 check-output-contains: #define CONCAT(x,y) x ## y
 check-output-contains: #define unlocks(...) annotate(unlock_func(__VA_ARGS__))
 check-output-contains: #define apply(x,...) x(__VA_ARGS__)
+check-output-contains: int main(int argc, char \\*argv\\[\\])
  */