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