diff options
Diffstat (limited to 'test/unit/formatc.lua')
-rw-r--r-- | test/unit/formatc.lua | 201 |
1 files changed, 135 insertions, 66 deletions
diff --git a/test/unit/formatc.lua b/test/unit/formatc.lua index c94f0d88f7..ce9cb81f4a 100644 --- a/test/unit/formatc.lua +++ b/test/unit/formatc.lua @@ -24,103 +24,145 @@ SOFTWARE. --]] -- work. -- see: http://lua-users.org/wiki/LpegRecipes -local lpeg = require "lpeg" +local lpeg = require 'lpeg' local C, P, R, S, V = lpeg.C, lpeg.P, lpeg.R, lpeg.S, lpeg.V local Carg, Cc, Cp, Ct = lpeg.Carg, lpeg.Cc, lpeg.Cp, lpeg.Ct -local tokens = P { "tokens"; +local tokens = P { + 'tokens', -- Comment of form /* ... */ - comment = Ct(P"/*" * C((V"newline" + (1 - P"*/"))^0) * P"*/" * Cc"comment"), + comment = Ct(P '/*' * C((V 'newline' + (1 - P '*/')) ^ 0) * P '*/' * Cc 'comment'), -- Single line comment - line_comment = Ct(P"//" * C((1 - V"newline")^0) * Cc"comment_line"), + line_comment = Ct(P '//' * C((1 - V 'newline') ^ 0) * Cc 'comment_line'), -- Single platform independent line break which increments line number - newline = (P"\r\n" + P"\n\r" + S"\r\n") * (Cp() * Carg(1)) / function(pos, state) + newline = (P '\r\n' + P '\n\r' + S '\r\n') * (Cp() * Carg(1)) / function(pos, state) state.line = state.line + 1 state.line_start = pos end, -- Line continuation - line_extend = Ct(C(P[[\]] * V"newline") * Cc"line_extend"), + line_extend = Ct(C(P [[\]] * V 'newline') * Cc 'line_extend'), -- Whitespace of any length (includes newlines) - whitespace = Ct(C((S" \t" + V"newline")^1) * Cc"whitespace"), + whitespace = Ct(C((S ' \t' + V 'newline') ^ 1) * Cc 'whitespace'), -- Special form of #include with filename followed in angled brackets (matches 3 tokens) - include = Ct(C(P"#include") * Cc"preprocessor") * - Ct(C(S" \t"^1) * Cc"whitespace") * - Ct(C(P"<" * (1 - P">")^1 * P">") * Cc"string"), + include = Ct(C(P '#include') * Cc 'preprocessor') * Ct(C(S ' \t' ^ 1) * Cc 'whitespace') * Ct( + C(P '<' * (1 - P '>') ^ 1 * P '>') * Cc 'string' + ), -- Preprocessor instruction - preprocessor = V"include" + - Ct(C(P"#" * P" "^0 * ( P"define" + P"elif" + P"else" + P"endif" + P"#" + - P"error" + P"ifdef" + P"ifndef" + P"if" + P"import" + - P"include" + P"line" + P"pragma" + P"undef" + P"using" + - P"pragma" - ) * #S" \r\n\t") * Cc"preprocessor"), + preprocessor = V 'include' + + Ct( + C( + P '#' + * P ' ' ^ 0 + * (P 'define' + P 'elif' + P 'else' + P 'endif' + P '#' + P 'error' + P 'ifdef' + P 'ifndef' + P 'if' + P 'import' + P 'include' + P 'line' + P 'pragma' + P 'undef' + P 'using' + P 'pragma') + * #S ' \r\n\t' + ) * Cc 'preprocessor' + ), -- Identifier of form [a-zA-Z_][a-zA-Z0-9_]* - identifier = Ct(C(R("az","AZ","__") * R("09","az","AZ","__")^0) * Cc"identifier"), + identifier = Ct(C(R('az', 'AZ', '__') * R('09', 'az', 'AZ', '__') ^ 0) * Cc 'identifier'), -- Single character in a string - sstring_char = R("\001&","([","]\255") + (P"\\" * S[[ntvbrfa\?'"0x]]), - dstring_char = R("\001!","#[","]\255") + (P"\\" * S[[ntvbrfa\?'"0x]]), + sstring_char = R('\001&', '([', ']\255') + (P '\\' * S [[ntvbrfa\?'"0x]]), + dstring_char = R('\001!', '#[', ']\255') + (P '\\' * S [[ntvbrfa\?'"0x]]), -- String literal - string = Ct(C(P"'" * (V"sstring_char" + P'"')^0 * P"'" + - P'"' * (V"dstring_char" + P"'")^0 * P'"') * Cc"string"), + string = Ct( + C( + P "'" * (V 'sstring_char' + P '"') ^ 0 * P "'" + + P '"' * (V 'dstring_char' + P "'") ^ 0 * P '"' + ) * Cc 'string' + ), -- Operator - operator = Ct(C(P">>=" + P"<<=" + P"..." + - P"::" + P"<<" + P">>" + P"<=" + P">=" + P"==" + P"!=" + - P"||" + P"&&" + P"++" + P"--" + P"->" + P"+=" + P"-=" + - P"*=" + P"/=" + P"|=" + P"&=" + P"^=" + S"+-*/=<>%^|&.?:!~,") * Cc"operator"), + operator = Ct( + C( + P '>>=' + + P '<<=' + + P '...' + + P '::' + + P '<<' + + P '>>' + + P '<=' + + P '>=' + + P '==' + + P '!=' + + P '||' + + P '&&' + + P '++' + + P '--' + + P '->' + + P '+=' + + P '-=' + + P '*=' + + P '/=' + + P '|=' + + P '&=' + + P '^=' + + S '+-*/=<>%^|&.?:!~,' + ) * Cc 'operator' + ), -- Misc. char (token type is the character itself) - char = Ct(C(S"[]{}();") / function(x) return x, x end), + char = Ct(C(S '[]{}();') / function(x) + return x, x + end), -- Hex, octal or decimal number - int = Ct(C((P"0x" * R("09","af","AF")^1) + (P"0" * R"07"^0) + R"09"^1) * Cc"integer"), + int = Ct( + C((P '0x' * R('09', 'af', 'AF') ^ 1) + (P '0' * R '07' ^ 0) + R '09' ^ 1) * Cc 'integer' + ), -- Floating point number - f_exponent = S"eE" + S"+-"^-1 * R"09"^1, - f_terminator = S"fFlL", - float = Ct(C( - R"09"^1 * V"f_exponent" * V"f_terminator"^-1 + - R"09"^0 * P"." * R"09"^1 * V"f_exponent"^-1 * V"f_terminator"^-1 + - R"09"^1 * P"." * R"09"^0 * V"f_exponent"^-1 * V"f_terminator"^-1 - ) * Cc"float"), + f_exponent = S 'eE' + S '+-' ^ -1 * R '09' ^ 1, + f_terminator = S 'fFlL', + float = Ct( + C( + R '09' ^ 1 * V 'f_exponent' * V 'f_terminator' ^ -1 + + R '09' ^ 0 * P '.' * R '09' ^ 1 * V 'f_exponent' ^ -1 * V 'f_terminator' ^ -1 + + R '09' ^ 1 * P '.' * R '09' ^ 0 * V 'f_exponent' ^ -1 * V 'f_terminator' ^ -1 + ) * Cc 'float' + ), -- Any token - token = V"comment" + - V"line_comment" + - V"identifier" + - V"whitespace" + - V"line_extend" + - V"preprocessor" + - V"string" + - V"char" + - V"operator" + - V"float" + - V"int", + token = V 'comment' + + V 'line_comment' + + V 'identifier' + + V 'whitespace' + + V 'line_extend' + + V 'preprocessor' + + V 'string' + + V 'char' + + V 'operator' + + V 'float' + + V 'int', -- Error for when nothing else matches error = (Cp() * C(P(1) ^ -8) * Carg(1)) / function(pos, where, state) - error(("Tokenising error on line %i, position %i, near '%s'") - :format(state.line, pos - state.line_start + 1, where)) + error( + ("Tokenising error on line %i, position %i, near '%s'"):format( + state.line, + pos - state.line_start + 1, + where + ) + ) end, -- Match end of input or throw error - finish = -P(1) + V"error", + finish = -P(1) + V 'error', -- Match stream of tokens into a table - tokens = Ct(V"token" ^ 0) * V"finish", + tokens = Ct(V 'token' ^ 0) * V 'finish', } local function TokeniseC(str) - return tokens:match(str, 1, {line = 1, line_start = 1}) + return tokens:match(str, 1, { line = 1, line_start = 1 }) end local function set(t) @@ -131,16 +173,43 @@ local function set(t) return s end -local C_keywords = set { -- luacheck: ignore - "break", "case", "char", "const", "continue", "default", "do", "double", - "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", - "register", "return", "short", "signed", "sizeof", "static", "struct", - "switch", "typedef", "union", "unsigned", "void", "volatile", "while", +local C_keywords = set { -- luacheck: ignore + 'break', + 'case', + 'char', + 'const', + 'continue', + 'default', + 'do', + 'double', + 'else', + 'enum', + 'extern', + 'float', + 'for', + 'goto', + 'if', + 'int', + 'long', + 'register', + 'return', + 'short', + 'signed', + 'sizeof', + 'static', + 'struct', + 'switch', + 'typedef', + 'union', + 'unsigned', + 'void', + 'volatile', + 'while', } -- Very primitive C formatter that tries to put "things" inside braces on one -- line. This is a step done after preprocessing the C source to ensure that --- the duplicate line detecter can more reliably pick out identical declarations. +-- the duplicate line detector can more reliably pick out identical declarations. -- -- an example: -- struct mystruct @@ -174,7 +243,7 @@ local function formatc(str) -- if we're not inside a block, we're at the basic statement level, -- and ';' indicates we're at the end of a statement, so we put end -- it with a newline. - token[1] = token[1] .. "\n" + token[1] = token[1] .. '\n' end_at_brace = false end elseif typ == 'identifier' then @@ -194,20 +263,20 @@ local function formatc(str) -- if we're not inside a block, we're at the basic statement level, -- and ';' indicates we're at the end of a statement, so we put end -- it with a newline. - token[1] = ";\n" + token[1] = ';\n' end elseif typ == 'whitespace' then -- replace all whitespace by one space - local repl = " " + local repl = ' ' -- except when allow_on_nl is true and there's a newline in the whitespace - if string.find(token[1], "[\r\n]+") and allow_one_nl == true then + if string.find(token[1], '[\r\n]+') and allow_one_nl == true then -- in that case we replace all whitespace by one newline - repl = "\n" + repl = '\n' allow_one_nl = false end - token[1] = string.gsub(token[1], "%s+", repl) + token[1] = string.gsub(token[1], '%s+', repl) end result[#result + 1] = token[1] end @@ -216,8 +285,8 @@ local function formatc(str) end -- standalone operation (very handy for debugging) -local function standalone(...) -- luacheck: ignore - local Preprocess = require("preprocess") +local function standalone(...) -- luacheck: ignore + local Preprocess = require('preprocess') Preprocess.add_to_include_path('./../../src') Preprocess.add_to_include_path('./../../build/include') Preprocess.add_to_include_path('./../../.deps/usr/include') @@ -226,9 +295,9 @@ local function standalone(...) -- luacheck: ignore local formatted if #arg == 2 and arg[2] == 'no' then - formatted = raw + formatted = raw else - formatted = formatc(raw) + formatted = formatc(raw) end print(formatted) |