X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=warning.c;h=67ee728493774e291099ccb28a0c74344111cbe0;hb=refs%2Fheads%2Falias;hp=65e39dd15636fd31944c504c72d1e9b8b3f9e2a3;hpb=bb8544d38aaa4c716603a5d565c3ff3840454ffc;p=cparser diff --git a/warning.c b/warning.c index 65e39dd..67ee728 100644 --- a/warning.c +++ b/warning.c @@ -1,81 +1,70 @@ /* * This file is part of cparser. - * Copyright (C) 2007-2009 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" static warning_switch_t warning[] = { - [WARN_ADDRESS] = { WARN_LEVEL_ON, "address" }, - [WARN_AGGREGATE_RETURN] = { WARN_LEVEL_OFF, "aggregate-return" }, - [WARN_ATTRIBUTE] = { WARN_LEVEL_ON, "attribute" }, - [WARN_CAST_QUAL] = { WARN_LEVEL_OFF, "cast-qual", }, - [WARN_CHAR_SUBSCRIPTS] = { WARN_LEVEL_ON, "char-subscripts", }, - [WARN_COMMENT] = { WARN_LEVEL_OFF, "comment", }, - [WARN_CONVERSION] = { WARN_LEVEL_OFF, "conversion", }, - [WARN_DECLARATION_AFTER_STATEMENT] = { WARN_LEVEL_OFF, "declaration-after-statement", }, - [WARN_DEPRECATED_DECLARATIONS] = { WARN_LEVEL_ON, "deprecated-declarations", }, - [WARN_DIV_BY_ZERO] = { WARN_LEVEL_ON, "div-by-zero", }, - [WARN_EMPTY_STATEMENT] = { WARN_LEVEL_OFF, "empty-statement", }, - [WARN_ERROR] = { WARN_LEVEL_OFF, "error" }, - [WARN_FATAL_ERRORS] = { WARN_LEVEL_OFF, "fatal-errors" }, - [WARN_FLOAT_EQUAL] = { WARN_LEVEL_OFF, "float-equal", }, - [WARN_FORMAT] = { WARN_LEVEL_ON, "format" }, - [WARN_IMPLICIT_FUNCTION_DECLARATION] = { WARN_LEVEL_ON, "implicit-function-declaration" }, - [WARN_IMPLICIT_INT] = { WARN_LEVEL_ON, "implicit-int" }, - [WARN_INIT_SELF] = { WARN_LEVEL_ON, "init-self", }, - [WARN_LONG_LONG] = { WARN_LEVEL_OFF, "long-long" }, - [WARN_MAIN] = { WARN_LEVEL_ON, "main", }, - [WARN_MISSING_DECLARATIONS] = { WARN_LEVEL_OFF, "missing-declarations", }, - [WARN_MISSING_NORETURN] = { WARN_LEVEL_OFF, "missing-noreturn", }, - [WARN_MISSING_PROTOTYPES] = { WARN_LEVEL_OFF, "missing-prototypes", }, - [WARN_MULTICHAR] = { WARN_LEVEL_ON, "multichar", }, - [WARN_NESTED_EXTERNS] = { WARN_LEVEL_OFF, "nested-externs" }, - [WARN_NONNULL] = { WARN_LEVEL_ON, "nonnull", }, - [WARN_OLD_STYLE_DEFINITION] = { WARN_LEVEL_OFF, "old-style-definition", }, - [WARN_OTHER] = { WARN_LEVEL_ON, "other" }, - [WARN_PACKED] = { WARN_LEVEL_OFF, "packed", }, - [WARN_PADDED] = { WARN_LEVEL_OFF, "padded", }, - [WARN_PARENTHESES] = { WARN_LEVEL_OFF, "parentheses", }, - [WARN_POINTER_ARITH] = { WARN_LEVEL_ON, "pointer-arith", }, - [WARN_REDUNDANT_DECLS] = { WARN_LEVEL_ON, "redundant-decls", }, - [WARN_RETURN_TYPE] = { WARN_LEVEL_ON, "return-type", }, - [WARN_SHADOW] = { WARN_LEVEL_OFF, "shadow", }, - [WARN_SHADOW_LOCAL] = { WARN_LEVEL_OFF, "shadow-local", }, - [WARN_SIGN_COMPARE] = { WARN_LEVEL_OFF, "sign-compare", }, - [WARN_STRICT_PROTOTYPES] = { WARN_LEVEL_ON, "strict-prototypes" }, - [WARN_SWITCH_DEFAULT] = { WARN_LEVEL_OFF, "switch-default", }, - [WARN_SWITCH_ENUM] = { WARN_LEVEL_OFF, "switch-enum", }, - [WARN_TRADITIONAL] = { WARN_LEVEL_OFF, "traditional" }, - [WARN_UNINITIALIZED] = { WARN_LEVEL_ON, "uninitialized", }, - [WARN_UNKNOWN_PRAGMAS] = { WARN_LEVEL_ON, "unknown-pragmas", }, - [WARN_UNREACHABLE_CODE] = { WARN_LEVEL_OFF, "unreachable-code" }, - [WARN_UNUSED_FUNCTION] = { WARN_LEVEL_OFF, "unused-function", }, - [WARN_UNUSED_LABEL] = { WARN_LEVEL_OFF, "unused-label", }, - [WARN_UNUSED_PARAMETER] = { WARN_LEVEL_OFF, "unused-parameter", }, - [WARN_UNUSED_VALUE] = { WARN_LEVEL_ON, "unused-value", }, - [WARN_UNUSED_VARIABLE] = { WARN_LEVEL_OFF, "unused-variable", }, - [WARN_WRITE_STRINGS] = { WARN_LEVEL_OFF, "write-strings", }, + [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) @@ -89,22 +78,37 @@ void print_warning_opt_help(void) { /* TODO: write explanations */ for (warning_switch_t* i = warning; i != endof(warning); ++i) { - put_help(i->name, ""); + 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; - warn_level_t const level = - strncmp(s, "no-", 3) == 0 ? s += 3, WARN_LEVEL_OFF : /* "no-" prefix */ - strncmp(s, "error-", 6) == 0 ? s += 6, WARN_LEVEL_ERROR : /* "error-" prefix */ - WARN_LEVEL_ON; + 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; + } for (warning_switch_t* i = warning; i != endof(warning); ++i) { - if (strcmp(i->name, s) == 0) { - i->level = level; + if (streq(i->name, s)) { + i->state = (i->state & ~off) | on; return; } } @@ -112,8 +116,8 @@ void set_warning_opt(const char *const opt) if (s[0] == '\0') { // -W is an alias for -Wextra goto extra; } -#define OPTX(x) else if (strcmp(s, x) == 0) -#define SET(y) (void)(warning[y].level = level) +#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 more warnings than gcc's -Wall */ SET(WARN_ADDRESS); @@ -124,7 +128,6 @@ void set_warning_opt(const char *const opt) SET(WARN_FORMAT); SET(WARN_IMPLICIT_FUNCTION_DECLARATION); SET(WARN_IMPLICIT_INT); - SET(WARN_INIT_SELF); SET(WARN_MAIN); SET(WARN_MISSING_DECLARATIONS); SET(WARN_NONNULL); @@ -171,6 +174,11 @@ extra: } #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); } @@ -181,7 +189,7 @@ 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->level = WARN_LEVEL_OFF; + i->state &= ~WARN_STATE_ON; } } }