Merge pull request #492 from Ket3r/fix_FIELDLIST_macro_geneartion

Fix fieldlist macro geneartion for special struct members X and a
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py
index 6ecf063..79e05e9 100755
--- a/generator/nanopb_generator.py
+++ b/generator/nanopb_generator.py
@@ -318,6 +318,9 @@
         self.checks.extend(extend.checks)
 
 class Field:
+    macro_x_param = 'X'
+    macro_a_param = 'a'
+
     def __init__(self, struct_name, desc, field_options):
         '''desc is FieldDescriptorProto'''
         self.tag = desc.number
@@ -620,7 +623,13 @@
           else:
             name = '(%s,%s,%s)' % (self.union_name, self.name, self.name)
 
-        return 'X(a, %-9s %-9s %-9s %-16s %3d)' % (self.allocation + ',', self.rules + ',', self.pbtype + ',', name + ',', self.tag)
+        return '%s(%s, %-9s %-9s %-9s %-16s %3d)' % (self.macro_x_param,
+                                                     self.macro_a_param,
+                                                     self.allocation + ',',
+                                                     self.rules + ',',
+                                                     self.pbtype + ',',
+                                                     name + ',',
+                                                     self.tag)
 
     def data_size(self, dependencies):
         '''Return estimated size of this field in the C struct.
@@ -1077,7 +1086,16 @@
 
     def fields_declaration(self, dependencies):
         '''Return X-macro declaration of all fields in this message.'''
-        result = '#define %s_FIELDLIST(X, a) \\\n' % (self.name)
+        Field.macro_x_param = 'X'
+        Field.macro_a_param = 'a'
+        while any(field.name == Field.macro_x_param for field in self.fields):
+            Field.macro_x_param += '_'
+        while any(field.name == Field.macro_a_param for field in self.fields):
+            Field.macro_a_param += '_'
+
+        result = '#define %s_FIELDLIST(%s, %s) \\\n' % (self.name,
+                                                        Field.macro_x_param,
+                                                        Field.macro_a_param)
         result += ' \\\n'.join(field.fieldlist() for field in sorted(self.fields))
         result += '\n'
 
diff --git a/tests/special_characters/funny-proto+name has.characters.proto b/tests/special_characters/funny-proto+name has.characters.proto
index 26b2cb1..f5170c8 100644
--- a/tests/special_characters/funny-proto+name has.characters.proto
+++ b/tests/special_characters/funny-proto+name has.characters.proto
@@ -1 +1,21 @@
 syntax="proto2";
+
+message WorkingMessage {
+        required int32 b = 1;
+        required int32 Z = 2;
+}
+
+message FailingMessageBecauseMembersAreMacroParameter {
+        required int32 a = 1;
+        required int32 X = 2;
+}
+
+message TestMacroParametersAndUnderscores {
+        required int32 a     = 1;
+        required int32 a_    = 2;
+        required int32 X     = 3;
+        required int32 X_    = 4;
+        required int32 X__   = 5;
+        required int32 X___  = 6;
+        required int32 X____ = 7;
+}