From a02509ff4b29a03fd396ff62a2b19ac96f71ef39 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 17 Jul 2014 22:19:52 +0200 Subject: Initial version of a script to check basic style. This script reports basic violations of the style, such as indentation using spaces, alignment using tabs, trailing whitespace etc. Passing this script does NOT mean that the style is clean, it's only for fast-checking purposes. --- src/CheckBasicStyle.lua | 188 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 src/CheckBasicStyle.lua (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua new file mode 100644 index 000000000..f9bb41975 --- /dev/null +++ b/src/CheckBasicStyle.lua @@ -0,0 +1,188 @@ + +-- CheckBasicStyle.lua + +--[[ +Checks that all source files (*.cpp, *.h) use the basic style requirements of the project: + - Tabs for indentation, spaces for alignment + - Trailing whitespace on non-empty lines + - Two spaces between code and line-end comment ("//") + - (TODO) Spaces around +, -, (cannot check /, * or & due to their other usage - comment, ptr deref, address-of) + - (TODO) Spaces before *, /, & + - (TODO) Spaces after , + - (TODO) Hex numbers with even digit length + - (TODO) Hex numbers in lowercase + - (TODO) Braces not on the end of line + - (TODO) Line dividers (////...) exactly 80 slashes + +Reports all violations on stdout in a form that is readable by Visual Studio's parser, so that dblclicking +the line brings the editor directly to the violation. + +Returns 0 on success, 1 on internal failure, 2 if any violations found + +This script requires LuaFileSystem to be available in the current Lua interpreter. +--]] + + + + + +-- Check that LFS is installed: +local hasLfs = pcall(require, "lfs") +if not(hasLfs) then + print("This script requires LuaFileSystem to be installed") + os.exit(1) +end +local lfs = require("lfs") +assert(lfs ~= nil) + + + + + +-- The list of file extensions that are processed: +local g_ShouldProcessExt = +{ + ["h"] = true, + ["cpp"] = true, +} + +--- The list of files not to be processed: +local g_IgnoredFiles = +{ + "./Bindings/Bindings.cpp", + "./Bindings/DeprecatedBindings.cpp", + "./LeakFinder.cpp", + "./LeakFinder.h", + "./MersenneTwister.h", + "./StackWalker.cpp", + "./StackWalker.h", +} + +--- The list of files not to be processed, as a dictionary (filename => true), built from g_IgnoredFiles +local g_ShouldIgnoreFile = {} + +-- Initialize the g_ShouldIgnoreFile map: +for _, fnam in ipairs(g_IgnoredFiles) do + g_ShouldIgnoreFile[fnam] = true +end + +--- Keeps track of the number of violations for this folder +local g_NumViolations = 0 + + + + + +--- Reports one violation +-- Pretty-prints the message +-- Also increments g_NumViolations +local function ReportViolation(a_FileName, a_LineNumber, a_Message) + print(a_FileName .. "(" .. a_LineNumber .. "): " .. a_Message) + g_NumViolations = g_NumViolations + 1 +end + + + + + +--- Processes one file +local function ProcessFile(a_FileName) + assert(type(a_FileName) == "string") + + -- Read the whole file: + local f, err = io.open(a_FileName, "r") + if (f == nil) then + print("Cannot open file \"" .. a_FileName .. "\": " .. err) + print("Aborting") + os.exit(1) + end + local all = f:read("*all") + + -- Check that the last line is empty - otherwise processing won't work properly: + local lastChar = string.byte(all, string.len(all)) + if ((lastChar ~= 13) and (lastChar ~= 10)) then + local numLines = 1 + string.gsub(all, "\n", function() numLines = numLines + 1 end) -- Count the number of line-ends + ReportViolation(a_FileName, numLines, "Missing empty line at file end") + return + end + + -- Process each line separately: + -- Ref.: http://stackoverflow.com/questions/10416869/iterate-over-possibly-empty-lines-in-a-way-that-matches-the-expectations-of-exis + local lineCounter = 1 + all:gsub("\r\n", "\n") -- normalize CRLF into LF-only + string.gsub(all .. "\n", "[^\n]*\n", -- Iterate over each line, while preserving empty lines + function(a_Line) + -- Check against indenting using spaces: + if (a_Line:find("^\t* +")) then -- Find any number of tabs at the start of line (incl 0), followed by a space + ReportViolation(a_FileName, lineCounter, "Indenting with a space") + end + -- Check against alignment using tabs: + if (a_Line:find("[^%s]\t+[^%s]")) then -- Find any number of tabs after non-whitespace followed by non-whitespace + ReportViolation(a_FileName, lineCounter, "Aligning with a tab") + end + -- Check against trailing whitespace: + if (a_Line:find("[^%s]%s+\n")) then -- Find any whitespace after non-whitespace at the end of line + ReportViolation(a_FileName, lineCounter, "Trailing whitespace") + end + -- Check that all "//"-style comments have at least two spaces in front (unless alone on line): + if (a_Line:find("[^%s] //")) then + ReportViolation(a_FileName, lineCounter, "Needs at least two spaces in front of a \"//\"-style comment") + end + -- Check that all "//"-style comments have at least one spaces after: + if (a_Line:find("%s//[^%s/*<]")) then + ReportViolation(a_FileName, lineCounter, "Needs a space after a \"//\"-style comment") + end + lineCounter = lineCounter + 1 + end + ) +end + + + + + +--- Processes one item - a file or a folder +local function ProcessItem(a_ItemName) + assert(type(a_ItemName) == "string") + + -- Skip files / folders that should be ignored + if (g_ShouldIgnoreFile[a_ItemName]) then + return + end + + -- If the item is a folder, recurse: + local attrs = lfs.attributes(a_ItemName) + if (attrs and (attrs.mode == "directory")) then + for fnam in lfs.dir(a_ItemName) do + if ((fnam ~= ".") and (fnam ~= "..")) then + ProcessItem(a_ItemName .. "/" .. fnam) + end + end + return + end + + local ext = a_ItemName:match("%.([^/%.]-)$") + if (g_ShouldProcessExt[ext]) then + ProcessFile(a_ItemName) + end +end + + + + + +-- Process the entire current folder: +ProcessItem(".") + +-- Report final verdict: +print("Number of violations found: " .. g_NumViolations) +if (g_NumViolations > 0) then + os.exit(2) +else + os.exit(0) +end + + + + -- cgit v1.2.3 From 204b59117225268a569fb68614bb59add4d53a03 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 18 Jul 2014 09:58:29 +0200 Subject: CheckBasicStyle: Proper spaces with commas. --- src/CheckBasicStyle.lua | 69 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 21 deletions(-) (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index f9bb41975..6aad4125d 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -6,13 +6,16 @@ Checks that all source files (*.cpp, *.h) use the basic style requirements of th - Tabs for indentation, spaces for alignment - Trailing whitespace on non-empty lines - Two spaces between code and line-end comment ("//") - - (TODO) Spaces around +, -, (cannot check /, * or & due to their other usage - comment, ptr deref, address-of) + - Spaces after comma, not before (except in #define argument list) - (TODO) Spaces before *, /, & - - (TODO) Spaces after , - (TODO) Hex numbers with even digit length - (TODO) Hex numbers in lowercase - (TODO) Braces not on the end of line - (TODO) Line dividers (////...) exactly 80 slashes + - (TODO) Not using "* "-style doxy comments continuation lines + +Violations that cannot be checked easily: + - Spaces around "+" (there are things like "a++", "++a", "a += 1", "X+", "stack +1" and ascii-drawn tables) Reports all violations on stdout in a form that is readable by Visual Studio's parser, so that dblclicking the line brings the editor directly to the violation. @@ -85,6 +88,45 @@ end +--- Searches for the specified pattern, if found, reports it as a violation with the given message +local function ReportViolationIfFound(a_Line, a_FileName, a_LineNum, a_Pattern, a_Message) + local patStart, patEnd = a_Line:find(a_Pattern) + if not(patStart) then + return + end + ReportViolation(a_FileName, a_LineNum, a_Message .. "(" .. patStart .. " .. " .. patEnd .. ")") +end + + + + + +local g_ViolationPatterns = +{ + -- Check against indenting using spaces: + {"^\t* +", "Indenting with a space"}, + + -- Check against alignment using tabs: + {"[^%s]\t+[^%s]", "Aligning with a tab"}, + + -- Check against trailing whitespace: + {"[^%s]%s+\n", "Trailing whitespace"}, + + -- Check that all "//"-style comments have at least two spaces in front (unless alone on line): + {"[^%s] //", "Needs at least two spaces in front of a \"//\"-style comment"}, + + -- Check that all "//"-style comments have at least one spaces after: + {"%s//[^%s/*<]", "Needs a space after a \"//\"-style comment"}, + + -- Check that all commas have spaces after them and not in front of them: + {" ,", "Extra space before a \",\""}, + {"^\t*[^#].*,[^%s]", "Needs a space after a \",\""}, -- Anywhere except lines starting with "#" - avoid #define params +} + + + + + --- Processes one file local function ProcessFile(a_FileName) assert(type(a_FileName) == "string") @@ -113,26 +155,11 @@ local function ProcessFile(a_FileName) all:gsub("\r\n", "\n") -- normalize CRLF into LF-only string.gsub(all .. "\n", "[^\n]*\n", -- Iterate over each line, while preserving empty lines function(a_Line) - -- Check against indenting using spaces: - if (a_Line:find("^\t* +")) then -- Find any number of tabs at the start of line (incl 0), followed by a space - ReportViolation(a_FileName, lineCounter, "Indenting with a space") - end - -- Check against alignment using tabs: - if (a_Line:find("[^%s]\t+[^%s]")) then -- Find any number of tabs after non-whitespace followed by non-whitespace - ReportViolation(a_FileName, lineCounter, "Aligning with a tab") - end - -- Check against trailing whitespace: - if (a_Line:find("[^%s]%s+\n")) then -- Find any whitespace after non-whitespace at the end of line - ReportViolation(a_FileName, lineCounter, "Trailing whitespace") - end - -- Check that all "//"-style comments have at least two spaces in front (unless alone on line): - if (a_Line:find("[^%s] //")) then - ReportViolation(a_FileName, lineCounter, "Needs at least two spaces in front of a \"//\"-style comment") - end - -- Check that all "//"-style comments have at least one spaces after: - if (a_Line:find("%s//[^%s/*<]")) then - ReportViolation(a_FileName, lineCounter, "Needs a space after a \"//\"-style comment") + -- Check against each violation pattern: + for _, pat in ipairs(g_ViolationPatterns) do + ReportViolationIfFound(a_Line, a_FileName, lineCounter, pat[1], pat[2]) end + lineCounter = lineCounter + 1 end ) -- cgit v1.2.3 From 822d83009d9ccc698e930907a707ba2451e95a20 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 19 Jul 2014 15:08:49 +0200 Subject: CheckBasicStyle: Check spaces around commas. We want no space in front of and at least one space after a comma. --- src/CheckBasicStyle.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 6aad4125d..14e3caa26 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -6,13 +6,13 @@ Checks that all source files (*.cpp, *.h) use the basic style requirements of th - Tabs for indentation, spaces for alignment - Trailing whitespace on non-empty lines - Two spaces between code and line-end comment ("//") - - Spaces after comma, not before (except in #define argument list) + - Spaces after comma, not before - (TODO) Spaces before *, /, & - (TODO) Hex numbers with even digit length - (TODO) Hex numbers in lowercase - (TODO) Braces not on the end of line - (TODO) Line dividers (////...) exactly 80 slashes - - (TODO) Not using "* "-style doxy comments continuation lines + - (TODO) Not using "* "-style doxy comment continuation lines Violations that cannot be checked easily: - Spaces around "+" (there are things like "a++", "++a", "a += 1", "X+", "stack +1" and ascii-drawn tables) @@ -79,8 +79,8 @@ local g_NumViolations = 0 --- Reports one violation -- Pretty-prints the message -- Also increments g_NumViolations -local function ReportViolation(a_FileName, a_LineNumber, a_Message) - print(a_FileName .. "(" .. a_LineNumber .. "): " .. a_Message) +local function ReportViolation(a_FileName, a_LineNumber, a_PatStart, a_PatEnd, a_Message) + print(a_FileName .. "(" .. a_LineNumber .. "): " .. a_PatStart .. " .. " .. a_PatEnd .. ": " .. a_Message) g_NumViolations = g_NumViolations + 1 end @@ -94,7 +94,7 @@ local function ReportViolationIfFound(a_Line, a_FileName, a_LineNum, a_Pattern, if not(patStart) then return end - ReportViolation(a_FileName, a_LineNum, a_Message .. "(" .. patStart .. " .. " .. patEnd .. ")") + ReportViolation(a_FileName, a_LineNum, patStart, patEnd, a_Message) end @@ -120,7 +120,7 @@ local g_ViolationPatterns = -- Check that all commas have spaces after them and not in front of them: {" ,", "Extra space before a \",\""}, - {"^\t*[^#].*,[^%s]", "Needs a space after a \",\""}, -- Anywhere except lines starting with "#" - avoid #define params + {",[^%s\"%%]", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting } -- cgit v1.2.3 From e612d07eeae351cbdb413dbb8fb543284ea46628 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 19 Jul 2014 15:25:28 +0200 Subject: CheckBasicStyle: Checks for braces not on separate lines. Only the opening braces at the end of a line are checked, others (such as inline getters and setters or initializers) are valid. --- src/CheckBasicStyle.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 14e3caa26..e4597a426 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -7,10 +7,11 @@ Checks that all source files (*.cpp, *.h) use the basic style requirements of th - Trailing whitespace on non-empty lines - Two spaces between code and line-end comment ("//") - Spaces after comma, not before + - Opening braces not at the end of a code line + - (TODO) Spaces after if, for, while - (TODO) Spaces before *, /, & - (TODO) Hex numbers with even digit length - (TODO) Hex numbers in lowercase - - (TODO) Braces not on the end of line - (TODO) Line dividers (////...) exactly 80 slashes - (TODO) Not using "* "-style doxy comment continuation lines @@ -121,6 +122,9 @@ local g_ViolationPatterns = -- Check that all commas have spaces after them and not in front of them: {" ,", "Extra space before a \",\""}, {",[^%s\"%%]", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting + + -- Check that opening braces are not at the end of a code line: + {"[^%s].-{\n?$", "Brace should be on a separate line"}, } @@ -145,7 +149,7 @@ local function ProcessFile(a_FileName) if ((lastChar ~= 13) and (lastChar ~= 10)) then local numLines = 1 string.gsub(all, "\n", function() numLines = numLines + 1 end) -- Count the number of line-ends - ReportViolation(a_FileName, numLines, "Missing empty line at file end") + ReportViolation(a_FileName, numLines, 1, 1, "Missing empty line at file end") return end -- cgit v1.2.3 From fe6a3b5d7229ae07b536afa794fdb5bedbeb37e4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 21 Jul 2014 15:20:27 +0200 Subject: CheckBasicStyle: Checks spaces after keywords, no space before ")". --- src/CheckBasicStyle.lua | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index e4597a426..ddc552fa4 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -8,7 +8,7 @@ Checks that all source files (*.cpp, *.h) use the basic style requirements of th - Two spaces between code and line-end comment ("//") - Spaces after comma, not before - Opening braces not at the end of a code line - - (TODO) Spaces after if, for, while + - Spaces after if, for, while - (TODO) Spaces before *, /, & - (TODO) Hex numbers with even digit length - (TODO) Hex numbers in lowercase @@ -125,6 +125,21 @@ local g_ViolationPatterns = -- Check that opening braces are not at the end of a code line: {"[^%s].-{\n?$", "Brace should be on a separate line"}, + + -- Space after keywords: + {"[^_]if%(", "Needs a space after \"if\""}, + {"for%(", "Needs a space after \"for\""}, + {"while%(", "Needs a space after \"while\""}, + {"switch%(", "Needs a space after \"switch\""}, + + -- No space after keyword's parenthesis: + {"[^%a#]if %( ", "Remove the space after \"(\""}, + {"for %( ", "Remove the space after \"(\""}, + {"while %( ", "Remove the space after \"(\""}, + {"switch %( ", "Remove the space after \"(\""}, + + -- No space before a closing parenthesis: + {" %)", "Remove the space before \")\""}, } -- cgit v1.2.3 From 9e7b9a4ebe815bd631d8b124e81f017fc7fa35a2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 21 Jul 2014 15:21:54 +0200 Subject: Normalized spaces after "catch". --- src/CheckBasicStyle.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index ddc552fa4..fba30ea98 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -131,12 +131,13 @@ local g_ViolationPatterns = {"for%(", "Needs a space after \"for\""}, {"while%(", "Needs a space after \"while\""}, {"switch%(", "Needs a space after \"switch\""}, + {"catch%(", "Needs a space after \"catch\""}, -- No space after keyword's parenthesis: {"[^%a#]if %( ", "Remove the space after \"(\""}, {"for %( ", "Remove the space after \"(\""}, {"while %( ", "Remove the space after \"(\""}, - {"switch %( ", "Remove the space after \"(\""}, + {"catch %( ", "Remove the space after \"(\""}, -- No space before a closing parenthesis: {" %)", "Remove the space before \")\""}, -- cgit v1.2.3 From 26ad3dbee4aacef035e2d085fecdc5610469fc7d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 21 Jul 2014 17:38:36 +0200 Subject: CheckBasicStyle: Doesn't require LuaFileSystem. Instead it uses the list of files generated by CMake. --- src/CheckBasicStyle.lua | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index fba30ea98..e85c074dc 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -23,26 +23,12 @@ the line brings the editor directly to the violation. Returns 0 on success, 1 on internal failure, 2 if any violations found -This script requires LuaFileSystem to be available in the current Lua interpreter. --]] --- Check that LFS is installed: -local hasLfs = pcall(require, "lfs") -if not(hasLfs) then - print("This script requires LuaFileSystem to be installed") - os.exit(1) -end -local lfs = require("lfs") -assert(lfs ~= nil) - - - - - -- The list of file extensions that are processed: local g_ShouldProcessExt = { @@ -53,13 +39,12 @@ local g_ShouldProcessExt = --- The list of files not to be processed: local g_IgnoredFiles = { - "./Bindings/Bindings.cpp", - "./Bindings/DeprecatedBindings.cpp", - "./LeakFinder.cpp", - "./LeakFinder.h", - "./MersenneTwister.h", - "./StackWalker.cpp", - "./StackWalker.h", + "Bindings/Bindings.cpp", + "LeakFinder.cpp", + "LeakFinder.h", + "MersenneTwister.h", + "StackWalker.cpp", + "StackWalker.h", } --- The list of files not to be processed, as a dictionary (filename => true), built from g_IgnoredFiles @@ -198,17 +183,6 @@ local function ProcessItem(a_ItemName) return end - -- If the item is a folder, recurse: - local attrs = lfs.attributes(a_ItemName) - if (attrs and (attrs.mode == "directory")) then - for fnam in lfs.dir(a_ItemName) do - if ((fnam ~= ".") and (fnam ~= "..")) then - ProcessItem(a_ItemName .. "/" .. fnam) - end - end - return - end - local ext = a_ItemName:match("%.([^/%.]-)$") if (g_ShouldProcessExt[ext]) then ProcessFile(a_ItemName) @@ -219,8 +193,10 @@ end --- Process the entire current folder: -ProcessItem(".") +-- Process all files in the AllFiles.lst file (generated by cmake): +for fnam in io.lines("AllFiles.lst") do + ProcessItem(fnam) +end -- Report final verdict: print("Number of violations found: " .. g_NumViolations) -- cgit v1.2.3 From 63cc008340a13428eb254e82acf886035c728025 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 21 Jul 2014 17:57:50 +0200 Subject: CheckBasicStyle: Added a lua shebang. --- src/CheckBasicStyle.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'src/CheckBasicStyle.lua') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index e85c074dc..13a6d15d2 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -1,3 +1,4 @@ +#!/usr/bin/env lua -- CheckBasicStyle.lua -- cgit v1.2.3