From 8ab3b5c9f78fefc5891b38b6316193d440294beb Mon Sep 17 00:00:00 2001
From: Hackerpilot <briancschott@gmail.com>
Date: Sun, 8 Mar 2015 18:01:04 -0700
Subject: [PATCH] Fix #74

---
 src/dfmt.d            | 42 ++++++++++++++++++++++++++++++++++++++----
 tests/issue0074.d     | 13 +++++++++++++
 tests/issue0074.d.ref | 13 +++++++++++++
 3 files changed, 64 insertions(+), 4 deletions(-)
 create mode 100644 tests/issue0074.d
 create mode 100644 tests/issue0074.d.ref

diff --git a/src/dfmt.d b/src/dfmt.d
index a1bddfa..5bdb674 100644
--- a/src/dfmt.d
+++ b/src/dfmt.d
@@ -293,7 +293,7 @@ private:
         else if (isBlockHeader())
         {
             if (current.type == tok!"if")
-                ifIndents ~= tempIndent;
+                ifIndents.push(tempIndent);
             writeToken();
             write(" ");
             writeParens(false);
@@ -464,9 +464,9 @@ private:
             case tok!";":
                 if (peekIs(tok!"else"))
                 {
-                    tempIndent = ifIndents[$ - 1];
+                    tempIndent = ifIndents.top();
                     if (ifIndents.length)
-                        ifIndents = ifIndents[0 .. $ - 1];
+                        ifIndents.pop();
                 }
                 else if (!peekIs(tok!"}"))
                     tempIndent = 0;
@@ -669,6 +669,7 @@ private:
         {
             if (current.type == tok!"{")
             {
+                braceIndents.push(tempIndent);
                 depth++;
                 if (assumeSorted(astInformation.structInitStartLocations)
                     .equalRange(tokens[index].index).length)
@@ -695,6 +696,7 @@ private:
             }
             else if (current.type == tok!"}")
             {
+                braceIndents.pop();
                 if (assumeSorted(astInformation.structInitEndLocations)
                     .equalRange(tokens[index].index).length)
                 {
@@ -1071,7 +1073,10 @@ private:
         if (hasCurrent)
         {
             if (current.type == tok!"}")
+            {
+                tempIndent = braceIndents.top();
                 indentLevel--;
+            }
             else if ((!assumeSorted(astInformation.attributeDeclarationLines)
                 .equalRange(current.line).empty) || (current.type == tok!"identifier"
                 && peekIs(tok!":") && !isBlockHeader(2)))
@@ -1139,7 +1144,8 @@ private:
 
     size_t[] linebreakHints;
 
-    int[] ifIndents;
+    FixedStack ifIndents;
+    FixedStack braceIndents;
 
     /// Configuration
     FormatterConfig* config;
@@ -1652,6 +1658,34 @@ State[] validMoves(const Token[] tokens, ref const State current,
     return states;
 }
 
+struct FixedStack
+{
+    void push(int i)
+    {
+        index = index == 255 ? index : index + 1;
+        arr[index] = i;
+    }
+
+    void pop()
+    {
+        index = index == 0 ? index : index - 1;
+    }
+
+    int top()
+    {
+        return arr[index];
+    }
+
+    size_t length()
+    {
+        return index;
+    }
+
+private:
+    size_t index;
+    int[256] arr;
+}
+
 unittest
 {
     import std.string : format;
diff --git a/tests/issue0074.d b/tests/issue0074.d
new file mode 100644
index 0000000..408695d
--- /dev/null
+++ b/tests/issue0074.d
@@ -0,0 +1,13 @@
+@property bool isFunctionType()
+{
+	with (CXTypeKind)
+		return kind == CXType_FunctionNoProto || kind == CXType_FunctionProto
+			||  // FIXME: This "hack" shouldn't be needed.
+			func.resultType.isValid;
+}
+
+@property bool isFunctionPointerType()
+{
+	with (CXTypeKind)
+		return kind == CXType_Pointer && pointeeType.isFunctionType;
+}
diff --git a/tests/issue0074.d.ref b/tests/issue0074.d.ref
new file mode 100644
index 0000000..94a4645
--- /dev/null
+++ b/tests/issue0074.d.ref
@@ -0,0 +1,13 @@
+@property bool isFunctionType()
+{
+    with (CXTypeKind)
+        return kind == CXType_FunctionNoProto || kind == CXType_FunctionProto
+            ||  // FIXME: This "hack" shouldn't be needed.
+            func.resultType.isValid;
+}
+
+@property bool isFunctionPointerType()
+{
+    with (CXTypeKind)
+        return kind == CXType_Pointer && pointeeType.isFunctionType;
+}