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