xref: /netbsd-src/usr.bin/config/lint.c (revision 93b25323436f832f83862b693a2b44c057a19e45)
1*93b25323Sjoe /*	$NetBSD: lint.c,v 1.17 2025/01/07 14:21:11 joe Exp $	*/
259c94545Scube 
359c94545Scube /*
490426267Scube  *  Copyright (c) 2007 The NetBSD Foundation.
559c94545Scube  *  All rights reserved.
659c94545Scube  *
759c94545Scube  *  Redistribution and use in source and binary forms, with or without
859c94545Scube  *  modification, are permitted provided that the following conditions
959c94545Scube  *  are met:
1059c94545Scube  *  1. Redistributions of source code must retain the above copyright
1159c94545Scube  *     notice, this list of conditions and the following disclaimer.
1259c94545Scube  *  2. Redistributions in binary form must reproduce the above copyright
1359c94545Scube  *     notice, this list of conditions and the following disclaimer in the
1459c94545Scube  *     documentation and/or other materials provided with the distribution.
1559c94545Scube  *
1659c94545Scube  *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1759c94545Scube  *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1859c94545Scube  *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1959c94545Scube  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2059c94545Scube  *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2159c94545Scube  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2259c94545Scube  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2359c94545Scube  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2459c94545Scube  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2559c94545Scube  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2659c94545Scube  *  POSSIBILITY OF SUCH DAMAGE.
2759c94545Scube  */
2859c94545Scube 
2959c94545Scube #if HAVE_NBTOOL_CONFIG_H
3059c94545Scube #include "nbtool_config.h"
3159c94545Scube #endif
3259c94545Scube 
33d12b0036Schristos #include <sys/cdefs.h>
34*93b25323Sjoe __RCSID("$NetBSD: lint.c,v 1.17 2025/01/07 14:21:11 joe Exp $");
35d12b0036Schristos 
36cb79ede2Sdholland #include <assert.h>
3759c94545Scube #include <stdlib.h>
3859c94545Scube 
3959c94545Scube #include "defs.h"
4059c94545Scube 
4159c94545Scube void
42d34c2845Smatt emit_params(void)
4359c94545Scube {
4459c94545Scube 
4559c94545Scube 	printf("version\t%d\n", CONFIG_VERSION);
4659c94545Scube 	printf("ident\t\"LINT_%s\"\n", conffile);
4759c94545Scube 	printf("maxusers\t%d\n", defmaxusers);
48072ab000Scube 	printf("config netbsdlint root on ?\n");
4959c94545Scube 	printf("\n");
5059c94545Scube }
5159c94545Scube 
5259c94545Scube enum opt_types {
5359c94545Scube 	OT_FLAG,
5459c94545Scube 	OT_PARAM,
5559c94545Scube 	OT_FS
5659c94545Scube };
5759c94545Scube 
5859c94545Scube static struct opt_type {
5959c94545Scube 	enum opt_types ot_type;
6059c94545Scube 	const char *ot_name;
6159c94545Scube 	struct hashtab **ot_ht;
6259c94545Scube } opt_types[] = {
6359c94545Scube 	{ OT_FLAG, "options", &opttab },
6459c94545Scube 	{ OT_PARAM, "options", &opttab },
6559c94545Scube 	{ OT_FS, "file-system", &fsopttab },
6659c94545Scube };
6759c94545Scube 
6859c94545Scube static int
69cb79ede2Sdholland do_emit_option(const char *name, struct defoptlist *dl, void *v)
7059c94545Scube {
7159c94545Scube 	const struct opt_type *ot = v;
72cb79ede2Sdholland 	const char *value;
7359c94545Scube 
74cb79ede2Sdholland 	if (dl->dl_obsolete)
7559c94545Scube 		return 0;
7659c94545Scube 
7759c94545Scube 	if (ht_lookup(*(ot->ot_ht), name))
7859c94545Scube 		return 0;
7959c94545Scube 
80cb79ede2Sdholland 	printf("%s\t%s", ot->ot_name, dl->dl_name);
8190426267Scube 	if (ot->ot_type == OT_PARAM) {
82cb79ede2Sdholland 		struct defoptlist *dl2 = dlhash_lookup(defoptlint, dl->dl_name);
8302f8fe8fSchristos 		if (dl2 != NULL) {
84cb79ede2Sdholland 			assert(dl2 == dl);
8502f8fe8fSchristos 			value = dl2->dl_lintvalue;
8602f8fe8fSchristos 		} else
8702f8fe8fSchristos 			value = dl->dl_value;
88cb79ede2Sdholland 		printf("=\"%s\"", value ? value : "1");
8990426267Scube 	}
9059c94545Scube 	printf("\n");
9159c94545Scube 
9259c94545Scube 	return 1;
9359c94545Scube }
9459c94545Scube 
95cb79ede2Sdholland /*
96cb79ede2Sdholland  * Same as do_emit_option but for filesystem definitions, which now
97cb79ede2Sdholland  * have a different data type. XXX these should probably be unified
98cb79ede2Sdholland  * again.
99cb79ede2Sdholland  */
100cb79ede2Sdholland static int
101cb79ede2Sdholland do_emit_fs(const char *name, struct nvlist *nv, void *v)
102cb79ede2Sdholland {
103cb79ede2Sdholland 	const struct opt_type *ot = v;
104cb79ede2Sdholland 
105cb79ede2Sdholland 	if (ht_lookup(*(ot->ot_ht), name))
106cb79ede2Sdholland 		return 0;
107cb79ede2Sdholland 
108cb79ede2Sdholland 	assert(ot->ot_type != OT_PARAM);
109cb79ede2Sdholland 	printf("%s\t%s\n", ot->ot_name, nv->nv_name);
110cb79ede2Sdholland 
111cb79ede2Sdholland 	return 1;
112cb79ede2Sdholland }
113cb79ede2Sdholland 
11459c94545Scube void
115a883398eSdholland emit_options(void)
11659c94545Scube {
11759c94545Scube 
118cb79ede2Sdholland 	(void)dlhash_enumerate(defflagtab, do_emit_option, &opt_types[0]);
11959c94545Scube 	printf("\n");
120cb79ede2Sdholland 	(void)dlhash_enumerate(defparamtab, do_emit_option, &opt_types[1]);
12159c94545Scube 	printf("\n");
122cb79ede2Sdholland 	(void)nvhash_enumerate(deffstab, do_emit_fs, &opt_types[2]);
12359c94545Scube 	printf("\n");
12459c94545Scube }
12559c94545Scube 
12659c94545Scube static void
12759c94545Scube do_emit_instances(struct devbase *d, struct attr *at)
12859c94545Scube {
129f5d4142bSdholland 	struct nvlist *nv1;
130f5d4142bSdholland 	struct loclist *ll;
131bbe96a5aSdholland 	struct attrlist *al;
13259c94545Scube 	struct attr *a;
13359c94545Scube 	struct deva *da;
13459c94545Scube 
135072ab000Scube 	/*
136072ab000Scube 	 * d_isdef is used to check whether a deva has been seen or not,
137072ab000Scube 	 * for there are devices that can be their own ancestor (e.g.
138072ab000Scube 	 * uhub, pci).
139072ab000Scube 	 */
140072ab000Scube 
14159c94545Scube 	if (at != NULL) {
14259c94545Scube 		for (da = d->d_ahead; da != NULL; da = da->d_bsame)
14359c94545Scube 			if (onlist(da->d_atlist, at))
14459c94545Scube 				break;
14559c94545Scube 		if (da == NULL)
14659c94545Scube 			panic("do_emit_instances: no deva found for %s at %s",
14759c94545Scube 			    d->d_name, at->a_name);
14859c94545Scube 
14959c94545Scube 		if (da->d_isdef > 1)
15059c94545Scube 			return;
15159c94545Scube 		da->d_isdef = 2;
15259c94545Scube 	}
15359c94545Scube 
154323b3394Scube 	if (at == NULL && !d->d_ispseudo && d->d_ihead == NULL)
15559c94545Scube 		printf("%s0\tat\troot\n", d->d_name);
156323b3394Scube 	else if (at != NULL && !d->d_ispseudo && da->d_ihead == NULL) {
15759c94545Scube 		printf("%s0\tat\t%s?", d->d_name, at->a_name);
15859c94545Scube 
159f5d4142bSdholland 		for (ll = at->a_locs; ll != NULL; ll = ll->ll_next) {
160f5d4142bSdholland 			if (ll->ll_num == 0)
161f5d4142bSdholland 				printf(" %s %c", ll->ll_name,
162f5d4142bSdholland 				    ll->ll_string ? '?' : '0');
16359c94545Scube 		}
16459c94545Scube 
16559c94545Scube 		printf("\n");
16659c94545Scube 	}
16759c94545Scube 
168072ab000Scube 	/*
169072ab000Scube 	 * Children attachments are found the same way as in the orphan
170072ab000Scube 	 * detection code in main.c.
171072ab000Scube 	 */
172bbe96a5aSdholland 	for (al = d->d_attrs; al != NULL; al = al->al_next) {
173bbe96a5aSdholland 		a = al->al_this;
17459c94545Scube 		for (nv1 = a->a_devs; nv1 != NULL; nv1 = nv1->nv_next)
17559c94545Scube 			do_emit_instances(nv1->nv_ptr, a);
17659c94545Scube 	}
17759c94545Scube }
17859c94545Scube 
17959c94545Scube /* ARGSUSED */
18059c94545Scube static int
18159c94545Scube emit_root_instance(const char *name, void *value, void *v)
18259c94545Scube {
18359c94545Scube 
18459c94545Scube 	do_emit_instances((struct devbase *)value, NULL);
18559c94545Scube 
18659c94545Scube 	return 1;
18759c94545Scube }
18859c94545Scube 
1896ebb2291Scube /* ARGSUSED */
1906ebb2291Scube static int
1916ebb2291Scube emit_pseudo_instance(const char *name, void *value, void *v)
1926ebb2291Scube {
1936ebb2291Scube 	struct devbase *d = value;
1946ebb2291Scube 
195323b3394Scube 	if (d->d_ispseudo && d->d_ihead == NULL)
1966ebb2291Scube 		printf("pseudo-device\t%s\n", d->d_name);
1976ebb2291Scube 	return 0;
1986ebb2291Scube }
1996ebb2291Scube 
20059c94545Scube void
201d34c2845Smatt emit_instances(void)
20259c94545Scube {
20359c94545Scube 
20459c94545Scube 	(void)ht_enumerate(devroottab, emit_root_instance, NULL);
2056ebb2291Scube 	printf("\n");
2066ebb2291Scube 	(void)ht_enumerate(devbasetab, emit_pseudo_instance, NULL);
20759c94545Scube }
208