From b9ac1c6033a0b32ca9984f23223d9fc167415b10 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 28 Dec 2013 12:33:52 -0800 Subject: Implement core formatter --- src/login/login.cpp | 6 +- src/map/magic-interpreter-lexer.lpp | 1 - src/warnings.hpp | 359 ++++++++++++++++---------------- tools/indenter | 403 +++++++++++++++++++++++++++++++++--- 4 files changed, 557 insertions(+), 212 deletions(-) diff --git a/src/login/login.cpp b/src/login/login.cpp index bd466e1..6ba09d2 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -534,7 +534,7 @@ bool extract(XString line, AuthData *ad) static int mmo_auth_init(void) { - int GM_count = 0; + int gm_count = 0; io::ReadFile in(account_filename); if (!in.is_open()) @@ -570,14 +570,14 @@ int mmo_auth_init(void) auth_data.push_back(ad); if (isGM(ad.account_id) > 0) - GM_count++; + gm_count++; if (ad.account_id >= account_id_count) account_id_count = ad.account_id + 1; } FString str = STRPRINTF("%s has %zu accounts (%d GMs)\n", - account_filename, auth_data.size(), GM_count); + account_filename, auth_data.size(), gm_count); PRINTF("%s: %s\n", __PRETTY_FUNCTION__, str); LOGIN_LOG("%s\n", line); diff --git a/src/map/magic-interpreter-lexer.lpp b/src/map/magic-interpreter-lexer.lpp index cef1121..83cb36f 100644 --- a/src/map/magic-interpreter-lexer.lpp +++ b/src/map/magic-interpreter-lexer.lpp @@ -12,7 +12,6 @@ #define FIXLOC magic_frontend_lloc.first_line = magic_frontend_lineno #define HEADING(dir) { magic_frontend_lval.i = dir; FIXLOC; return DIR; } - %} %option yylineno diff --git a/src/warnings.hpp b/src/warnings.hpp index 9932ce3..61482bf 100644 --- a/src/warnings.hpp +++ b/src/warnings.hpp @@ -56,12 +56,13 @@ // BEGIN Macros to make my life easier // stringification requirement - #sw within #ar +// this is a lie ^ #define P(ar) _Pragma(#ar) // Use "GCC diagnostic" for warnings applicable to all versions. -#define I(sw) P(GCC diagnostic ignored #sw) -#define W(sw) P(GCC diagnostic warning #sw) -#define E(sw) P(GCC diagnostic error #sw) +#define I(sw) P(GCC diagnostic ignored sw) +#define W(sw) P(GCC diagnostic warning sw) +#define E(sw) P(GCC diagnostic error sw) // configurable thing (also change in clang below!) #define X(sw) I(sw) @@ -69,26 +70,26 @@ #ifdef __clang__ // Use "clang diagnostic" for warnings specific to clang -# define IC(sw) P(clang diagnostic ignored #sw) -# define WC(sw) P(clang diagnostic warning #sw) -# define EC(sw) P(clang diagnostic error #sw) +# define IC(sw) P(clang diagnostic ignored sw) +# define WC(sw) P(clang diagnostic warning sw) +# define EC(sw) P(clang diagnostic error sw) # define XC(sw) IC(sw) // this is below // warning specific to gcc -# define IG(sw) static_assert('I', #sw "skipped for clang"); -# define WG(sw) static_assert('W', #sw "skipped for clang"); -# define EG(sw) static_assert('E', #sw "skipped for clang"); -# define XG(sw) static_assert('X', #sw "skipped for clang"); +# define IG(sw) static_assert('I', sw "skipped for clang"); +# define WG(sw) static_assert('W', sw "skipped for clang"); +# define EG(sw) static_assert('E', sw "skipped for clang"); +# define XG(sw) static_assert('X', sw "skipped for clang"); -# define IG47(sw) static_assert('I', #sw "only for gcc 4.7+"); -# define WG47(sw) static_assert('W', #sw "only for gcc 4.7+"); -# define EG47(sw) static_assert('E', #sw "only for gcc 4.7+"); -# define XG47(sw) static_assert('X', #sw "only for gcc 4.7+"); +# define IG47(sw) static_assert('I', sw "only for gcc 4.7+"); +# define WG47(sw) static_assert('W', sw "only for gcc 4.7+"); +# define EG47(sw) static_assert('E', sw "only for gcc 4.7+"); +# define XG47(sw) static_assert('X', sw "only for gcc 4.7+"); -# define IG48(sw) static_assert('I', #sw "only for gcc 4.8+"); -# define WG48(sw) static_assert('W', #sw "only for gcc 4.8+"); -# define EG48(sw) static_assert('E', #sw "only for gcc 4.8+"); -# define XG48(sw) static_assert('X', #sw "only for gcc 4.8+"); +# define IG48(sw) static_assert('I', sw "only for gcc 4.8+"); +# define WG48(sw) static_assert('W', sw "only for gcc 4.8+"); +# define EG48(sw) static_assert('E', sw "only for gcc 4.8+"); +# define XG48(sw) static_assert('X', sw "only for gcc 4.8+"); # define I47(sw) I(sw) # define W47(sw) W(sw) @@ -103,10 +104,10 @@ #else // warnings specific to clang -# define IC(sw) static_assert('I', #sw "skipped for gcc"); -# define WC(sw) static_assert('W', #sw "skipped for gcc"); -# define EC(sw) static_assert('E', #sw "skipped for gcc"); -# define XC(sw) static_assert('X', #sw "skipped for gcc"); +# define IC(sw) static_assert('I', sw "skipped for gcc"); +# define WC(sw) static_assert('W', sw "skipped for gcc"); +# define EC(sw) static_assert('E', sw "skipped for gcc"); +# define XC(sw) static_assert('X', sw "skipped for gcc"); // warnings specific to gcc # define IG(sw) I(sw) @@ -128,15 +129,15 @@ # define E47(sw) E(sw) # define X47(sw) X(sw) # else -# define IG47(sw) static_assert('I', #sw "only for gcc 4.7+"); -# define WG47(sw) static_assert('W', #sw "only for gcc 4.7+"); -# define EG47(sw) static_assert('E', #sw "only for gcc 4.7+"); -# define XG47(sw) static_assert('X', #sw "only for gcc 4.7+"); - -# define I47(sw) static_assert('I', #sw "only for gcc 4.7+ or clang"); -# define W47(sw) static_assert('W', #sw "only for gcc 4.7+ or clang"); -# define E47(sw) static_assert('E', #sw "only for gcc 4.7+ or clang"); -# define X47(sw) static_assert('X', #sw "only for gcc 4.7+ or clang"); +# define IG47(sw) static_assert('I', sw "only for gcc 4.7+"); +# define WG47(sw) static_assert('W', sw "only for gcc 4.7+"); +# define EG47(sw) static_assert('E', sw "only for gcc 4.7+"); +# define XG47(sw) static_assert('X', sw "only for gcc 4.7+"); + +# define I47(sw) static_assert('I', sw "only for gcc 4.7+ or clang"); +# define W47(sw) static_assert('W', sw "only for gcc 4.7+ or clang"); +# define E47(sw) static_assert('E', sw "only for gcc 4.7+ or clang"); +# define X47(sw) static_assert('X', sw "only for gcc 4.7+ or clang"); # endif // __GNUC_MINOR__ # if __GNUC_MINOR__ >= 8 # define IG48(sw) IG(sw) @@ -149,15 +150,15 @@ # define E48(sw) EG(sw) # define X48(sw) XG(sw) # else -# define IG48(sw) static_assert('I', #sw "only for gcc 4.8+"); -# define WG48(sw) static_assert('W', #sw "only for gcc 4.8+"); -# define EG48(sw) static_assert('E', #sw "only for gcc 4.8+"); -# define XG48(sw) static_assert('X', #sw "only for gcc 4.8+"); - -# define I48(sw) static_assert('I', #sw "only for gcc 4.8+ or clang"); -# define W48(sw) static_assert('W', #sw "only for gcc 4.8+ or clang"); -# define E48(sw) static_assert('E', #sw "only for gcc 4.8+ or clang"); -# define X48(sw) static_assert('X', #sw "only for gcc 4.8+ or clang"); +# define IG48(sw) static_assert('I', sw "only for gcc 4.8+"); +# define WG48(sw) static_assert('W', sw "only for gcc 4.8+"); +# define EG48(sw) static_assert('E', sw "only for gcc 4.8+"); +# define XG48(sw) static_assert('X', sw "only for gcc 4.8+"); + +# define I48(sw) static_assert('I', sw "only for gcc 4.8+ or clang"); +# define W48(sw) static_assert('W', sw "only for gcc 4.8+ or clang"); +# define E48(sw) static_assert('E', sw "only for gcc 4.8+ or clang"); +# define X48(sw) static_assert('X', sw "only for gcc 4.8+ or clang"); # endif // __GNUC_MINOR__ # endif // __GNUC__ #endif // __clang__ @@ -168,56 +169,56 @@ /// Warn about things that will change when compiling /// with an ABI-compliant compiler // see note about -fabi-version=6 in the makefile -E(-Wabi) +E("-Wabi") /// Warn if a subobject has an abi_tag attribute that /// the complete object type does not have -WG48(-Wabi-tag) +WG48("-Wabi-tag") /// Warn about suspicious uses of memory addresses -E(-Waddress) +E("-Waddress") /// Warn about returning structures, unions or arrays -I(-Waggregate-return) +I("-Waggregate-return") /// Warn if an array is accessed out of bounds -E(-Warray-bounds) +E("-Warray-bounds") /// Warn about inappropriate attribute usage -E(-Wattributes) +E("-Wattributes") /// Warn when a built-in preprocessor macro is // undefined or redefined -E(-Wbuiltin-macro-redefined) +E("-Wbuiltin-macro-redefined") /// Warn about C++ constructs whose meaning differs /// between ISO C++ 1998 and ISO C++ 2011 // This has gone funky lately. It probably doesn't do anything useful anyway. -//E(-Wc++0x-compat) -//W(-Wc++11-compat) -I(-Wc++0x-compat) +//E("-Wc++0x-compat") +//W("-Wc++11-compat") +I("-Wc++0x-compat") /// Warn about pointer casts which increase alignment -X(-Wcast-align) +X("-Wcast-align") /// Warn about casts which discard qualifiers -E(-Wcast-qual) +E("-Wcast-qual") /// Warn about subscripts whose type is "char" -E(-Wchar-subscripts) +E("-Wchar-subscripts") /// Warn about variables that might be changed by /// "longjmp" or "vfork" -EG(-Wclobbered) +EG("-Wclobbered") /// Warn about possibly nested block comments, and /// C++ comments spanning more than one physical line -E(-Wcomment) +E("-Wcomment") // A fixable difference between c++11 and c++14 #ifdef __clang__ # if __has_warning("-Wconstexpr-not-const") -EC(-Wconstexpr-not-const) +EC("-Wconstexpr-not-const") # else static_assert('E', "-Wconstexpr-not-const not in this clang version"); # endif @@ -227,434 +228,434 @@ static_assert('E', "-Wconstexpr-not-const not in GCC"); /// Warn for implicit type conversions that may /// change a value -X(-Wconversion) +X("-Wconversion") /// Warn for converting NULL from/to a non-pointer /// type -E(-Wconversion-null) +E("-Wconversion-null") /// Warn in case profiles in -fprofile-use do not /// match -WG(-Wcoverage-mismatch) +WG("-Wcoverage-mismatch") /// -XC(-Wcovered-switch-default) +XC("-Wcovered-switch-default") /// Warn when a #warning directive is encountered -WG(-Wcpp) +WG("-Wcpp") /// Warn when all constructors and destructors are /// private -E(-Wctor-dtor-privacy) +E("-Wctor-dtor-privacy") /// Warn about deleting polymorphic objects with non- /// virtual destructors -E47(-Wdelete-non-virtual-dtor) +E47("-Wdelete-non-virtual-dtor") /// Warn if a deprecated compiler feature, class, /// method, or field is used -W(-Wdeprecated) +W("-Wdeprecated") -/// Warn about uses of __attribute__((deprecated)) +/// Warn about uses of __attribute__((deprecated)") /// declarations -W(-Wdeprecated-declarations) +W("-Wdeprecated-declarations") #ifdef QUIET -I(-Wdeprecated-declarations) +I("-Wdeprecated-declarations") #endif /// Warn when an optimization pass is disabled -W(-Wdisabled-optimization) +W("-Wdisabled-optimization") /// Warn about compile-time integer division by zero -E(-Wdiv-by-zero) +E("-Wdiv-by-zero") /// -WC(-Wdocumentation) +WC("-Wdocumentation") /// Warn about implicit conversions from "float" to /// "double" -IG(-Wdouble-promotion) +IG("-Wdouble-promotion") /// Warn about violations of Effective C++ style rules -I(-Weffc++) +I("-Weffc++") /// Warn about an empty body in an if or else /// statement -E(-Wempty-body) +E("-Wempty-body") /// Warn about stray tokens after #elif and #endif -E(-Wendif-labels) +E("-Wendif-labels") /// Warn about comparison of different enum types -E(-Wenum-compare) +E("-Wenum-compare") /// -EC(-Wextra-semi) +EC("-Wextra-semi") /// Warn if testing floating point numbers for /// equality -E(-Wfloat-equal) +E("-Wfloat-equal") /// Warn about printf/scanf/strftime/strfmon format /// string anomalies // see below -EG(-Wformat) +EG("-Wformat") // but gcc 4.8 warns on %ms, since we enabled -Wpedantic. -//WG48(-Wformat) +//WG48("-Wformat") /// Warn about format strings that contain NUL bytes -EG(-Wformat-contains-nul) +EG("-Wformat-contains-nul") /// Warn if passing too many arguments to a function /// for its format string -E(-Wformat-extra-args) +E("-Wformat-extra-args") /// Warn about format strings that are not literals -EG(-Wformat-nonliteral) +EG("-Wformat-nonliteral") // Available in clang, but not smart enough to handle constexpr. -IC(-Wformat-nonliteral) +IC("-Wformat-nonliteral") /// Warn about possible security problems with format /// functions -EG(-Wformat-security) +EG("-Wformat-security") // Same. -IC(-Wformat-security) +IC("-Wformat-security") /// Warn about strftime formats yielding 2-digit years -E(-Wformat-y2k) +E("-Wformat-y2k") /// Warn about zero-length formats -I(-Wformat-zero-length) +I("-Wformat-zero-length") /// Warn when attempting to free a non-heap object -EG47(-Wfree-nonheap-object) +EG47("-Wfree-nonheap-object") // -Wgnu is a clang alias for -Wpedantic /// Warn whenever type qualifiers are ignored. -E(-Wignored-qualifiers) +E("-Wignored-qualifiers") /// -EC(-Wimplicit-fallthrough) +EC("-Wimplicit-fallthrough") /// Warn about C++11 inheriting constructors when the /// base has a variadic constructor -WG48(-Winherited-variadic-ctor) +WG48("-Winherited-variadic-ctor") /// Warn about variables which are initialized to /// themselves -E(-Winit-self) +E("-Winit-self") /// Warn when an inlined function cannot be inlined -X(-Winline) +X("-Winline") /// Warn when there is a cast to a pointer from an /// integer of a different size -E(-Wint-to-pointer-cast) +E("-Wint-to-pointer-cast") /// Warn when an atomic memory model parameter is /// known to be outside the valid range. -WG47(-Winvalid-memory-model) +WG47("-Winvalid-memory-model") /// Warn about invalid uses of the "offsetof" macro -E(-Winvalid-offsetof) +E("-Winvalid-offsetof") /// Warn about PCH files that are found but not used -E(-Winvalid-pch) +E("-Winvalid-pch") /// Warn when a string or character literal is /// followed by a ud-suffix which does not begin with /// an underscore. -WG48(-Wliteral-suffix) +WG48("-Wliteral-suffix") /// Warn when a logical operator is suspiciously /// always evaluating to true or false -WG(-Wlogical-op) +WG("-Wlogical-op") /// Do not warn about using "long long" when -pedantic -I(-Wlong-long) +I("-Wlong-long") /// Warn about suspicious declarations of "main" -E(-Wmain) +E("-Wmain") /// Warn about maybe uninitialized automatic variables -EG47(-Wmaybe-uninitialized) +EG47("-Wmaybe-uninitialized") /// Warn about possibly missing braces around /// initializers // beware of things like std::array! -E(-Wmissing-braces) +E("-Wmissing-braces") /// Warn about global functions without previous /// declarations // This doesn't work for clang, it wants -Wmissing-prototypes instead. -E(-Wmissing-declarations) +E("-Wmissing-declarations") /// Warn about missing fields in struct initializers // Actually supported by GCC, but gives warnings when I don't want, e.g.: // Foo foo = {}; -EC(-Wmissing-field-initializers) -IG(-Wmissing-field-initializers) +EC("-Wmissing-field-initializers") +IG("-Wmissing-field-initializers") /// Warn about functions which might be candidates /// for format attributes -E(-Wmissing-format-attribute) +E("-Wmissing-format-attribute") /// Warn about user-specified include directories /// that do not exist -E(-Wmissing-include-dirs) +E("-Wmissing-include-dirs") /// Warn about functions which might be candidates -/// for __attribute__((noreturn)) -W(-Wmissing-noreturn) +/// for __attribute__((noreturn)") +W("-Wmissing-noreturn") // clang uses this instead of -Wmissing-declarations -EC(-Wmissing-prototypes) +EC("-Wmissing-prototypes") /// // like -Wmissing-declarations but for variables instead of functions #ifndef GTEST_HAS_PTHREAD // this is a hack -EC(-Wmissing-variable-declarations) +EC("-Wmissing-variable-declarations") #endif /// Warn about constructs not instrumented by /// -fmudflap -EG(-Wmudflap) +EG("-Wmudflap") /// Warn about use of multi-character character /// constants -E(-Wmultichar) +E("-Wmultichar") /// Warn about narrowing conversions within { } that /// are ill-formed in C++11 -EG47(-Wnarrowing) +EG47("-Wnarrowing") /// Warn when a noexcept expression evaluates to /// false even though the expression can't actually /// throw -WG(-Wnoexcept) +WG("-Wnoexcept") /// Warn when non-templatized friend functions are /// declared within a template -EG(-Wnon-template-friend) +EG("-Wnon-template-friend") /// Warn about non-virtual destructors -E(-Wnon-virtual-dtor) +E("-Wnon-virtual-dtor") /// Warn about NULL being passed to argument slots /// marked as requiring non-NULL -E(-Wnonnull) +E("-Wnonnull") /// -XC(-Wnull-conversion) +XC("-Wnull-conversion") /// Warn if a C-style cast is used in a program -E(-Wold-style-cast) +E("-Wold-style-cast") /// Warn about overflow in arithmetic expressions -W(-Woverflow) +W("-Woverflow") /// Warn if a string is longer than the maximum /// portable length specified by the standard -//X(-Woverlength-strings) +//X("-Woverlength-strings") /// Warn about overloaded virtual function names -E(-Woverloaded-virtual) +E("-Woverloaded-virtual") /// Warn when the packed attribute has no effect on /// struct layout -E(-Wpacked) +E("-Wpacked") /// Warn about packed bit-fields whose offset changed /// in GCC 4.4 -WG(-Wpacked-bitfield-compat) +WG("-Wpacked-bitfield-compat") /// Warn when padding is required to align structure /// members -I(-Wpadded) +I("-Wpadded") /// Warn about possibly missing parentheses -E(-Wparentheses) +E("-Wparentheses") /// Issue warnings needed for strict compliance to /// the standard -//EG48(-Wpedantic) +//EG48("-Wpedantic") // lots of minor extensions are used -IG48(-Wpedantic) +IG48("-Wpedantic") // a bit too noisy -XC(-Wpedantic) +XC("-Wpedantic") /// Warn when converting the type of pointers to /// member functions -EG(-Wpmf-conversions) +EG("-Wpmf-conversions") /// Warn about function pointer arithmetic -E(-Wpointer-arith) +E("-Wpointer-arith") /// Warn about misuses of pragmas -EG(-Wpragmas) +EG("-Wpragmas") /// Warn about multiple declarations of the same /// object -W(-Wredundant-decls) +W("-Wredundant-decls") /// Warn when the compiler reorders code -E(-Wreorder) +E("-Wreorder") /// Warn about returning a pointer/reference to a /// local or temporary variable. -WG48(-Wreturn-local-addr) +WG48("-Wreturn-local-addr") /// Warn whenever a function's return type defaults /// to "int" (C), or about inconsistent return types -/// (C++) -E(-Wreturn-type) +/// (C++") +E("-Wreturn-type") /// Warn about possible violations of sequence point /// rules -E(-Wsequence-point) +E("-Wsequence-point") /// Warn when one local variable shadows another -E(-Wshadow) +E("-Wshadow") /// Warn about signed-unsigned comparisons -X(-Wsign-compare) +X("-Wsign-compare") /// Warn when overload promotes from unsigned to /// signed -X(-Wsign-promo) +X("-Wsign-promo") /// This switch lacks documentation -WG48(-Wsizeof-pointer-memaccess) +WG48("-Wsizeof-pointer-memaccess") /// Warn when not issuing stack smashing protection /// for some reason -X(-Wstack-protector) +X("-Wstack-protector") /// Warn about code which might break strict aliasing /// rules -E(-Wstrict-aliasing) +E("-Wstrict-aliasing") /// Warn about uncasted NULL used as sentinel -WG(-Wstrict-null-sentinel) +WG("-Wstrict-null-sentinel") /// Warn about optimizations that assume that signed /// overflow is undefined -X(-Wstrict-overflow) +X("-Wstrict-overflow") /// Warn about enumerated switches, with no default, /// missing a case -X(-Wswitch) +X("-Wswitch") /// Warn about enumerated switches missing a /// "default:" statement -X(-Wswitch-default) +X("-Wswitch-default") /// Warn about all enumerated switches missing a /// specific case -X(-Wswitch-enum) +X("-Wswitch-enum") /// Warn when __sync_fetch_and_nand and /// __sync_nand_and_fetch built-in functions are used -WG(-Wsync-nand) +WG("-Wsync-nand") /// Warn whenever a trampoline is generated -EG(-Wtrampolines) +EG("-Wtrampolines") /// Warn if trigraphs are encountered that might /// affect the meaning of the program -E(-Wtrigraphs) +E("-Wtrigraphs") /// Warn if a comparison is always true or always /// false due to the limited range of the data type -E(-Wtype-limits) +E("-Wtype-limits") /// Warn if an undefined macro is used in an #if /// directive -E(-Wundef) +E("-Wundef") /// Warn about uninitialized automatic variables -E(-Wuninitialized) +E("-Wuninitialized") /// Warn about unrecognized pragmas -E(-Wunknown-pragmas) +E("-Wunknown-pragmas") /// // Not an error because of some remaining enum+default -WC(-Wunreachable-code) +WC("-Wunreachable-code") /// Warn if the loop cannot be optimized due to /// nontrivial assumptions. -XG(-Wunsafe-loop-optimizations) +XG("-Wunsafe-loop-optimizations") /// Warn when a function parameter is only set, /// otherwise unused -EG(-Wunused-but-set-parameter) +EG("-Wunused-but-set-parameter") /// Warn when a variable is only set, otherwise unused -EG(-Wunused-but-set-variable) +EG("-Wunused-but-set-variable") /// Warn when a function is unused -E(-Wunused-function) +E("-Wunused-function") /// Warn when a label is unused -E(-Wunused-label) +E("-Wunused-label") /// Warn when typedefs locally defined in a function /// are not used -EG47(-Wunused-local-typedefs) +EG47("-Wunused-local-typedefs") /// Warn about macros defined in the main file that /// are not used -W(-Wunused-macros) +W("-Wunused-macros") /// Warn when a function parameter is unused -E(-Wunused-parameter) +E("-Wunused-parameter") /// Warn if a caller of a function, marked with /// attribute warn_unused_result, does not use its /// return value -E(-Wunused-result) +E("-Wunused-result") /// Warn when an expression value is unused -E(-Wunused-value) +E("-Wunused-value") /// Warn when a variable is unused -E(-Wunused-variable) +E("-Wunused-variable") /// Warn about useless casts -EG48(-Wuseless-cast) +EG48("-Wuseless-cast") /// Warn about questionable usage of the macros used /// to retrieve variable arguments -EG48(-Wvarargs) +EG48("-Wvarargs") /// Warn about using variadic macros -W(-Wvariadic-macros) +W("-Wvariadic-macros") /// Warn when a vector operation is compiled /// outside the SIMD -WG47(-Wvector-operation-performance) +WG47("-Wvector-operation-performance") /// Warn if a virtual base has a non-trivial move /// assignment operator -EG48(-Wvirtual-move-assign) +EG48("-Wvirtual-move-assign") /// Warn if a variable length array is used -I(-Wvla) +I("-Wvla") /// Warn when a register variable is declared volatile -E(-Wvolatile-register-var) +E("-Wvolatile-register-var") /// In C++, nonzero means warn about deprecated /// conversion from string literals to 'char *'. In /// C, similar warning, except that the conversion is /// of course not deprecated by the ISO C standard. -E(-Wwrite-strings) +E("-Wwrite-strings") /// Warn when a literal '0' is used as null /// pointer -XG47(-Wzero-as-null-pointer-constant) +XG47("-Wzero-as-null-pointer-constant") // clean up after myself diff --git a/tools/indenter b/tools/indenter index 0f0f31d..0d93543 100755 --- a/tools/indenter +++ b/tools/indenter @@ -59,11 +59,15 @@ if 1: self._diagnostic('warning', msg, to) def note(self, msg, to=None): self._diagnostic('note', msg, to) + def fatal(self, msg, to=None): + self.error(msg, to) + sys.exit(1) Location._diagnostic = _diagnostic Location.error = error Location.warning = warning Location.note = note - del _diagnostic, error, warning, note + Location.fatal = fatal + del _diagnostic, error, warning, note, fatal class Reader(object): @@ -144,10 +148,10 @@ def take_slc(b, r): while True: c = r.get() # if c == '\n': return - r.adv() - b += c if c == '\n' and not bs: return + r.adv() + b += c bs = c == '\\' def take_char(b, r): @@ -214,7 +218,7 @@ def format_lex_or_yacc_definitions(): 'definitions section (mostly used for options actually)' table = Table() in_code = False - code = bytearray() + code = '' for line in sys.stdin: if line == '%%\n': break @@ -241,7 +245,7 @@ def format_lex_or_yacc_definitions(): table.put1('') elif code: table.put1('') - code = bytearray() + code = '' if line.startswith('%'): # %top is flex, %code and %union are bison @@ -249,7 +253,7 @@ def format_lex_or_yacc_definitions(): if union or line.startswith('%top') or line.startswith('%code'): # TODO fix stupidity when in strings or comments count = line.count('{') - #code = bytearray() + #code = '' if union: assert count <= 1 code += line[1:] @@ -277,7 +281,7 @@ def format_lex_or_yacc_definitions(): else: for line2 in indent_cpp_slop(code): table.put1(LexSettings.nested_indent * ' ' + line2) - code = bytearray() + code = '' else: table.put1(line) elif line[0].isalpha() or line[0] == '_': @@ -337,7 +341,7 @@ def format_lex_rules(): del bs del p pattern = line[:i] - rule = bytearray(line[i:]) + rule = line[i:] del i count = rule.count('{') - rule.count('}') while count: @@ -410,7 +414,7 @@ def format_yacc_rules(): continue if line.startswith('{'): line += '\n' - lines = bytearray() + lines = '' # TODO fix braces in comments and strings lo = 1 behold = 1 @@ -547,7 +551,12 @@ def format_cc(): sys.exit(tail.wait()) def indent_cpp_slop(code): - return subprocess.Popen(['indenter-cpp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE).communicate(code)[0].strip().split('\n') + proc = subprocess.Popen(['indenter-cpp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) + rv = proc.communicate(code)[0].strip().split('\n') + prv = proc.wait() + if prv: + sys.exit(prv) + return rv operators = { '#', '##', @@ -578,6 +587,21 @@ operators = { k: {v[len(k):] for v in operators if v is not k and v.startswith(k)} for k in operators } +# *please* don't use any of these except and, or, and not +operator_map = { + 'and': '&&', + 'and_eq': '&=', + 'bitand': '&', + 'bitor': '|', + 'compl': '~', + 'not': '!', + 'not_eq': '!=', + 'or': '||', + 'or_eq': '|=', + 'xor': '^', + 'xor_eq': '^=', +} + num1 = string.digits num_x = num1 + '.\'' @@ -585,7 +609,7 @@ ident1 = string.ascii_letters + '_$@' # $@ for bison ident_x = ident1 + string.digits class CxxLexer(object): - __slots__ = ('_reader', '_w', '_t', '_f', '_namespaces', '_classes') + __slots__ = ('_reader', '_w', '_t', '_l', '_namespaces', '_classes') def __init__(self, reader): self._reader = reader @@ -593,11 +617,11 @@ class CxxLexer(object): self._namespaces = [] self._classes = [] - def get(self): - return self._w, self._t, self._f + def get2(self): + return self._w, self._t, self._l def adv(self): - self._w, self._t, self._f = self.pull() + self._w, self._t, self._l = self.pull() def pull(self): r = self._reader @@ -606,11 +630,12 @@ class CxxLexer(object): while True: c = r.get() if not c: - return '\n', None, None + return '\n', None, r.loc() if not c.isspace(): break white += c r.adv() + white = str(white) black = bytearray() black += c @@ -652,32 +677,352 @@ class CxxLexer(object): else: l.error('Unknown character: %r' % c) sys.exit(1) + black = str(black) + + return white, black, l + + +class Flavored(object): + __slots__ = ('_str') + + def __init__(self, s): + self._str = s + +class Control(Flavored): + __slots__ = () + +class Binary(Flavored): + __slots__ = () + +class Unary(Flavored): + __slots__ = () + +class Postfix(Flavored): + __slots__ = () + +class Type(Flavored): + __slots__ = () + +class Value(Flavored): + __slots__ = () + +class Literal(Value): + __slots__ = () + +class TypeExpr(Flavored): + __slots__ = () + +class Attr(Flavored): + __slots__ = () + +class Def(Flavored): + __slots__ = () + +class MatchHead(Flavored): + __slots__ = ('_tail_char', '_purpose') + def __init__(self, s, t, p): + Flavored.__init__(self, s) + assert isinstance(t, str) + self._tail_char = t + self._purpose = p + +class MatchTail(Flavored): + __slots__ = ('_head_obj') + def __init__(self, s, head): + Flavored.__init__(self, s) + assert isinstance(head, MatchHead) + self._head_obj = head + @property + def _purpose(self): + return self._head_obj._purpose + +class MatchTail2(Flavored): + __slots__ = ('_head_inner', '_head_outer') + def __init__(self, s, head_inner, head_outer): + Flavored.__init__(self, s) + assert isinstance(head_inner, MatchHead) + assert isinstance(head_outer, MatchHead) + self._head_inner = head_inner + self._head_outer = head_outer + + @property + def _purpose(self): + return self._head_outer._purpose + + +class CxxFormatter(object): + __slots__ = ('_lexer', '_w', '_t', '_types', '_values', '_type_expressions', '_scopes') + + def __init__(self, lexer): + assert isinstance(lexer, CxxLexer) + self._lexer = lexer + self._w = None + self._t = None + self._scopes = [] + + self._types = { + 'auto', + 'bool', + 'char', + 'char16_t', + 'char32_t', + 'double', + 'float', + 'int', + 'long', + 'short', + 'signed', + 'unsigned', + 'void', + 'wchar_t', + } + self._values = { + 'alignof', + 'const_cast', + 'dynamic_cast', + 'false', + 'nullptr', + 'reinterpret_cast', + 'sizeof', + 'static_cast', + 'this', + 'typeid', + 'true', + } + self._type_expressions = { + 'decltype', + } - # c is the first char of the next thing - return white, black, None + # the following two functions should *generally* not access self + # but they do need to a bit + def flavor2(self, w, t, l): + ''' Given the next token and its whitespace, calculate the flavor. -def whitespace(w, (t, f), (pt, pf)): - return w + Note: the need to know the preceding whitespace is a hack + (but a pretty good one!) + + self.w, self.t, and self.f still contain the previous token. + ''' + if t.startswith('//') or t.startswith('/*') or (t.startswith('#') and len(t) > 2): + return None + if t[0] in num1 or t[0] == '\'': + return Literal(t) + if '"' in t: + if self._t and self._t._str == 'extern': + # extern "C" + return Attr(t) + return Literal(t) + o = operator_map.get(t, t) + + if o in { + '#', + '!', + '~', + }: + return Unary(t) + if o in { + '##', + '+=', + '-=', + '->', + '->*', + '*=', + '/', + '/=', + '%', + '%=', + '=', + '==', + '!=', + '|', + '||', + '|=', + '&=', + '^', + '^=', + '<=', + '<<', + '<<=', + '>=', + '>>=', + '.', + '..', + '.*', + '::', + }: + return Binary(t) + if o == '<': + if w: + return Binary(t) + u = {'<': '>', '(': ')', '{': '}', '[': ']'}.get(o) + if u is not None: + rv = MatchHead(t, u, None) # fix this, it is CRITICAL + self._scopes.append(rv) + return rv + if o == '>' or o == '>>': + if not self._scopes or self._scopes[-1]._str != '<': + return Binary(t) + if o == '>>': + assert len(self._scopes) >= 2 + assert self._scopes[-1]._str == '<' + assert self._scopes[-2]._str == '<' + return MatchTail2(t, self._scopes.pop(), self._scopes.pop()) + if o in {'>', ')', '}', ']'}: + if not self._scopes: + l.fatal('Unexpected %r' % t) + if self._scopes[-1]._tail_char != t: + l.fatal('Expected %r, got %r' % (self._scopes[-1]._tail_char, t)) + return MatchTail(t, self._scopes.pop()) + if o == '...': + return Postfix(t) + if o in {'*', '&', '&&'}: + if isinstance(self._t, Type): + return Type(t) + if o in {'+', '-', '*', '&', '&&'}: + # && is a gcc extension for address-of-a-label + if isinstance(self._t, (Unary, Binary, Control, MatchHead)): + return Unary(t) + elif isinstance(self._t, (Value, Postfix, MatchTail, MatchTail2)): + return Binary(t) + else: + l.fatal('Not sure how to handle ambiguous unary/binary after instance of %r' % self._t.__class__.__name__) + if o in {'--', '++'}: + if isinstance(self._t, (Unary, Binary, Control, MatchHead)): + return Unary(t) + elif isinstance(self._t, (Value, Postfix, MatchTail, MatchTail2)): + return Postfix(t) + else: + l.fatal('Not sure how to handle ambiguous prefix/postfix after instance of %r' % self._t.__class__.__name__) + if o in {',', ';'}: + return Binary(t) + if o == '?': + return Binary(t) + if o == ':': + return Binary(t) + + assert t == o + assert t[0] in ident1 + assert all(c in ident_x for c in t[1:]) + + # keywords! + if t == '__attribute__': + return Attr(t) + if t in { + 'alignas', + 'constexpr', + 'explicit', + 'export', + 'extern', + 'friend', + 'inline', + 'mutable', + 'register', + 'static', + 'thread_local', + 'virtual', + }: + return Attr(t) + if t in { + 'const', + 'volatile', + }: + if self._t is None or isinstance(self._t, (Attr, Binary, MatchTail, MatchTail2)): # ; is binary + return Attr(t) + if isinstance(self._t, Def): + # trailing function + return Attr(t) + return Type(t) + if t in {'final', 'override'}: + # theoretically, should only do this for thingy + return Attr(t) + if t == 'noexcept': + if isinstance(self._t, (Attr, MatchTail, MatchTail2)): + return Attr(t) + else: + return Value(t) + if t == 'asm': + return Value(t) + if t in {'delete', 'default'} and isinstance(self._t, Binary): # = delete + return Value(t) + if t in {'new', 'delete'}: + return Unary(t) + if t in {'case', 'goto', 'return', 'throw'}: + return Unary(t) + if t in {'default', 'public', 'private', 'protected'}: + return Value(t) + if t in {'break', 'continue'}: + return Value(t) + if t in {'try', 'catch', 'do', 'else', 'for', 'if', 'switch', 'while'}: + return Control(t) + if t in {'class', 'enum', 'struct', 'typename', 'union'}: + return Def(t) + if t == 'static_assert': + return Value(t) + if t == 'operator': + return Value(t) + if t == 'namespace': + return Def(t) + if t == 'template': + return Def(t) + if t == 'typedef': + return Def(t) + if t == 'using': + return Unary(t) + + if t in self._type_expressions: + return TypeExpr(t) + + # types, values, and keywords that act like one of those + if t in self._types: + return Type(t) + if t in self._values: + return Value(t) + u = t.replace('_', '') + if u.isupper(): + return Value(t) + if u and u[0].isupper(): + return Type(t) + return Value(t) + + def whitespace(self, pt, t): + ''' Given a token and its flavor, calculate its whitespace. + ''' + w = self._w # TODO set to '' instead to force calculation + for func in [ + ]: + w = func(w, pt, t) + return w def format_ii(): r = Reader('', sys.stdin) l = CxxLexer(r) - pt = None - pf = None + f = CxxFormatter(l) while True: - w, t, f = l.get() - if not t: + wspace, raw_tok, loc = l.get2() + assert isinstance(wspace, str) + if raw_tok is None: break + assert isinstance(raw_tok, str) l.adv() - w = whitespace(w, (t, f), (pt, pf)) - sys.stdout.writelines([w, t]) - #print('w:', repr(str(w))) - #print('t:', t) - pt, pf = t, f - if not pt.endswith('\n'): + prev_tok = f._t + cooked_tok = f.flavor2(wspace, raw_tok, loc) + if cooked_tok is None: + f._w = wspace # or ' ' + # f._t is unchanged + else: + f._w = wspace + f._t = cooked_tok + wspace = f.whitespace(prev_tok, cooked_tok) + + if cooked_tok is None: + sys.stdout.writelines([wspace, raw_tok]) + else: + sys.stdout.writelines([wspace, cooked_tok._str]) + if 1: sys.stdout.write('\n') + exts = { '-lpp': format_lex, '-ypp': format_yacc, -- cgit v1.2.3-70-g09d2