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