summaryrefslogtreecommitdiff
path: root/tools/validateinterfaces.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/validateinterfaces.py')
-rwxr-xr-xtools/validateinterfaces.py246
1 files changed, 246 insertions, 0 deletions
diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py
new file mode 100755
index 000000000..87ff46a85
--- /dev/null
+++ b/tools/validateinterfaces.py
@@ -0,0 +1,246 @@
+#! /usr/bin/env python
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Andrei Karas (4144)
+
+import os
+import re
+import sys
+from sets import Set
+
+interfaceRe = re.compile("struct (?P<name1>[a-z_]+)_interface (?P<name2>[a-z_]+)_s;")
+
+class Tracker:
+ pass
+
+def searchDefault(r, ifname):
+ defaultStr = "void {0}_defaults(void)".format(ifname);
+ for line in r:
+ if line.find(defaultStr) == 0:
+ return True
+ return False
+
+def searchStructStart(r, ifname):
+ for line in r:
+ if line.find("struct {0}_interface".format(ifname)) == 0:
+ return True
+ return False
+
+def readCFile(tracker, cFile):
+ methods = Set()
+ shortIfName = ""
+ with open(cFile, "r") as r:
+ for line in r:
+# print "cline1: " + line
+ m = interfaceRe.search(line)
+ if m != None and m.group("name1") == m.group("name2"):
+ # found C file with interface
+ ifname = m.group("name1")
+ if searchDefault(r, ifname) == False:
+ return (None, shortIfName, methods)
+ lineRe = re.compile("(?P<ifname>[a-z_]+)->(?P<method>[\w_]+)[ ][=][ ](?P<fullmethod>[^;]+);")
+ for line in r:
+# print "cline2: " + line
+ test = line.strip()
+ if len(test) > 2 and test[0:2] == "//":
+ continue
+ if len(line) > 0 and line[0] == "}":
+ break
+ m = lineRe.search(line)
+ if m != None:
+ tmp = m.group("ifname")
+ if len(tmp) < 2 or tmp[0] != ifname[0]:
+ continue
+ if shortIfName == "":
+ shortIfName = m.group("ifname")
+# print "{2}: add {0}, from: {1}".format(m.group("method"), line, ifname)
+ methods.add(m.group("method"))
+ tracker.interfaces.add(ifname);
+ tracker.fullmethods.add(m.group("fullmethod"));
+ return (ifname, shortIfName, methods)
+ return (None, shortIfName, methods)
+
+def readHFile(tracker, hFile, ifname):
+ methods = Set()
+ with open(hFile, "r") as r:
+ if searchStructStart(r, ifname) == False:
+ return methods
+ lineRe = re.compile("[(][*](?P<method>[^)]+)[)]".format(ifname))
+ for line in r:
+# print "hline: " + line
+ test = line.strip()
+ if len(test) > 2 and test[0:2] == "//":
+ continue
+ if len(line) > 0 and line[0] == "}":
+ break
+ m = lineRe.search(line)
+ if m != None:
+# print "{2}: add {0}, from: {1}".format(m.group("method"), line, ifname)
+ methods.add(m.group("method"))
+ tracker.fullmethods.add(ifname + "_" + m.group("method"))
+ return methods
+
+def checkIfFile(tracker, cFile, hFile):
+ data = readCFile(tracker, cFile)
+ cMethods = data[2]
+ ifname = data[0]
+ shortIfName = data[1]
+ if len(cMethods) > 0:
+ hMethods = readHFile(tracker, hFile, ifname)
+ for method in hMethods:
+ tracker.arr[ifname + "_" + method] = list()
+ tracker.methods.add(ifname + "_" + method)
+ if method not in cMethods:
+ print "Missing initialisation in file {0}: {1}".format(cFile, method)
+ tracker.retCode = 1
+# for method in cMethods:
+# if method not in hMethods:
+# print "Extra method in file {0}: {1}".format(cFile, method)
+
+def processIfDir(tracker, srcDir):
+ files = os.listdir(srcDir)
+ for file1 in files:
+ if file1[0] == '.' or file1 == "..":
+ continue
+ cPath = os.path.abspath(srcDir + os.path.sep + file1)
+ if not os.path.isfile(cPath):
+ processIfDir(tracker, cPath)
+ else:
+ if file1[-2:] == ".c":
+ file2 = file1[:-2] + ".h"
+ hPath = srcDir + os.path.sep + file2;
+ if os.path.exists(hPath) and os.path.isfile(hPath):
+ checkIfFile(tracker, cPath, hPath)
+
+
+def checkChr(ch):
+ if (ch >= "a" and ch <= "z") or ch == "_" or (ch >= "0" and ch <= "9" or ch == "\"" or ch == ">"):
+ return True
+ return False
+
+def checkFile(tracker, cFile):
+# print "Checking: " + cFile
+ with open(cFile, "r") as r:
+ for line in r:
+ parts = re.findall(r'[\w_]+', line)
+ for part in parts:
+ if part in tracker.methods:
+ idx = line.find(part)
+ if idx > 0:
+ if idx + len(part) >= len(line):
+ continue
+ if checkChr(line[idx + len(part)]):
+ continue
+ if checkChr(line[idx - 1]):
+ continue
+ if line[0:3] == " * ":
+ continue;
+ if line[-1] == "\n":
+ line = line[:-1]
+ text = line.strip()
+ if text[0:2] == "/*" or text[0:2] == "//":
+ continue
+ idx2 = line.find("//")
+ if idx2 > 0 and idx2 < idx:
+ continue
+ tracker.arr[part].append(line)
+
+def processDir(tracker, srcDir):
+ files = os.listdir(srcDir)
+ for file1 in files:
+ if file1[0] == '.' or file1 == "..":
+ continue
+ cPath = os.path.abspath(srcDir + os.path.sep + file1)
+ if not os.path.isfile(cPath):
+ processDir(tracker, cPath)
+ elif file1[-2:] == ".c" or file1[-2:] == ".h":
+# elif file1[-2:] == ".c":
+ checkFile(tracker, cPath)
+
+def reportMethods(tracker):
+ print "\n"
+ for method in tracker.methods:
+ if len(tracker.arr[method]) > 2:
+ print method
+ for t in tracker.arr[method]:
+ print t
+ print "\n"
+
+
+def checkLostFile(tracker, cFile):
+# print "Checking: " + cFile
+ methodRe = re.compile("^([\w0-9* _]*)([ ]|[*])(?P<ifname>[a-z_]+)_(?P<method>[\w_]+)(|[ ])[(]")
+ with open(cFile, "r") as r:
+ for line in r:
+ if line.find("(") < 1 or len(line) < 3 or line[0] == "\t" or line[0] == " " or line.find("_defaults") > 0:
+ continue
+ m = methodRe.search(line)
+ if m != None:
+ name = "{0}_{1}".format(m.group("ifname"), m.group("method"))
+ if name[:name.find("_")] not in tracker.interfaces and m.group("ifname") not in tracker.interfaces:
+ continue
+ if name not in tracker.fullmethods:
+# print "src : " + line
+ print name
+
+def processLostDir(tracker, srcDir):
+ files = os.listdir(srcDir)
+ for file1 in files:
+ if file1[0] == '.' or file1 == "..":
+ continue
+ cPath = os.path.abspath(srcDir + os.path.sep + file1)
+ if not os.path.isfile(cPath):
+ processLostDir(tracker, cPath)
+ elif file1[-2:] == ".c":
+ checkLostFile(tracker, cPath)
+
+def runIf():
+ processIfDir(tracker, "../src/char");
+ processIfDir(tracker, "../src/map");
+ processIfDir(tracker, "../src/login");
+ processIfDir(tracker, "../src/common");
+
+def runLost():
+ processLostDir(tracker, "../src/char");
+ processLostDir(tracker, "../src/map");
+ processLostDir(tracker, "../src/login");
+ processLostDir(tracker, "../src/common");
+
+def runLong():
+ processDir(tracker, "../src/char");
+ processDir(tracker, "../src/map");
+ processDir(tracker, "../src/login");
+ processDir(tracker, "../src/common");
+ reportMethods(tracker)
+
+tracker = Tracker()
+tracker.arr = dict()
+tracker.methods = Set()
+tracker.fullmethods = Set()
+tracker.interfaces = Set()
+tracker.retCode = 0
+
+if len(sys.argv) > 1:
+ cmd = sys.argv[1]
+else:
+ cmd = "default"
+
+if cmd == "silent":
+ runIf()
+elif cmd == "init":
+ print "Checking interfaces initialisation"
+ runIf()
+elif cmd == "lost":
+ print "Checking not added functions to interfaces"
+ runLost();
+elif cmd == "long":
+ print "Checking interfaces usage"
+ runLong();
+else:
+ print "Checking interfaces initialisation"
+ runIf()
+ print "Checking not added functions to interfaces"
+ runLost();
+ print "Checking interfaces usage"
+ runLong();
+exit(tracker.retCode)