xref: /csrg-svn/usr.bin/indent/args.c (revision 34885)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are permitted
7  * provided that the above copyright notice and this paragraph are
8  * duplicated in all such forms and that any documentation,
9  * advertising materials, and other materials related to such
10  * distribution and use acknowledge that the software was developed
11  * by the University of California, Berkeley and the University
12  * of Illinois, Urbana.  The name of either
13  * University may not be used to endorse or promote products derived
14  * from this software without specific prior written permission.
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18  */
19 
20 #ifndef lint
21 static char sccsid[] = "@(#)args.c	5.4 (Berkeley) 06/29/88";
22 #endif /* not lint */
23 
24 /*
25  * Argument scanning and profile reading code.  Default parameters
26  * are set here as well.
27  */
28 
29 #include "indent_globs.h"
30 #include <sys/types.h>
31 #include <ctype.h>
32 
33 char *getenv(), *index();
34 
35 /* profile types */
36 #define	PRO_SPECIAL	1	/* special case */
37 #define	PRO_BOOL	2	/* boolean */
38 #define	PRO_INT		3	/* integer */
39 
40 /* profile specials for booleans */
41 #define	ON		1	/* turn it on */
42 #define	OFF		0	/* turn it off */
43 
44 /* profile specials for specials */
45 #define	IGN		1	/* ignore it */
46 #define	CLI		2	/* case label indent (float) */
47 #define	STDIN		3	/* use stdin */
48 #define	KEY		4	/* type (keyword) */
49 
50 /*
51  * N.B.: because of the way the table here is scanned, options
52  * whose names are substrings of other options must occur later;
53  * that is, with -lp vs -l, -lp must be first.  Also, while (most)
54  * booleans occur more than once, the last default value is the
55  * one actually assigned.
56  */
57 struct pro {
58     char *p_name;		/* name, eg -bl, -cli */
59     int   p_type;		/* type (int, bool, special) */
60     int   p_default;		/* the default value (if int) */
61     int   p_special;		/* depends on type */
62     int  *p_obj;		/* the associated variable */
63 } pro[] = {
64     "npro",	PRO_SPECIAL,	0,	IGN,	0,
65     "lc",	PRO_INT,	0,	0,	&block_comment_max_col,
66     "lp",	PRO_BOOL,	true,	ON,	&lineup_to_parens,
67     "nlp",	PRO_BOOL,	true,	OFF,	&lineup_to_parens,
68     "l",	PRO_INT,	78,	0,	&max_col,
69     "psl",	PRO_BOOL,	true,	ON,	&procnames_start_line,
70     "npsl",	PRO_BOOL,	true,	OFF,	&procnames_start_line,
71     "fc1",	PRO_BOOL,	true,	ON,	&format_col1_comments,
72     "nfc1",	PRO_BOOL,	true,	OFF,	&format_col1_comments,
73     "pcs",	PRO_BOOL,	false,	ON,	&proc_calls_space,
74     "npcs",	PRO_BOOL,	false,	OFF,	&proc_calls_space,
75     "ip",	PRO_BOOL,	true,	ON,	&ps.indent_parameters,
76     "nip",	PRO_BOOL,	true,	OFF,	&ps.indent_parameters,
77  /* see set_defaults for initialization of -cli */
78     "cli",	PRO_SPECIAL,	0,	CLI,	0,
79     "ci",	PRO_INT,	0,	0,	&continuation_indent,
80     "cdb",	PRO_BOOL,	true,	ON,  &comment_delimiter_on_blankline,
81     "ncdb",	PRO_BOOL,	true,	OFF, &comment_delimiter_on_blankline,
82     "i",	PRO_INT,	8,	0,	&ps.ind_size,
83     "cd",	PRO_INT,	0,	0,	&ps.decl_com_ind,
84     "ce",	PRO_BOOL,	true,	ON,	&cuddle_else,
85     "nce",	PRO_BOOL,	true,	OFF,	&cuddle_else,
86     "c",	PRO_INT,	33,	0,	&ps.com_ind,
87     "v",	PRO_BOOL,	false,	ON,	&verbose,
88     "nv",	PRO_BOOL,	false,	OFF,	&verbose,
89     "dj",	PRO_BOOL,	false,	ON,	&ps.ljust_decl,
90     "ndj",	PRO_BOOL,	false,	OFF,	&ps.ljust_decl,
91  /* don't ask *me* why -bc/-nbc is backwards.... */
92     "bc",	PRO_BOOL,	true,	OFF,	&ps.leave_comma,
93     "nbc",	PRO_BOOL,	true,	ON,	&ps.leave_comma,
94     "di",	PRO_INT,	16,	0,	&ps.decl_indent,
95     "d",	PRO_INT,	0,	0,	&ps.unindent_displace,
96     "br",	PRO_BOOL,	true,	ON,	&btype_2,
97     "bl",	PRO_BOOL,	true,	OFF,	&btype_2,
98     "st",	PRO_SPECIAL,	0,	STDIN,	0,
99     "ei",	PRO_BOOL,	true,	ON,	&ps.else_if,
100     "nei",	PRO_BOOL,	true,	OFF,	&ps.else_if,
101     "sc",	PRO_BOOL,	true,	ON,	&star_comment_cont,
102     "nsc",	PRO_BOOL,	true,	OFF,	&star_comment_cont,
103     "bap",	PRO_BOOL,	false,	ON,	&blanklines_after_procs,
104     "nbap",	PRO_BOOL,	false,	OFF,	&blanklines_after_procs,
105     "sob",	PRO_BOOL,	false,	ON,	&swallow_optional_blanklines,
106     "nsob",	PRO_BOOL,	false,	OFF,	&swallow_optional_blanklines,
107     "bad",	PRO_BOOL,	false,	ON,  &blanklines_after_declarations,
108     "nbad",	PRO_BOOL,	false,	OFF, &blanklines_after_declarations,
109     "bbb",	PRO_BOOL,	false,	ON,  &blanklines_before_blockcomments,
110     "nbbb",	PRO_BOOL,	false,	OFF, &blanklines_before_blockcomments,
111     "ps",	PRO_BOOL,	false,	ON,	&pointer_as_binop,
112     "nps",	PRO_BOOL,	false,	OFF,	&pointer_as_binop,
113     "troff",	PRO_BOOL,	false,	ON,	&troff,
114     "T",	PRO_SPECIAL,	0,	KEY,	0,
115  /* whew! */
116     0,		0,		0,	0,	0
117 };
118 
119 /*
120  * set_profile reads $HOME/.indent.pro and ./.indent.pro and
121  * handles arguments given in these files.
122  */
123 set_profile()
124 {
125     register FILE *f;
126     char fname[BUFSIZ];
127     static char pro[] = ".indent.pro";
128 
129     sprintf(fname, "%s/%s", getenv("HOME"), pro);
130     if ((f = fopen(fname, "r")) != NULL) {
131 	scan_profile(f);
132 	(void) fclose(f);
133     }
134     if ((f = fopen(pro, "r")) != NULL) {
135 	scan_profile(f);
136 	(void) fclose(f);
137     }
138 }
139 
140 scan_profile(f)
141     register FILE *f;
142 {
143     register char *p, *arg;
144     char buf[BUFSIZ];
145 
146     while (fgets(buf, sizeof buf, f)) {
147 	if ((p = index(buf, '\n')) != NULL)
148 	    *p = 0;
149 	if (verbose)
150 	    printf("profile: %s\n", buf);
151 	p = buf;
152 	for (;;) {
153 	    while (isspace(*p))
154 		p++;
155 	    if (*p == 0)
156 		break;
157 	    arg = p;
158 	    while (*p) {
159 		if (isspace(*p)) {
160 		    *p++ = 0;
161 		    break;
162 		}
163 		p++;
164 	    }
165 	    set_option(arg);
166 	}
167     }
168 }
169 
170 char       *param_start;
171 
172 eqin(s1, s2)
173     register char *s1;
174     register char *s2;
175 {
176     while (*s1) {
177 	if (*s1++ != *s2++)
178 	    return (false);
179     }
180     param_start = s2;
181     return (true);
182 }
183 
184 /*
185  * Set the defaults.
186  */
187 set_defaults()
188 {
189     register struct pro *p;
190 
191     /*
192      * Because ps.case_indent is a float, we can't initialize it
193      * from the table:
194      */
195     ps.case_indent = 0.0;	/* -cli0.0 */
196     for (p = pro; p->p_name; p++)
197 	if (p->p_type != PRO_SPECIAL)
198 	    *p->p_obj = p->p_default;
199 }
200 
201 set_option(arg)
202     register char *arg;
203 {
204     register struct pro *p;
205     extern double atof();
206 
207     arg++;			/* ignore leading "-" */
208     for (p = pro; p->p_name; p++)
209 	if (*p->p_name == *arg && eqin(p->p_name, arg))
210 	    goto found;
211     fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
212     exit(1);
213 found:
214     switch (p->p_type) {
215 
216 	case PRO_SPECIAL:
217 	    switch (p->p_special) {
218 
219 		case IGN:
220 		    break;
221 
222 		case CLI:
223 		    if (*param_start == 0)
224 			goto need_param;
225 		    ps.case_indent = atof(param_start);
226 		    break;
227 
228 		case STDIN:
229 		    if (input == 0)
230 			input = stdin;
231 		    if (output == 0)
232 			output = stdout;
233 		    break;
234 
235 		case KEY:
236 		    if (*param_start == 0)
237 			goto need_param;
238 		    addkey(param_start, 4);
239 		    break;
240 
241 		default:
242 		    fprintf(stderr, "\
243 indent: set_option: internal error: p_special %d\n", p->p_special);
244 		    exit(1);
245 	    }
246 	    break;
247 
248 	case PRO_BOOL:
249 	    if (p->p_special == OFF)
250 		*p->p_obj = false;
251 	    else
252 		*p->p_obj = true;
253 	    break;
254 
255 	case PRO_INT:
256 	    if (*param_start == 0) {
257 need_param:
258 		fprintf(stderr, "indent: ``%s'' requires a parameter\n",
259 			arg - 1);
260 		exit(1);
261 	    }
262 	    *p->p_obj = atoi(param_start);
263 	    break;
264 
265 	default:
266 	    fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
267 		    p->p_type);
268 	    exit(1);
269     }
270 }
271