From 49bb25a16d652dee43be5454b984134918200fe1 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 9 Nov 2014 15:31:38 +0300 Subject: Add tool to validate interfaces usage. --- tools/validateinterfaces.py | 162 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100755 tools/validateinterfaces.py diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py new file mode 100755 index 000000000..987c68ed0 --- /dev/null +++ b/tools/validateinterfaces.py @@ -0,0 +1,162 @@ +#! /usr/bin/env python +# -*- coding: utf8 -*- +# +# Copyright (C) 2014 Andrei Karas (4144) + +import os +import re +from sets import Set + +interfaceRe = re.compile("struct (?P[a-z_]+)_interface (?P[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(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[a-z_]+)->(?P[\w_]+) ") + 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")) + return (ifname, shortIfName, methods) + return (None, shortIfName, methods) + +def readHFile(hFile, ifname): + methods = Set() + with open(hFile, "r") as r: + if searchStructStart(r, ifname) == False: + return methods + lineRe = re.compile("[(][*](?P[^)]+)[)]".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")) + return methods + +def checkIfFile(tracker, cFile, hFile): + data = readCFile(cFile) + cMethods = data[2] + ifname = data[0] + shortIfName = data[1] + if len(cMethods) > 0: + hMethods = readHFile(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) +# 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: + for method in tracker.methods: + idx = line.find(method) + if idx > 0: + if idx + len(method) >= len(line): + continue + if checkChr(line[idx + len(method)]): + continue + if checkChr(line[idx - 1]): + continue + if line[-1] == "\n": + line = line[:-1] + tracker.arr[method].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" + + +tracker = Tracker() +tracker.arr = dict() +tracker.methods = Set() +print "Checking initerfaces initialisation" +processIfDir(tracker, "../src"); +print "Checking interfaces usage" +processDir(tracker, "../src"); +reportMethods(tracker) -- cgit v1.2.3-70-g09d2 From be19d06b83e10c23b562c7bebe455e026a5fd738 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 10 Nov 2014 22:55:03 +0300 Subject: Check only dirs with servers sources and common dir. --- tools/validateinterfaces.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py index 987c68ed0..985ab4d59 100755 --- a/tools/validateinterfaces.py +++ b/tools/validateinterfaces.py @@ -156,7 +156,13 @@ tracker = Tracker() tracker.arr = dict() tracker.methods = Set() print "Checking initerfaces initialisation" -processIfDir(tracker, "../src"); +processIfDir(tracker, "../src/char"); +processIfDir(tracker, "../src/map"); +processIfDir(tracker, "../src/login"); +processIfDir(tracker, "../src/common"); print "Checking interfaces usage" -processDir(tracker, "../src"); +processDir(tracker, "../src/char"); +processDir(tracker, "../src/map"); +processDir(tracker, "../src/login"); +processDir(tracker, "../src/common"); reportMethods(tracker) -- cgit v1.2.3-70-g09d2 From e56747c574e3956504f0c62dd89a27e74bddb83d Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 10 Nov 2014 22:59:45 +0300 Subject: Add command line option for silent checks. It will show anything only if error found. Command line option: silent --- tools/validateinterfaces.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py index 985ab4d59..6061b358b 100755 --- a/tools/validateinterfaces.py +++ b/tools/validateinterfaces.py @@ -5,9 +5,11 @@ import os import re +import sys from sets import Set interfaceRe = re.compile("struct (?P[a-z_]+)_interface (?P[a-z_]+)_s;") +silent = False class Tracker: pass @@ -155,14 +157,21 @@ def reportMethods(tracker): tracker = Tracker() tracker.arr = dict() tracker.methods = Set() -print "Checking initerfaces initialisation" -processIfDir(tracker, "../src/char"); -processIfDir(tracker, "../src/map"); -processIfDir(tracker, "../src/login"); -processIfDir(tracker, "../src/common"); -print "Checking interfaces usage" -processDir(tracker, "../src/char"); -processDir(tracker, "../src/map"); -processDir(tracker, "../src/login"); -processDir(tracker, "../src/common"); -reportMethods(tracker) +if len(sys.argv) > 1 and sys.argv[1] == "silent": + silent = True + processIfDir(tracker, "../src/char"); + processIfDir(tracker, "../src/map"); + processIfDir(tracker, "../src/login"); + processIfDir(tracker, "../src/common"); +else: + print "Checking initerfaces initialisation" + processIfDir(tracker, "../src/char"); + processIfDir(tracker, "../src/map"); + processIfDir(tracker, "../src/login"); + processIfDir(tracker, "../src/common"); + print "Checking interfaces usage" + processDir(tracker, "../src/char"); + processDir(tracker, "../src/map"); + processDir(tracker, "../src/login"); + processDir(tracker, "../src/common"); + reportMethods(tracker) -- cgit v1.2.3-70-g09d2 From 24481e228f0d64f878b34b028c0dc03d2a4a5f7e Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 10 Nov 2014 23:03:31 +0300 Subject: Add support for return error code if any error found. --- tools/validateinterfaces.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py index 6061b358b..8c794cb7c 100755 --- a/tools/validateinterfaces.py +++ b/tools/validateinterfaces.py @@ -9,7 +9,6 @@ import sys from sets import Set interfaceRe = re.compile("struct (?P[a-z_]+)_interface (?P[a-z_]+)_s;") -silent = False class Tracker: pass @@ -90,6 +89,7 @@ def checkIfFile(tracker, cFile, hFile): 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) @@ -157,8 +157,8 @@ def reportMethods(tracker): tracker = Tracker() tracker.arr = dict() tracker.methods = Set() +tracker.retCode = 0 if len(sys.argv) > 1 and sys.argv[1] == "silent": - silent = True processIfDir(tracker, "../src/char"); processIfDir(tracker, "../src/map"); processIfDir(tracker, "../src/login"); @@ -175,3 +175,4 @@ else: processDir(tracker, "../src/login"); processDir(tracker, "../src/common"); reportMethods(tracker) +exit(tracker.retCode) -- cgit v1.2.3-70-g09d2 From e08c40aa7260c5bb84b61a759179e9b081d03a80 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 10 Nov 2014 23:40:40 +0300 Subject: Improve performance in validateinterfaces.py. --- tools/validateinterfaces.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py index 8c794cb7c..a4222adb5 100755 --- a/tools/validateinterfaces.py +++ b/tools/validateinterfaces.py @@ -119,18 +119,20 @@ def checkFile(tracker, cFile): print "Checking: " + cFile with open(cFile, "r") as r: for line in r: - for method in tracker.methods: - idx = line.find(method) - if idx > 0: - if idx + len(method) >= len(line): - continue - if checkChr(line[idx + len(method)]): - continue - if checkChr(line[idx - 1]): - continue - if line[-1] == "\n": - line = line[:-1] - tracker.arr[method].append(line) + 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[-1] == "\n": + line = line[:-1] + tracker.arr[part].append(line) def processDir(tracker, srcDir): files = os.listdir(srcDir) -- cgit v1.2.3-70-g09d2