X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=warning.c;h=67ee728493774e291099ccb28a0c74344111cbe0;hb=refs%2Fheads%2Falias;hp=a41b56a715be289db36f4051b43f0d32ac3906e3;hpb=eac33b4424a86a7e47d72a91dddcf7c5b12d3074;p=cparser diff --git a/warning.c b/warning.c index a41b56a..67ee728 100644 --- a/warning.c +++ b/warning.c @@ -1,177 +1,195 @@ /* * This file is part of cparser. - * Copyright (C) 2007-2008 Matthias Braun - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * Copyright (C) 2012 Matthias Braun */ +#include #include #include + +#include "adt/strutil.h" +#include "adt/util.h" #include "warning.h" +#include "help.h" -warning_t warning = { - .aggregate_return = false, - .attribute = true, - .cast_qual = false, - .char_subscripts = true, - .comment = false, - .declaration_after_statement = false, - .deprecated_declarations = true, - .div_by_zero = true, - .empty_statement = false, - .fatal_errors = false, - .float_equal = false, - .format = true, - .implicit_function_declaration = true, - .implicit_int = true, - .long_long = false, - .main = true, - .missing_declarations = false, - .missing_noreturn = false, - .missing_prototypes = false, - .multichar = true, - .nested_externs = false, - .nonnull = true, - .pointer_arith = true, - .redundant_decls = true, - .return_type = true, - .s_are_errors = false, - .shadow = false, - .sign_compare = false, - .strict_prototypes = true, - .switch_default = false, - .switch_enum = false, - .unknown_pragmas = true, - .unreachable_code = false, - .unused_function = false, - .unused_label = false, - .unused_parameter = false, - .unused_value = true, - .unused_variable = false, - .write_strings = false +static warning_switch_t warning[] = { + [WARN_ADDRESS] = { WARN_STATE_ON, "address" }, + [WARN_AGGREGATE_RETURN] = { WARN_STATE_NONE, "aggregate-return" }, + [WARN_ATTRIBUTE] = { WARN_STATE_ON, "attribute" }, + [WARN_CAST_QUAL] = { WARN_STATE_NONE, "cast-qual", }, + [WARN_CHAR_SUBSCRIPTS] = { WARN_STATE_ON, "char-subscripts", }, + [WARN_COMMENT] = { WARN_STATE_NONE, "comment", }, + [WARN_CONVERSION] = { WARN_STATE_NONE, "conversion", }, + [WARN_DECLARATION_AFTER_STATEMENT] = { WARN_STATE_NONE, "declaration-after-statement", }, + [WARN_DEPRECATED_DECLARATIONS] = { WARN_STATE_ON, "deprecated-declarations", }, + [WARN_DIV_BY_ZERO] = { WARN_STATE_ON, "div-by-zero", }, + [WARN_EMPTY_BODY] = { WARN_STATE_NONE, "empty-body", }, + [WARN_EMPTY_STATEMENT] = { WARN_STATE_NONE, "empty-statement", }, + [WARN_ERROR] = { WARN_STATE_NONE, "error" }, + [WARN_FATAL_ERRORS] = { WARN_STATE_NONE, "fatal-errors" }, + [WARN_FLOAT_EQUAL] = { WARN_STATE_NONE, "float-equal", }, + [WARN_FORMAT] = { WARN_STATE_ON, "format" }, + [WARN_IGNORED_QUALIFIERS] = { WARN_STATE_ON, "ignored-qualifiers" }, + [WARN_IMPLICIT_FUNCTION_DECLARATION] = { WARN_STATE_ON, "implicit-function-declaration" }, + [WARN_IMPLICIT_INT] = { WARN_STATE_ON, "implicit-int" }, + [WARN_LONG_LONG] = { WARN_STATE_NONE, "long-long" }, + [WARN_MAIN] = { WARN_STATE_ON, "main", }, + [WARN_MISSING_DECLARATIONS] = { WARN_STATE_NONE, "missing-declarations", }, + [WARN_MISSING_NORETURN] = { WARN_STATE_NONE, "missing-noreturn", }, + [WARN_MISSING_PROTOTYPES] = { WARN_STATE_NONE, "missing-prototypes", }, + [WARN_MULTICHAR] = { WARN_STATE_ON, "multichar", }, + [WARN_NESTED_EXTERNS] = { WARN_STATE_NONE, "nested-externs" }, + [WARN_NONNULL] = { WARN_STATE_ON, "nonnull", }, + [WARN_OLD_STYLE_DEFINITION] = { WARN_STATE_NONE, "old-style-definition", }, + [WARN_OTHER] = { WARN_STATE_ON, "other" }, + [WARN_PACKED] = { WARN_STATE_NONE, "packed", }, + [WARN_PADDED] = { WARN_STATE_NONE, "padded", }, + [WARN_PARENTHESES] = { WARN_STATE_NONE, "parentheses", }, + [WARN_POINTER_ARITH] = { WARN_STATE_ON, "pointer-arith", }, + [WARN_REDUNDANT_DECLS] = { WARN_STATE_ON, "redundant-decls", }, + [WARN_RETURN_TYPE] = { WARN_STATE_ON, "return-type", }, + [WARN_SHADOW] = { WARN_STATE_NONE, "shadow", }, + [WARN_SHADOW_LOCAL] = { WARN_STATE_NONE, "shadow-local", }, + [WARN_SIGN_COMPARE] = { WARN_STATE_NONE, "sign-compare", }, + [WARN_STRAY_SEMICOLON] = { WARN_STATE_ON, "stray-semicolon", }, + [WARN_STRICT_PROTOTYPES] = { WARN_STATE_ON, "strict-prototypes" }, + [WARN_SWITCH_DEFAULT] = { WARN_STATE_NONE, "switch-default", }, + [WARN_SWITCH_ENUM] = { WARN_STATE_NONE, "switch-enum", }, + [WARN_SYSTEM] = { WARN_STATE_NONE, "system", }, + [WARN_TRADITIONAL] = { WARN_STATE_NONE, "traditional" }, + [WARN_UNINITIALIZED] = { WARN_STATE_ON, "uninitialized", }, + [WARN_UNKNOWN_PRAGMAS] = { WARN_STATE_ON, "unknown-pragmas", }, + [WARN_UNREACHABLE_CODE] = { WARN_STATE_NONE, "unreachable-code" }, + [WARN_UNUSED_FUNCTION] = { WARN_STATE_NONE, "unused-function", }, + [WARN_UNUSED_LABEL] = { WARN_STATE_NONE, "unused-label", }, + [WARN_UNUSED_PARAMETER] = { WARN_STATE_NONE, "unused-parameter", }, + [WARN_UNUSED_VALUE] = { WARN_STATE_ON, "unused-value", }, + [WARN_UNUSED_VARIABLE] = { WARN_STATE_NONE, "unused-variable", }, + [WARN_WRITE_STRINGS] = { WARN_STATE_NONE, "write-strings", }, }; +warning_switch_t const *get_warn_switch(warning_t const w) +{ + assert((size_t)w < lengthof(warning)); + assert(warning[w].name); + return &warning[w]; +} + +void print_warning_opt_help(void) +{ + /* TODO: write explanations */ + for (warning_switch_t* i = warning; i != endof(warning); ++i) { + char buf[256]; + snprintf(buf, sizeof(buf), "-W%s", i->name); + put_help(buf, ""); + } +} + void set_warning_opt(const char *const opt) { - const char* s = opt; + /* Process prefixes: -W[no-][error=] */ + char const *s = opt; + char const *rest; + bool const no = (rest = strstart(s, "no-")) ? s = rest, true : false; + bool const error = (rest = strstart(s, "error=")) ? s = rest, true : false; - bool state = true; + warn_state_t on = WARN_STATE_NONE; + warn_state_t off = WARN_STATE_NONE; + if (!no || !error) + on |= WARN_STATE_ON; + if (error) { + on |= WARN_STATE_ERROR; + off |= WARN_STATE_NO_ERROR; + } + if (no) { + warn_state_t const tmp = on; + on = off; + off = tmp; + } - /* "no-" prefix */ - if (s[0] == 'n' && s[1] == 'o' && s[2] == '-') { - s += 3; - state = false; + for (warning_switch_t* i = warning; i != endof(warning); ++i) { + if (streq(i->name, s)) { + i->state = (i->state & ~off) | on; + return; + } } - if (0) {} -#define OPTX(x) else if (strcmp(s, x) == 0) -#define SET(y) (void)(warning.y = state) -#define OPT(x, y) OPTX(x) SET(y) + if (s[0] == '\0') { // -W is an alias for -Wextra + goto extra; + } +#define OPTX(x) else if (streq(s, x)) +#define SET(y) (void)(warning[y].state = (warning[y].state & ~off) | on) OPTX("all") { - /* Note: this switched on a lot of more warnings than gcc's -Wall */ - SET(attribute); - SET(char_subscripts); - SET(comment); - SET(empty_statement); - SET(format); - SET(implicit_function_declaration); - SET(implicit_int); - SET(main); - SET(nonnull); - SET(pointer_arith); - SET(redundant_decls); - SET(return_type); - SET(shadow); - SET(sign_compare); - SET(strict_prototypes); - SET(switch_enum); - SET(unknown_pragmas); - SET(unreachable_code); - SET(unused_function); - SET(unused_label); - SET(unused_parameter); - SET(unused_value); - SET(unused_variable); + /* Note: this switched on a lot more warnings than gcc's -Wall */ + SET(WARN_ADDRESS); + SET(WARN_ATTRIBUTE); + SET(WARN_CHAR_SUBSCRIPTS); + SET(WARN_COMMENT); + SET(WARN_EMPTY_STATEMENT); + SET(WARN_FORMAT); + SET(WARN_IMPLICIT_FUNCTION_DECLARATION); + SET(WARN_IMPLICIT_INT); + SET(WARN_MAIN); + SET(WARN_MISSING_DECLARATIONS); + SET(WARN_NONNULL); + SET(WARN_OTHER); + SET(WARN_PARENTHESES); + SET(WARN_POINTER_ARITH); + SET(WARN_REDUNDANT_DECLS); + SET(WARN_RETURN_TYPE); + SET(WARN_SHADOW_LOCAL); + SET(WARN_SIGN_COMPARE); + SET(WARN_STRICT_PROTOTYPES); + SET(WARN_SWITCH_ENUM); + SET(WARN_UNINITIALIZED); + SET(WARN_UNKNOWN_PRAGMAS); + SET(WARN_UNREACHABLE_CODE); + SET(WARN_UNUSED_FUNCTION); + SET(WARN_UNUSED_LABEL); + SET(WARN_UNUSED_PARAMETER); + SET(WARN_UNUSED_VALUE); + SET(WARN_UNUSED_VARIABLE); } - OPT("aggregate-return", aggregate_return); - OPT("attribute", attribute); - OPT("cast-qual", cast_qual); - OPT("char-subscripts", char_subscripts); - OPT("comment", comment); - OPT("declaration-after-statement", declaration_after_statement); - OPT("deprecated-declarations", deprecated_declarations); - OPT("div_by_zero", div_by_zero); - OPT("empty-statement", empty_statement); - OPT("error", s_are_errors); OPTX("extra") { +extra: /* TODO */ // TODO SET(function_end_without_return); - SET(empty_statement); + SET(WARN_EMPTY_STATEMENT); // TODO SET(incomplete_aggregate_init); // TODO SET(missing_field_initializers); // TODO SET(pointless_comparison); - SET(unused_parameter); - SET(unused_value); - } - OPT("fatal-errors", fatal_errors); - OPT("float-equal", float_equal); - OPTX("format") { - SET(format); - SET(nonnull); + SET(WARN_SHADOW); + SET(WARN_UNUSED_PARAMETER); + SET(WARN_UNUSED_VALUE); } OPTX("implicit") { - SET(implicit_function_declaration); - SET(implicit_int); + SET(WARN_IMPLICIT_FUNCTION_DECLARATION); + SET(WARN_IMPLICIT_INT); } - OPT("implicit-function-declaration", implicit_function_declaration); - OPT("implicit-int", implicit_int); - OPT("long-long", long_long); - OPT("main", main); - OPT("missing-declarations", missing_declarations); - OPT("missing-noreturn", missing_noreturn); - OPT("missing-prototypes", missing_prototypes); - OPT("multichar", multichar); - OPT("nested-externs", nested_externs); - OPT("nonnull", nonnull); - OPT("pointer_arith", pointer_arith); - OPT("redundant-decls", redundant_decls); - OPT("return-type", return_type); - OPT("shadow", shadow); - OPT("sign-compare", sign_compare); - OPT("strict-prototypes", strict_prototypes); - OPT("switch-default", switch_default); - OPT("switch-enum", switch_enum); - OPT("unknown-pragmas", unknown_pragmas); - OPT("unreachable-code", unreachable_code); OPTX("unused") { - SET(unused_function); - SET(unused_label); - SET(unused_parameter); - SET(unused_value); - SET(unused_variable); + SET(WARN_UNUSED_FUNCTION); + SET(WARN_UNUSED_LABEL); + SET(WARN_UNUSED_PARAMETER); + SET(WARN_UNUSED_VALUE); + SET(WARN_UNUSED_VARIABLE); } - OPT("unused-function", unused_function); - OPT("unused-label", unused_label); - OPT("unused-parameter", unused_parameter); - OPT("unused-value", unused_value); - OPT("unused-variable", unused_variable); - OPT("write-strings", write_strings); -#undef OPT #undef SET #undef OPT_X + else if (streq(opt /* sic */, "error-implicit-function-declaration")) { + /* GCC legacy: This way it only can be activated. */ + warning[WARN_IMPLICIT_FUNCTION_DECLARATION].state = WARN_STATE_ON | WARN_STATE_ERROR; + return; + } else { fprintf(stderr, "warning: ignoring unknown option -W%s\n", opt); } } + +void disable_all_warnings(void) +{ + for (warning_switch_t* i = warning; i != endof(warning); ++i) { + if (i != &warning[WARN_ERROR] && + i != &warning[WARN_FATAL_ERRORS]) { + i->state &= ~WARN_STATE_ON; + } + } +}