1/*	Id	*/
2/*	$NetBSD: wflag.c,v 1.1.1.1 2016/02/09 20:29:13 plunky Exp $	*/
3
4/*-
5 * Copyright (c) 2014 Iain Hibbert.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26#include <string.h>
27
28#include "driver.h"
29
30static struct {
31	const char *	name;
32	unsigned int	flag;
33} Warns[] = {
34    { "error",				W_CCOM | W_CXXCOM		},
35    { "truncate",			W_CCOM | W_CXXCOM		},
36    { "strict-prototypes",		W_CCOM | W_CXXCOM		},
37    { "missing-prototypes",		W_CCOM | W_CXXCOM		},
38    { "implicit-int",			W_CCOM | W_CXXCOM | W_ALL	},
39    { "implicit-function-declaration",	W_CCOM | W_CXXCOM | W_ALL	},
40    { "shadow",				W_CCOM | W_CXXCOM		},
41    { "pointer-sign",			W_CCOM | W_CXXCOM | W_ALL	},
42    { "sign-compare",			W_CCOM | W_CXXCOM		},
43    { "system-headers",			W_CPP				},
44    { "unknown-pragmas",		W_CCOM | W_CXXCOM | W_ALL	},
45    { "unreachable-code",		W_CCOM | W_CXXCOM		},
46};
47
48static int
49Wset(unsigned int match)
50{
51	size_t i;
52
53	for (i = 0; i < ARRAYLEN(Warns); i++) {
54		if ((Warns[i].flag & match) == match)
55			Warns[i].flag |= W_SET;
56	}
57
58	return 1;
59}
60
61int
62Wflag(const char *str)
63{
64	size_t i;
65	int set, err;
66
67	if (strcmp("all", str) == 0)
68		return Wset(W_ALL);
69	if (strcmp("extra", str) == 0)
70		return Wset(W_EXTRA);
71	if (strcmp("W", str) == 0)
72		return Wset(0);
73
74	set = 1;
75	err = 0;
76	if (strcmp("error", str) != 0) {
77		if (strncmp("no-", str, 3) == 0) {
78			str += 3;
79			set = 0;
80		}
81
82		if (strncmp("error=", str, 6) == 0) {
83			str += 6;
84			err = 1;
85		}
86	}
87
88	for (i = 0; i < ARRAYLEN(Warns); i++) {
89		if (strcmp(Warns[i].name, str) == 0) {
90			if (set)
91				Warns[i].flag |= W_SET;
92			else
93				Warns[i].flag &= ~W_SET;
94
95			if (err)
96				Warns[i].flag |= W_ERR;
97			else
98				Warns[i].flag &= ~W_ERR;
99
100			return 1;
101		}
102	}
103
104	return 0;
105}
106
107void
108Wflag_add(list_t *l, unsigned int match)
109{
110	size_t i;
111
112	for (i = 0; i < ARRAYLEN(Warns); i++) {
113		if ((Warns[i].set || Warns[i].err)
114		    && (match & Warns[i].flag)) {
115			list_add(l, "-W%s%s%s",
116			    (Warns[i].flag & W_SET ? "" : "no-"),
117			    (Warns[i].flag & W_ERR ? "error=" : ""),
118			    Warns[i].name);
119		}
120	}
121}
122