summaryrefslogtreecommitdiff
path: root/src/warning.h
blob: 658af93a1c28d1a8b12ebf3c785aa540015baeb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* Control warning output in GNU Make.
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of GNU Make.

GNU Make 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 3 of the License, or (at your option) any later
version.

GNU Make 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, see <https://www.gnu.org/licenses/>.  */

/* Types of warnings we can show.  */
enum warning_type
  {
    wt_invalid_var = 0, /* Assign to an invalid variable name.  */
    wt_invalid_ref,     /* Reference an invalid variable name.  */
    wt_undefined_var,   /* Reference an undefined variable name.  */
    wt_max
  };

/* Action taken for a given warning.  */
enum warning_action
  {
    w_unset = 0,
    w_ignore,
    w_warn,
    w_error
  };

struct warning_data
  {
    enum warning_action global;          /* Global setting.  */
    enum warning_action actions[wt_max]; /* Action for each warning type.  */
  };

/* Actions taken for each warning.  */
extern enum warning_action warnings[wt_max];

/* Get the current action for a given warning.  */
#define warn_get(_w)     (warnings[_w])

/* Set the current actin for a given warning.  Can't use w_unset here.
   This should only be used for temporary resetting of warnings.  */
#define warn_set(_w,_f)  do{ warnings[_w] = (_f); }while(0)

/* True if we should check for the warning in the first place.  */
#define warn_check(_w)   (warn_get (_w) > w_ignore)

/* Check if the warning is ignored.  */
#define warn_ignored(_w) (warn_get (_w) == w_ignore)

/* Check if the warning is in "warn" mode.  */
#define warn_warned(_w)  (warn_get (_w) == w_warn)

/* Check if the warning is in "error" mode.  */
#define warn_error(_w)   (warn_get (_w) == w_error)

void warn_init (void);
void decode_warn_actions (const char *value, const floc *flocp);
char *encode_warn_flag (char *fp);

void warn_get_vardata (struct warning_data *data);
void warn_set_vardata (const struct warning_data *data);

#define warning(_t,_f,_m)                                   \
    do{                                                     \
        if (warn_check (_t))                                \
          {                                                 \
            char *_a = xstrdup (_m);                        \
            if (warn_error (_t))                            \
              fatal (_f, strlen (_a), "%s", _a);            \
            error (_f, strlen (_a), _("warning: %s"), _a);  \
            free (_a);                                      \
          }                                                 \
    }while(0)