xref: /minix/usr.bin/indent/args.c (revision 0a6a1f1d)
1 /*	$NetBSD: args.c,v 1.11 2014/09/04 04:06:07 mrg Exp $	*/
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
34  * Copyright (c) 1985 Sun Microsystems, Inc.
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *	This product includes software developed by the University of
48  *	California, Berkeley and its contributors.
49  * 4. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  */
65 
66 #include <sys/cdefs.h>
67 #ifndef lint
68 #if 0
69 static char sccsid[] = "@(#)args.c	8.1 (Berkeley) 6/6/93";
70 #else
71 __RCSID("$NetBSD: args.c,v 1.11 2014/09/04 04:06:07 mrg Exp $");
72 #endif
73 #endif				/* not lint */
74 
75 /*
76  * Argument scanning and profile reading code.  Default parameters are set
77  * here as well.
78  */
79 
80 #include <ctype.h>
81 #include <stdio.h>
82 #include <stdlib.h>
83 #include <string.h>
84 #include "indent_globs.h"
85 
86 /* profile types */
87 #define	PRO_SPECIAL	1	/* special case */
88 #define	PRO_BOOL	2	/* boolean */
89 #define	PRO_INT		3	/* integer */
90 #define PRO_FONT	4	/* troff font */
91 
92 /* profile specials for booleans */
93 #define	ON		1	/* turn it on */
94 #define	OFF		0	/* turn it off */
95 
96 /* profile specials for specials */
97 #define	IGN		1	/* ignore it */
98 #define	CLI		2	/* case label indent (float) */
99 #define	STDIN		3	/* use stdin */
100 #define	KEY		4	/* type (keyword) */
101 
102 const char *option_source = "?";
103 
104 /*
105  * N.B.: because of the way the table here is scanned, options whose names are
106  * substrings of other options must occur later; that is, with -lp vs -l, -lp
107  * must be first.  Also, while (most) booleans occur more than once, the last
108  * default value is the one actually assigned.
109  */
110 struct pro {
111 	const char *p_name;	/* name, eg -bl, -cli */
112 	int     p_type;		/* type (int, bool, special) */
113 	int     p_default;	/* the default value (if int) */
114 	int     p_special;	/* depends on type */
115 	int    *p_obj;		/* the associated variable */
116 }       pro[] = {
117 	{
118 		"T", PRO_SPECIAL, 0, KEY, 0
119 	},
120 	{
121 		"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation
122 	},
123 	{
124 		"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop
125 	},
126 	{
127 		"bad", PRO_BOOL, false, ON, &blanklines_after_declarations
128 	},
129 	{
130 		"bap", PRO_BOOL, false, ON, &blanklines_after_procs
131 	},
132 	{
133 		"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments
134 	},
135 	{
136 		"bc", PRO_BOOL, true, OFF, &ps.leave_comma
137 	},
138 	{
139 		"bl", PRO_BOOL, true, OFF, &btype_2
140 	},
141 	{
142 		"br", PRO_BOOL, true, ON, &btype_2
143 	},
144 	{
145 		"bs", PRO_BOOL, false, ON, &Bill_Shannon
146 	},
147 	{
148 		"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline
149 	},
150 	{
151 		"cd", PRO_INT, 0, 0, &ps.decl_com_ind
152 	},
153 	{
154 		"ce", PRO_BOOL, true, ON, &cuddle_else
155 	},
156 	{
157 		"ci", PRO_INT, 0, 0, &continuation_indent
158 	},
159 	{
160 		"cli", PRO_SPECIAL, 0, CLI, 0
161 	},
162 	{
163 		"c", PRO_INT, 33, 0, &ps.com_ind
164 	},
165 	{
166 		"di", PRO_INT, 16, 0, &ps.decl_indent
167 	},
168 	{
169 		"dj", PRO_BOOL, false, ON, &ps.ljust_decl
170 	},
171 	{
172 		"d", PRO_INT, 0, 0, &ps.unindent_displace
173 	},
174 	{
175 		"eei", PRO_BOOL, false, ON, &extra_expression_indent
176 	},
177 	{
178 		"ei", PRO_BOOL, true, ON, &ps.else_if
179 	},
180 	{
181 		"fbc", PRO_FONT, 0, 0, (int *) &blkcomf
182 	},
183 	{
184 		"fbx", PRO_FONT, 0, 0, (int *) &boxcomf
185 	},
186 	{
187 		"fb", PRO_FONT, 0, 0, (int *) &bodyf
188 	},
189 	{
190 		"fc1", PRO_BOOL, true, ON, &format_col1_comments
191 	},
192 	{
193 		"fc", PRO_FONT, 0, 0, (int *) &scomf
194 	},
195 	{
196 		"fk", PRO_FONT, 0, 0, (int *) &keywordf
197 	},
198 	{
199 		"fs", PRO_FONT, 0, 0, (int *) &stringf
200 	},
201 	{
202 		"ip", PRO_BOOL, true, ON, &ps.indent_parameters
203 	},
204 	{
205 		"i", PRO_INT, 8, 0, &ps.ind_size
206 	},
207 	{
208 		"lc", PRO_INT, 0, 0, &block_comment_max_col
209 	},
210 	{
211 		"lp", PRO_BOOL, true, ON, &lineup_to_parens
212 	},
213 	{
214 		"l", PRO_INT, 78, 0, &max_col
215 	},
216 	{
217 		"nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation
218 	},
219 	{
220 		"nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop
221 	},
222 	{
223 		"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations
224 	},
225 	{
226 		"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs
227 	},
228 	{
229 		"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments
230 	},
231 	{
232 		"nbc", PRO_BOOL, true, ON, &ps.leave_comma
233 	},
234 	{
235 		"nbs", PRO_BOOL, false, OFF, &Bill_Shannon
236 	},
237 	{
238 		"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline
239 	},
240 	{
241 		"nce", PRO_BOOL, true, OFF, &cuddle_else
242 	},
243 	{
244 		"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl
245 	},
246 	{
247 		"neei", PRO_BOOL, false, OFF, &extra_expression_indent
248 	},
249 	{
250 		"nei", PRO_BOOL, true, OFF, &ps.else_if
251 	},
252 	{
253 		"nfc1", PRO_BOOL, true, OFF, &format_col1_comments
254 	},
255 	{
256 		"nip", PRO_BOOL, true, OFF, &ps.indent_parameters
257 	},
258 	{
259 		"nlp", PRO_BOOL, true, OFF, &lineup_to_parens
260 	},
261 	{
262 		"npcs", PRO_BOOL, false, OFF, &proc_calls_space
263 	},
264 	{
265 		"npro", PRO_SPECIAL, 0, IGN, 0
266 	},
267 	{
268 		"npsl", PRO_BOOL, true, OFF, &procnames_start_line
269 	},
270 	{
271 		"nps", PRO_BOOL, false, OFF, &pointer_as_binop
272 	},
273 	{
274 		"nsc", PRO_BOOL, true, OFF, &star_comment_cont
275 	},
276 	{
277 		"nut", PRO_BOOL, true, OFF, &use_tabs
278 	},
279 	{
280 		"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines
281 	},
282 	{
283 		"nv", PRO_BOOL, false, OFF, &verbose
284 	},
285 	{
286 		"pcs", PRO_BOOL, false, ON, &proc_calls_space
287 	},
288 	{
289 		"psl", PRO_BOOL, true, ON, &procnames_start_line
290 	},
291 	{
292 		"ps", PRO_BOOL, false, ON, &pointer_as_binop
293 	},
294 	{
295 		"sc", PRO_BOOL, true, ON, &star_comment_cont
296 	},
297 	{
298 		"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines
299 	},
300 	{
301 		"st", PRO_SPECIAL, 0, STDIN, 0
302 	},
303 	{
304 		"troff", PRO_BOOL, false, ON, &troff
305 	},
306 	{
307 		"ut", PRO_BOOL, true, ON, &use_tabs
308 	},
309 	{
310 		"v", PRO_BOOL, false, ON, &verbose
311 	},
312 	/* whew! */
313 	{
314 		0, 0, 0, 0, 0
315 	}
316 };
317 /*
318  * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
319  * given in these files.
320  */
321 void
set_profile(void)322 set_profile(void)
323 {
324 	FILE   *f;
325 	char    fname[BUFSIZ];
326 	static char prof[] = ".indent.pro";
327 
328 	snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof);
329 	if ((f = fopen(option_source = fname, "r")) != NULL) {
330 		scan_profile(f);
331 		(void) fclose(f);
332 	}
333 	if ((f = fopen(option_source = prof, "r")) != NULL) {
334 		scan_profile(f);
335 		(void) fclose(f);
336 	}
337 	option_source = "Command line";
338 }
339 
340 void
scan_profile(FILE * f)341 scan_profile(FILE *f)
342 {
343 	int     i;
344 	char   *p;
345 	char    buf[BUFSIZ];
346 
347 	while (1) {
348 		for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
349 		if (p != buf) {
350 			*p++ = 0;
351 			if (verbose)
352 				printf("profile: %s\n", buf);
353 			set_option(buf);
354 		} else
355 			if (i == EOF)
356 				return;
357 	}
358 }
359 
360 const char *param_start;
361 
362 int
eqin(const char * s1,const char * s2)363 eqin(const char *s1, const char *s2)
364 {
365 	while (*s1) {
366 		if (*s1++ != *s2++)
367 			return (false);
368 	}
369 	param_start = s2;
370 	return (true);
371 }
372 /*
373  * Set the defaults.
374  */
375 void
set_defaults(void)376 set_defaults(void)
377 {
378 	struct pro *p;
379 
380 	/*
381          * Because ps.case_indent is a float, we can't initialize it from the
382          * table:
383          */
384 	ps.case_indent = 0.0;	/* -cli0.0 */
385 	for (p = pro; p->p_name; p++)
386 		if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
387 			*p->p_obj = p->p_default;
388 }
389 
390 void
set_option(char * arg)391 set_option(char *arg)
392 {
393 	struct pro *p;
394 
395 	arg++;			/* ignore leading "-" */
396 	for (p = pro; p->p_name; p++)
397 		if (*p->p_name == *arg && eqin(p->p_name, arg))
398 			goto found;
399 	fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1);
400 	exit(1);
401 found:
402 	switch (p->p_type) {
403 
404 	case PRO_SPECIAL:
405 		switch (p->p_special) {
406 
407 		case IGN:
408 			break;
409 
410 		case CLI:
411 			if (*param_start == 0)
412 				goto need_param;
413 			ps.case_indent = atof(param_start);
414 			break;
415 
416 		case STDIN:
417 			if (input == 0)
418 				input = stdin;
419 			if (output == 0)
420 				output = stdout;
421 			break;
422 
423 		case KEY:
424 			if (*param_start == 0)
425 				goto need_param;
426 			{
427 				char   *str;
428 
429 				str = strdup(param_start);
430 				addkey(str, 4);
431 			}
432 			break;
433 
434 		default:
435 			fprintf(stderr, "\
436 indent: set_option: internal error: p_special %d\n", p->p_special);
437 			exit(1);
438 		}
439 		break;
440 
441 	case PRO_BOOL:
442 		if (p->p_special == OFF)
443 			*p->p_obj = false;
444 		else
445 			*p->p_obj = true;
446 		break;
447 
448 	case PRO_INT:
449 		if (!isdigit((unsigned char)*param_start)) {
450 	need_param:
451 			fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n",
452 			    option_source, arg - 1);
453 			exit(1);
454 		}
455 		*p->p_obj = atoi(param_start);
456 		break;
457 
458 	case PRO_FONT:
459 		parsefont((struct fstate *) p->p_obj, param_start);
460 		break;
461 
462 	default:
463 		fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
464 		    p->p_type);
465 		exit(1);
466 	}
467 }
468