From b860a92582e64e7051ce03fe5b694450d554bb3f Mon Sep 17 00:00:00 2001
From: Robert Goulet <robert.goulet@autodesk.com>
Date: Fri, 19 Feb 2016 14:00:19 -0500
Subject: Xcode: Refactor block writes to allow any level of nesting

Reviewed-by: Gregor Jasny <gjasny@googlemail.com>
---
 Source/cmXCodeObject.cxx | 126 +++++++++++++++++++++++------------------------
 Source/cmXCodeObject.h   |   4 ++
 2 files changed, 67 insertions(+), 63 deletions(-)

diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index 5bc34c1..911e154 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -111,102 +111,102 @@ void cmXCodeObject::Print(std::ostream& out)
   for(i = this->ObjectAttributes.begin();
       i != this->ObjectAttributes.end(); ++i)
     {
-    cmXCodeObject* object = i->second;
-    if(i->first != "isa")
-      {
-      cmXCodeObject::Indent(3*indentFactor, out);
-      }
-    else
-      {
+    if(i->first == "isa")
       continue;
-      }
-    if(object->TypeValue == OBJECT_LIST)
-      {
-      out << i->first << " = (" << separator;
-      for(unsigned int k = 0; k < i->second->List.size(); k++)
-        {
-        cmXCodeObject::Indent(4*indentFactor, out);
-        out << i->second->List[k]->Id;
-        i->second->List[k]->PrintComment(out);
-        out << "," << separator;
-        }
-      cmXCodeObject::Indent(3*indentFactor, out);
-      out << ");" << separator;
-      }
-    else if(object->TypeValue == ATTRIBUTE_GROUP)
+
+    PrintAttribute(out, 3, separator, indentFactor, i->first, i->second, this);
+    }
+  cmXCodeObject::Indent(2*indentFactor, out);
+  out << "};\n";
+}
+
+void cmXCodeObject::PrintAttribute(std::ostream& out, const int level,
+                                   const std::string separator,
+                                   const int factor, const std::string& name,
+                                   const cmXCodeObject* object,
+                                   const cmXCodeObject* parent)
+{
+  cmXCodeObject::Indent(level * factor, out);
+  switch(object->TypeValue)
+    {
+    case OBJECT_LIST:
       {
-      std::map<std::string, cmXCodeObject*>::iterator j;
-      out << i->first << " = {";
-      if(separator == "\n")
+      out << name << " = (";
+      if(parent->TypeValue != ATTRIBUTE_GROUP)
         {
         out << separator;
         }
-      for(j = object->ObjectAttributes.begin(); j !=
-            object->ObjectAttributes.end(); ++j)
+      for(unsigned int i = 0; i < object->List.size(); ++i)
         {
-        cmXCodeObject::Indent(4 *indentFactor, out);
-
-        if(j->second->TypeValue == STRING)
-          {
-          cmXCodeObject::PrintString(out,j->first);
-          out << " = ";
-          j->second->PrintString(out);
-          out << ";";
-          }
-        else if(j->second->TypeValue == OBJECT_LIST)
+        if(object->List[i]->TypeValue == STRING)
           {
-          cmXCodeObject::PrintString(out,j->first);
-          out << " = (";
-          for(unsigned int k = 0; k < j->second->List.size(); k++)
+          object->List[i]->PrintString(out);
+          if(i+1 < object->List.size())
             {
-            if(j->second->List[k]->TypeValue == STRING)
-              {
-              j->second->List[k]->PrintString(out);
-              out << ", ";
-              }
-            else
-              {
-              out << "List_" << k << "_TypeValue_IS_NOT_STRING, ";
-              }
+            out << ",";
             }
-          out << ");";
           }
         else
           {
-          cmXCodeObject::PrintString(out,j->first);
-          out << " = error_unexpected_TypeValue_" <<
-            j->second->TypeValue << ";";
+          cmXCodeObject::Indent((level + 1) * factor, out);
+          out << object->List[i]->Id;
+          object->List[i]->PrintComment(out);
+          out << "," << separator;
           }
+        }
+      if(parent->TypeValue != ATTRIBUTE_GROUP)
+        {
+        cmXCodeObject::Indent(level * factor, out);
+        }
+      out << ");" << separator;
+      }
+      break;
 
+    case ATTRIBUTE_GROUP:
+      {
+      out << name << " = {";
+      if(separator == "\n")
+        {
         out << separator;
         }
-      cmXCodeObject::Indent(3 *indentFactor, out);
+      std::map<std::string, cmXCodeObject*>::const_iterator i;
+      for(i = object->ObjectAttributes.begin();
+          i != object->ObjectAttributes.end(); ++i)
+        {
+        PrintAttribute(out, (level + 1) * factor, separator, factor,
+                       i->first, i->second, object);
+        }
+      cmXCodeObject::Indent(level * factor, out);
       out << "};" << separator;
       }
-    else if(object->TypeValue == OBJECT_REF)
+      break;
+
+    case OBJECT_REF:
       {
-      cmXCodeObject::PrintString(out,i->first);
+      cmXCodeObject::PrintString(out, name);
       out << " = " << object->Object->Id;
-      if(object->Object->HasComment() && i->first != "remoteGlobalIDString")
+      if(object->Object->HasComment() && name != "remoteGlobalIDString")
         {
         object->Object->PrintComment(out);
         }
       out << ";" << separator;
       }
-    else if(object->TypeValue == STRING)
+      break;
+
+    case STRING:
       {
-      cmXCodeObject::PrintString(out,i->first);
+      cmXCodeObject::PrintString(out, name);
       out << " = ";
       object->PrintString(out);
       out << ";" << separator;
       }
-    else
+      break;
+
+    default:
       {
-      out << "what is this?? " << i->first << "\n";
+      break;
       }
     }
-  cmXCodeObject::Indent(2*indentFactor, out);
-  out << "};\n";
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index bd0f43f..2d876da 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -75,6 +75,10 @@ public:
   }
   static void Indent(int level, std::ostream& out);
   void Print(std::ostream& out);
+  void PrintAttribute(std::ostream& out, const int level,
+                      const std::string separator, const int factor,
+                      const std::string& name, const cmXCodeObject* object,
+                      const cmXCodeObject* parent);
   virtual void PrintComment(std::ostream&) {}
 
   static void PrintList(std::vector<cmXCodeObject*> const&,
-- 
cgit v0.12