[hacking] Add Klammerw├╝sten validation tool. master
authorMaximilian Wilhelm <max@rfc2324.org>
Wed, 4 Jun 2014 12:04:37 +0000 (14:04 +0200)
committerMaximilian Wilhelm <max@rfc2324.org>
Wed, 4 Jun 2014 12:04:37 +0000 (14:04 +0200)
Signed-off-by: Maximilian Wilhelm <max@rfc2324.org>

hacking/check_brackets.py [new file with mode: 0755]

diff --git a/hacking/check_brackets.py b/hacking/check_brackets.py
new file mode 100755 (executable)
index 0000000..df600a1
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+#
+# Little tool[tm] to find broken bracket combinations in Klammerw├╝sten.
+# Brackets containt in escaped string sequences started an ended by
+# \" or \' are ignored.
+#
+# Dedicated to Jan 'iq' Walzer :)
+#
+# Maximilian Wilhelm <max@rfc2324.org>
+#  --  Wed 04 Jun 2014 01:13:43 PM CEST
+#
+
+import sys
+import os.path
+
+if (len (sys.argv) == 1):
+       print >> sys.stderr, "Usage: %s filename" % sys.argv[0]
+       sys.exit (1)
+
+filename = sys.argv[1]
+
+stack = []
+
+brackets_close = {
+       '>' : '<',
+       '(' : ')',
+       '[' : ']',
+       '{' : '}'
+}
+
+try:
+       line_no = 0
+       with open (filename, "r") as f:
+               in_string = False
+               in_escape = False
+
+               for line in f.readlines ():
+                       line = line.strip ()
+                       line_no += 1
+                       char_no = 0
+
+                       for char in line:
+                               char_no += 1
+
+                               # Search for escape character followed by " or ' which will occur
+                               # at start or stop of a string sequence we want to ignore.
+                               if char == '\\':
+                                       in_escape = True
+                                       continue
+
+                               if in_escape == True and char in ("'", '"'):
+                                       in_string = not in_string
+
+                               else:
+                                       in_escape = False
+
+                               # If not in escaped string sequence, watch our of brackets and use
+                               # a stack to keep record of previos brackets.
+                               if char in ('<', '(', '[', '{')  and not in_string:
+                                       stack.append (char)
+
+                               elif char in ('>', ')', ']', '}') and not in_string:
+                                       # Possible IOError thrown by pop() handler below.
+                                       last_bracket = stack.pop ()
+                                       if (char != brackets_close[last_bracket]):
+                                               print >> sys.stderr, "Error in line %d at char %d: Bracket mismatch." % (line_no, char_no)
+                                               sys.exit (4)
+
+       if len (stack) > 0:
+               print >> sys.stderr, "Unclosed brackets at end of file: %s" % ", ".join (stack)
+               sys.exit (5)
+
+except IOError as i:
+       print >> sys.stderr, "Failed to open file \"%s\": %s" % (filename, i)
+       sys.exit (2)
+except IndexError as i:
+       print >> sys.stderr, "Error in line %d at char %d: Closing bracket %s without opening one before." % (line_no, char_no, char)
+       sys.exit (3)
+
+print "No errors found."