Age Owner Branch data TLA Line data Source code
1 : : /*-
2 : : * Copyright (c) 1985 Sun Microsystems, Inc.
3 : : * Copyright (c) 1980, 1993
4 : : * The Regents of the University of California. All rights reserved.
5 : : * 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 : : #if 0
33 : : #ifndef lint
34 : : static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93";
35 : : #endif /* not lint */
36 : : #endif
37 : :
38 : : #include "c.h"
39 : :
40 : : /*
41 : : * Argument scanning and profile reading code. Default parameters are set
42 : : * here as well.
43 : : */
44 : :
45 : : #include <ctype.h>
46 : : #include <err.h>
47 : : #include <limits.h>
48 : : #include <stdio.h>
49 : : #include <stdlib.h>
50 : : #include <string.h>
51 : : #include "indent_globs.h"
52 : : #include "indent.h"
53 : :
54 : : #define INDENT_VERSION "2.1.2"
55 : :
56 : : /* profile types */
57 : : #define PRO_SPECIAL 1 /* special case */
58 : : #define PRO_BOOL 2 /* boolean */
59 : : #define PRO_INT 3 /* integer */
60 : :
61 : : /* profile specials for booleans */
62 : : #define ON 1 /* turn it on */
63 : : #define OFF 0 /* turn it off */
64 : :
65 : : /* profile specials for specials */
66 : : #define IGN 1 /* ignore it */
67 : : #define CLI 2 /* case label indent (float) */
68 : : #define STDIN 3 /* use stdin */
69 : : #define KEY 4 /* type (keyword) */
70 : :
71 : : static void scan_profile(FILE *);
72 : :
73 : : #define KEY_FILE 5 /* only used for args */
74 : : #define VERSION 6 /* only used for args */
75 : :
76 : : const char *option_source = "?";
77 : :
78 : : void add_typedefs_from_file(const char *str);
79 : :
80 : : /*
81 : : * N.B.: because of the way the table here is scanned, options whose names are
82 : : * substrings of other options must occur later; that is, with -lp vs -l, -lp
83 : : * must be first. Also, while (most) booleans occur more than once, the last
84 : : * default value is the one actually assigned.
85 : : */
86 : : struct pro {
87 : : const char *p_name; /* name, e.g. -bl, -cli */
88 : : int p_type; /* type (int, bool, special) */
89 : : int p_default; /* the default value (if int) */
90 : : int p_special; /* depends on type */
91 : : int *p_obj; /* the associated variable */
92 : : } pro[] = {
93 : :
94 : : {"T", PRO_SPECIAL, 0, KEY, 0},
95 : : {"U", PRO_SPECIAL, 0, KEY_FILE, 0},
96 : : {"-version", PRO_SPECIAL, 0, VERSION, 0},
97 : : {"P", PRO_SPECIAL, 0, IGN, 0},
98 : : {"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation},
99 : : {"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop},
100 : : {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations},
101 : : {"bap", PRO_BOOL, false, ON, &blanklines_after_procs},
102 : : {"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments},
103 : : {"bc", PRO_BOOL, true, OFF, &ps.leave_comma},
104 : : {"bl", PRO_BOOL, true, OFF, &btype_2},
105 : : {"br", PRO_BOOL, true, ON, &btype_2},
106 : : {"bs", PRO_BOOL, false, ON, &Bill_Shannon},
107 : : {"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline},
108 : : {"cd", PRO_INT, 0, 0, &ps.decl_com_ind},
109 : : {"ce", PRO_BOOL, true, ON, &cuddle_else},
110 : : {"ci", PRO_INT, 0, 0, &continuation_indent},
111 : : {"cli", PRO_SPECIAL, 0, CLI, 0},
112 : : {"cp", PRO_INT, 0, 0, &else_endif_com_ind},
113 : : {"c", PRO_INT, 33, 0, &ps.com_ind},
114 : : {"di", PRO_INT, 16, 0, &ps.decl_indent},
115 : : {"dj", PRO_BOOL, false, ON, &ps.ljust_decl},
116 : : {"d", PRO_INT, 0, 0, &ps.unindent_displace},
117 : : {"eei", PRO_BOOL, false, ON, &extra_expression_indent},
118 : : {"ei", PRO_BOOL, true, ON, &ps.else_if},
119 : : {"fbs", PRO_BOOL, true, ON, &function_brace_split},
120 : : {"fc1", PRO_BOOL, true, ON, &format_col1_comments},
121 : : {"fcb", PRO_BOOL, true, ON, &format_block_comments},
122 : : {"ip", PRO_BOOL, true, ON, &ps.indent_parameters},
123 : : {"i", PRO_INT, 8, 0, &ps.ind_size},
124 : : {"lc", PRO_INT, 0, 0, &block_comment_max_col},
125 : : {"ldi", PRO_INT, -1, 0, &ps.local_decl_indent},
126 : : {"lpl", PRO_BOOL, false, ON, &lineup_to_parens_always},
127 : : {"lp", PRO_BOOL, true, ON, &lineup_to_parens},
128 : : {"l", PRO_INT, 78, 0, &max_col},
129 : : {"nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation},
130 : : {"nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop},
131 : : {"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations},
132 : : {"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs},
133 : : {"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments},
134 : : {"nbc", PRO_BOOL, true, ON, &ps.leave_comma},
135 : : {"nbs", PRO_BOOL, false, OFF, &Bill_Shannon},
136 : : {"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline},
137 : : {"nce", PRO_BOOL, true, OFF, &cuddle_else},
138 : : {"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl},
139 : : {"neei", PRO_BOOL, false, OFF, &extra_expression_indent},
140 : : {"nei", PRO_BOOL, true, OFF, &ps.else_if},
141 : : {"nfbs", PRO_BOOL, true, OFF, &function_brace_split},
142 : : {"nfc1", PRO_BOOL, true, OFF, &format_col1_comments},
143 : : {"nfcb", PRO_BOOL, true, OFF, &format_block_comments},
144 : : {"nip", PRO_BOOL, true, OFF, &ps.indent_parameters},
145 : : {"nlpl", PRO_BOOL, false, OFF, &lineup_to_parens_always},
146 : : {"nlp", PRO_BOOL, true, OFF, &lineup_to_parens},
147 : : {"npcs", PRO_BOOL, false, OFF, &proc_calls_space},
148 : : {"npro", PRO_SPECIAL, 0, IGN, 0},
149 : : {"npsl", PRO_BOOL, true, OFF, &procnames_start_line},
150 : : {"nsac", PRO_BOOL, false, OFF, &space_after_cast},
151 : : {"nsc", PRO_BOOL, true, OFF, &star_comment_cont},
152 : : {"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines},
153 : : {"ntpg", PRO_BOOL, false, OFF, &postgres_tab_rules},
154 : : {"nut", PRO_BOOL, true, OFF, &use_tabs},
155 : : {"nv", PRO_BOOL, false, OFF, &verbose},
156 : : {"pcs", PRO_BOOL, false, ON, &proc_calls_space},
157 : : {"psl", PRO_BOOL, true, ON, &procnames_start_line},
158 : : {"sac", PRO_BOOL, false, ON, &space_after_cast},
159 : : {"sc", PRO_BOOL, true, ON, &star_comment_cont},
160 : : {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines},
161 : : {"st", PRO_SPECIAL, 0, STDIN, 0},
162 : : {"ta", PRO_BOOL, false, ON, &auto_typedefs},
163 : : {"tpg", PRO_BOOL, false, ON, &postgres_tab_rules},
164 : : {"ts", PRO_INT, 8, 0, &tabsize},
165 : : {"ut", PRO_BOOL, true, ON, &use_tabs},
166 : : {"v", PRO_BOOL, false, ON, &verbose},
167 : : /* whew! */
168 : : {0, 0, 0, 0, 0}
169 : : };
170 : :
171 : : /*
172 : : * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
173 : : * given in these files.
174 : : */
175 : : void
427 tgl@sss.pgh.pa.us 176 :CBC 19 : set_profile(const char *profile_name)
177 : : {
178 : : FILE *f;
179 : : char fname[MAXPGPATH];
180 : : static char prof[] = ".indent.pro";
181 : :
182 [ + + ]: 19 : if (profile_name == NULL)
183 : 1 : snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof);
184 : : else
185 : 18 : snprintf(fname, sizeof(fname), "%s", profile_name + 2);
186 [ + + ]: 19 : if ((f = fopen(option_source = fname, "r")) != NULL) {
187 : 8 : scan_profile(f);
188 : 8 : (void) fclose(f);
189 : : }
190 [ - + ]: 19 : if ((f = fopen(option_source = prof, "r")) != NULL) {
427 tgl@sss.pgh.pa.us 191 :UBC 0 : scan_profile(f);
192 : 0 : (void) fclose(f);
193 : : }
427 tgl@sss.pgh.pa.us 194 :CBC 19 : option_source = "Command line";
195 : 19 : }
196 : :
197 : : static void
198 : 8 : scan_profile(FILE *f)
199 : : {
200 : : int comment, i;
201 : : char *p;
202 : : char buf[BUFSIZ];
203 : :
204 : : while (1) {
205 : 19 : p = buf;
206 : 19 : comment = 0;
207 [ + + ]: 88 : while ((i = getc(f)) != EOF) {
208 [ - + - - : 80 : if (i == '*' && !comment && p > buf && p[-1] == '/') {
- - - - ]
427 tgl@sss.pgh.pa.us 209 :UBC 0 : comment = p - buf;
210 : 0 : *p++ = i;
427 tgl@sss.pgh.pa.us 211 [ - + - - :CBC 80 : } else if (i == '/' && comment && p > buf && p[-1] == '*') {
- - - - ]
427 tgl@sss.pgh.pa.us 212 :UBC 0 : p = buf + comment - 1;
213 : 0 : comment = 0;
427 tgl@sss.pgh.pa.us 214 [ + + ]:CBC 80 : } else if (isspace((unsigned char)i)) {
215 [ + - + - ]: 11 : if (p > buf && !comment)
216 : 11 : break;
217 : : } else {
218 : 69 : *p++ = i;
219 : : }
220 : : }
221 [ + + ]: 19 : if (p != buf) {
222 : 11 : *p++ = 0;
223 [ - + ]: 11 : if (verbose)
427 tgl@sss.pgh.pa.us 224 :UBC 0 : printf("profile: %s\n", buf);
427 tgl@sss.pgh.pa.us 225 :CBC 11 : set_option(buf);
226 : : }
227 [ + - ]: 8 : else if (i == EOF)
228 : 8 : return;
229 : : }
230 : : }
231 : :
232 : : static const char *
233 : 91 : eqin(const char *s1, const char *s2)
234 : : {
235 [ + + ]: 206 : while (*s1) {
236 [ + + ]: 176 : if (*s1++ != *s2++)
237 : 61 : return (NULL);
238 : : }
239 : 30 : return (s2);
240 : : }
241 : :
242 : : /*
243 : : * Set the defaults.
244 : : */
245 : : void
246 : 19 : set_defaults(void)
247 : : {
248 : : struct pro *p;
249 : :
250 : : /*
251 : : * Because ps.case_indent is a float, we can't initialize it from the
252 : : * table:
253 : : */
254 : 19 : ps.case_indent = 0.0; /* -cli0.0 */
255 [ + + ]: 1406 : for (p = pro; p->p_name; p++)
256 [ + + ]: 1387 : if (p->p_type != PRO_SPECIAL)
257 : 1254 : *p->p_obj = p->p_default;
258 : 19 : }
259 : :
260 : : void
261 : 30 : set_option(char *arg)
262 : : {
263 : : struct pro *p;
264 : : const char *param_start;
265 : :
266 : 30 : arg++; /* ignore leading "-" */
267 [ + - ]: 410 : for (p = pro; p->p_name; p++)
268 [ + + + + ]: 410 : if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL)
269 : 30 : goto found;
427 tgl@sss.pgh.pa.us 270 :UBC 0 : errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1);
427 tgl@sss.pgh.pa.us 271 :CBC 30 : found:
272 [ + + + - ]: 30 : switch (p->p_type) {
273 : :
274 : 21 : case PRO_SPECIAL:
275 [ + - - + : 21 : switch (p->p_special) {
+ + - ]
276 : :
277 : 18 : case IGN:
278 : 18 : break;
279 : :
427 tgl@sss.pgh.pa.us 280 :UBC 0 : case CLI:
281 [ # # ]: 0 : if (*param_start == 0)
282 : 0 : goto need_param;
283 : 0 : ps.case_indent = atof(param_start);
284 : 0 : break;
285 : :
286 : 0 : case STDIN:
287 [ # # ]: 0 : if (input == NULL)
288 : 0 : input = stdin;
289 [ # # ]: 0 : if (output == NULL)
290 : 0 : output = stdout;
291 : 0 : break;
292 : :
427 tgl@sss.pgh.pa.us 293 :CBC 1 : case KEY:
294 [ - + ]: 1 : if (*param_start == 0)
427 tgl@sss.pgh.pa.us 295 :UBC 0 : goto need_param;
427 tgl@sss.pgh.pa.us 296 :CBC 1 : add_typename(param_start);
297 : 1 : break;
298 : :
299 : 1 : case KEY_FILE:
300 [ - + ]: 1 : if (*param_start == 0)
427 tgl@sss.pgh.pa.us 301 :UBC 0 : goto need_param;
427 tgl@sss.pgh.pa.us 302 :CBC 1 : add_typedefs_from_file(param_start);
303 : 1 : break;
304 : :
305 : 1 : case VERSION:
306 : 1 : printf("pg_bsd_indent %s (based on FreeBSD indent)\n", INDENT_VERSION);
307 : 1 : exit(0);
308 : :
427 tgl@sss.pgh.pa.us 309 :UBC 0 : default:
310 : 0 : errx(1, "set_option: internal error: p_special %d", p->p_special);
311 : : }
427 tgl@sss.pgh.pa.us 312 :CBC 20 : break;
313 : :
314 : 6 : case PRO_BOOL:
315 [ + + ]: 6 : if (p->p_special == OFF)
316 : 3 : *p->p_obj = false;
317 : : else
318 : 3 : *p->p_obj = true;
319 : 6 : break;
320 : :
321 : 3 : case PRO_INT:
322 [ - + ]: 3 : if (!isdigit((unsigned char)*param_start)) {
427 tgl@sss.pgh.pa.us 323 :UBC 0 : need_param:
324 : 0 : errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name);
325 : : }
427 tgl@sss.pgh.pa.us 326 :CBC 3 : *p->p_obj = atoi(param_start);
327 : 3 : break;
328 : :
427 tgl@sss.pgh.pa.us 329 :UBC 0 : default:
330 : 0 : errx(1, "set_option: internal error: p_type %d", p->p_type);
331 : : }
427 tgl@sss.pgh.pa.us 332 :CBC 29 : }
333 : :
334 : : void
335 : 1 : add_typedefs_from_file(const char *str)
336 : : {
337 : : FILE *file;
338 : : char line[BUFSIZ];
339 : :
340 [ - + ]: 1 : if ((file = fopen(str, "r")) == NULL) {
427 tgl@sss.pgh.pa.us 341 :UBC 0 : fprintf(stderr, "indent: cannot open file %s\n", str);
342 : 0 : exit(1);
343 : : }
427 tgl@sss.pgh.pa.us 344 [ + + ]:CBC 3 : while ((fgets(line, BUFSIZ, file)) != NULL) {
345 : : /* Remove trailing whitespace */
346 : 2 : line[strcspn(line, " \t\n\r")] = '\0';
347 : 2 : add_typename(line);
348 : : }
349 : 1 : fclose(file);
350 : 1 : }
|