[patch] separate system defines from user defines

Bernhard Fischer <[email protected]> Sat, 12 May 2007 22:28:05 +0200
Newsgroups gmane.comp.documentation.synopsis
Message-ID <[email protected]>
Hi,

consider:

$ cat no.c 
#undef nonono
#define nonono 1

Current trunk rejects this with:
$ synopsis -p C -o /dev/null -Dnonono no.c
/tmp/i/no.c(1): warning: #undef may not be used on this predefined name: nonono
Error: CppError: /tmp/i/no.c:1 : warning: #undef may not be used on this predefined name: nonono

The problem arises since currently all flags are treated as
"predefined", from wave's perspective, and predefined macros per default
are not to be undefined unless explicitely requested --
remove_macro_definition(token,bool even_predefined=false).

The attached patch introduces a separation between defines that come
from the emulator and the user. The former are added with
is_predefined=true, whereas flags given by the user are not¹.

Stefan, ok to apply?

¹) our no.c example now yields:
XXX: add_macro_definition.ctx (predefined)unix=1
XXX: add_macro_definition.ctx (predefined)__ELF__=1
XXX: add_macro_definition.ctx (user)nono

2007-05-12  Bernhard Fischer  <..>

        * Parsers/Cpp/ParserImpl.cc (parse): Rename flags to system_flags, add
	user_flags. Insert system macros as predefined, explicitely state
        that removing system macros shall not remove predefined ones.  Insert
        user macros as not-predefined.
        * Parsers/Cpp/__init__.py (class Parser): Separate system_flags from
        user flags, adjust call.

_______________________________________________
Synopsis-devel mailing list
[email protected]
http://lists.fresco.org/cgi-bin/listinfo/synopsis-devel
synopsis-trunk.cow-20070512-2216.separate-user-defines.01.diff (text/x-diff, 5.3 KB)
2007-05-12  Bernhard Fischer  <..>

	* Parsers/Cpp/ParserImpl.cc (parse): Rename flags to system_flags, add 
	user_flags. Insert system macros as predefined, explicitely state
	that removing system macros shall not remove predefined ones. Insert
	user macros as not-predefined.
	* Parsers/Cpp/__init__.py (class Parser): Separate system_flags from
	user flags, adjust call.

Index: synopsis-trunk/Synopsis/Parsers/Cpp/ParserImpl.cc
===================================================================
--- synopsis-trunk/Synopsis/Parsers/Cpp/ParserImpl.cc	(revision 1822)
+++ synopsis-trunk/Synopsis/Parsers/Cpp/ParserImpl.cc	(working copy)
@@ -53,25 +53,28 @@ PyObject *parse(PyObject *self, PyObject
   char const *base_path;
   char const *output_file;
   char const *language;
-  PyObject *py_flags;
-  std::vector<char const *> flags;
+  PyObject *py_system_flags, *py_user_flags;
+  std::vector<char const *> system_flags;
+  std::vector<char const *> user_flags;
   PyObject *py_ast;
   int main_file_only = 0;
   int verbose = 0;
   int debug = 0;
   int profile = 0;
-  if (!PyArg_ParseTuple(args, "OszzsO!iiii",
+  if (!PyArg_ParseTuple(args, "OszzsO!O!iiii",
 			&py_ast,
 			&input_file,
 			&base_path,
 			&output_file,
 			&language,
-			&PyList_Type, &py_flags,
+			&PyList_Type, &py_system_flags,
+			&PyList_Type, &py_user_flags,
 			&main_file_only,
 			&verbose,
 			&debug,
 			&profile)
-      || !extract(py_flags, flags))
+      || !extract(py_system_flags, system_flags)
+      || !extract(py_user_flags, user_flags))
     return 0;
 
   Py_INCREF(error);
@@ -122,9 +125,14 @@ PyObject *parse(PyObject *self, PyObject
     {
       ctx.set_language(wave::support_c99);
       // Remove the '__STDC_HOSTED__' macro as wave predefines it.
-      flags.erase(std::remove(flags.begin(), flags.end(),
+      system_flags.erase(std::remove(system_flags.begin(), system_flags.end(),
 			      std::string("-D__STDC_HOSTED__=1")),
-		  flags.end());
+		  system_flags.end());
+
+      // Remove the '__STDC__' macro as wave predefines it.
+      system_flags.erase(std::remove(system_flags.begin(), system_flags.end(),
+			      std::string("-D__STDC__=1")),
+		  system_flags.end());
     }
     else
     {
@@ -132,15 +140,16 @@ PyObject *parse(PyObject *self, PyObject
       // FIXME: should only enable in GCC compat mode.
       ctx.set_language(wave::enable_long_long(ctx.get_language()));
       // Remove the '__cplusplus' macro as wave predefines it.
-      flags.erase(std::remove(flags.begin(), flags.end(),
+      system_flags.erase(std::remove(system_flags.begin(), system_flags.end(),
 			      std::string("-D__cplusplus=1")),
-		  flags.end());
+		  system_flags.end());
     }
     ctx.set_language(wave::enable_preserve_comments(ctx.get_language()));
 
     std::vector<std::string> includes;
-    for (std::vector<char const *>::iterator i = flags.begin();
-	 i != flags.end();
+    // Insert the system_flags from the Emulator
+    for (std::vector<char const *>::iterator i = system_flags.begin();
+	 i != system_flags.end();
 	 ++i)
     {
       if (**i == '-')
@@ -151,9 +160,30 @@ PyObject *parse(PyObject *self, PyObject
 	  ctx.add_sysinclude_path(*i + 2);
 	}
 	else if (*(*i + 1) == 'D')
-	  ctx.add_macro_definition(*i + 2, true);
+	  ctx.add_macro_definition(*i + 2, /*is_predefined=*/true);
 	else if (*(*i + 1) == 'U')
-	  ctx.remove_macro_definition(*i + 2);
+	  ctx.remove_macro_definition(*i + 2, /*even_predefined=*/false);
+	else if (*(*i + 1) == 'i')
+	  includes.push_back(*i + 2);
+      }
+    }
+
+    // Insert the user_flags
+    for (std::vector<char const *>::iterator i = user_flags.begin();
+	 i != user_flags.end();
+	 ++i)
+    {
+      if (**i == '-')
+      {
+	if (*(*i + 1) == 'I')
+	{
+	  ctx.add_include_path(*i + 2);
+	  ctx.add_sysinclude_path(*i + 2);
+	}
+	else if (*(*i + 1) == 'D')
+	  ctx.add_macro_definition(*i + 2, /*is_predefined=*/false);
+	else if (*(*i + 1) == 'U')
+	  ctx.remove_macro_definition(*i + 2, /*even_predefined=*/false);
 	else if (*(*i + 1) == 'i')
 	  includes.push_back(*i + 2);
       }
Index: synopsis-trunk/Synopsis/Parsers/Cpp/__init__.py
===================================================================
--- synopsis-trunk/Synopsis/Parsers/Cpp/__init__.py	(revision 1822)
+++ synopsis-trunk/Synopsis/Parsers/Cpp/__init__.py	(working copy)
@@ -31,13 +31,14 @@ class Parser(Processor):
         base_path = self.base_path and os.path.abspath(self.base_path) + os.sep or ''
         if self.emulate_compiler is not None:
             info = get_compiler_info(self.language, self.emulate_compiler)
-            flags += ['-I%s'%x for x in info.include_paths]
-            flags += ['-D%s'%k + (v and '=%s'%v or '') for (k,v) in info.macros]
+            system_flags = ['-I%s'%x for x in info.include_paths]
+            system_flags += ['-D%s'%k + (v and '=%s'%v or '') for (k,v) in info.macros]
         for file in self.input:
             self.ast = parse(self.ast,
                              os.path.abspath(file),
                              base_path,
                              self.cpp_output,
-                             self.language, flags, self.primary_file_only,
+                             self.language, system_flags, flags,
+                             self.primary_file_only,
                              self.verbose, self.debug, self.profile)
         return self.output_and_return_ast()