xref: /csrg-svn/usr.bin/indent/args.c (revision 34885)
124647Smckusick /*
224647Smckusick  * Copyright (c) 1980 Regents of the University of California.
333767Sbostic  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
433767Sbostic  * All rights reserved.
533767Sbostic  *
633767Sbostic  * Redistribution and use in source and binary forms are permitted
7*34885Sbostic  * provided that the above copyright notice and this paragraph are
8*34885Sbostic  * duplicated in all such forms and that any documentation,
9*34885Sbostic  * advertising materials, and other materials related to such
10*34885Sbostic  * distribution and use acknowledge that the software was developed
11*34885Sbostic  * by the University of California, Berkeley and the University
12*34885Sbostic  * of Illinois, Urbana.  The name of either
13*34885Sbostic  * University may not be used to endorse or promote products derived
14*34885Sbostic  * from this software without specific prior written permission.
15*34885Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16*34885Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17*34885Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1824647Smckusick  */
1924647Smckusick 
2024647Smckusick #ifndef lint
21*34885Sbostic static char sccsid[] = "@(#)args.c	5.4 (Berkeley) 06/29/88";
2233767Sbostic #endif /* not lint */
2324647Smckusick 
2424647Smckusick /*
2524647Smckusick  * Argument scanning and profile reading code.  Default parameters
2624647Smckusick  * are set here as well.
2724647Smckusick  */
2824647Smckusick 
2924647Smckusick #include "indent_globs.h"
3024647Smckusick #include <sys/types.h>
3124647Smckusick #include <ctype.h>
3224647Smckusick 
3324647Smckusick char *getenv(), *index();
3424647Smckusick 
3524647Smckusick /* profile types */
3624647Smckusick #define	PRO_SPECIAL	1	/* special case */
3724647Smckusick #define	PRO_BOOL	2	/* boolean */
3824647Smckusick #define	PRO_INT		3	/* integer */
3924647Smckusick 
4024647Smckusick /* profile specials for booleans */
4124647Smckusick #define	ON		1	/* turn it on */
4224647Smckusick #define	OFF		0	/* turn it off */
4324647Smckusick 
4424647Smckusick /* profile specials for specials */
4524647Smckusick #define	IGN		1	/* ignore it */
4624647Smckusick #define	CLI		2	/* case label indent (float) */
4724647Smckusick #define	STDIN		3	/* use stdin */
4824647Smckusick #define	KEY		4	/* type (keyword) */
4924647Smckusick 
5024647Smckusick /*
5124647Smckusick  * N.B.: because of the way the table here is scanned, options
5224647Smckusick  * whose names are substrings of other options must occur later;
5324647Smckusick  * that is, with -lp vs -l, -lp must be first.  Also, while (most)
5424647Smckusick  * booleans occur more than once, the last default value is the
5524647Smckusick  * one actually assigned.
5624647Smckusick  */
5724647Smckusick struct pro {
5824647Smckusick     char *p_name;		/* name, eg -bl, -cli */
5924647Smckusick     int   p_type;		/* type (int, bool, special) */
6024647Smckusick     int   p_default;		/* the default value (if int) */
6124647Smckusick     int   p_special;		/* depends on type */
6224647Smckusick     int  *p_obj;		/* the associated variable */
6324647Smckusick } pro[] = {
6424647Smckusick     "npro",	PRO_SPECIAL,	0,	IGN,	0,
6524647Smckusick     "lc",	PRO_INT,	0,	0,	&block_comment_max_col,
6624647Smckusick     "lp",	PRO_BOOL,	true,	ON,	&lineup_to_parens,
6724647Smckusick     "nlp",	PRO_BOOL,	true,	OFF,	&lineup_to_parens,
6824647Smckusick     "l",	PRO_INT,	78,	0,	&max_col,
6924647Smckusick     "psl",	PRO_BOOL,	true,	ON,	&procnames_start_line,
7024647Smckusick     "npsl",	PRO_BOOL,	true,	OFF,	&procnames_start_line,
7124647Smckusick     "fc1",	PRO_BOOL,	true,	ON,	&format_col1_comments,
7224647Smckusick     "nfc1",	PRO_BOOL,	true,	OFF,	&format_col1_comments,
7324647Smckusick     "pcs",	PRO_BOOL,	false,	ON,	&proc_calls_space,
7424647Smckusick     "npcs",	PRO_BOOL,	false,	OFF,	&proc_calls_space,
7524647Smckusick     "ip",	PRO_BOOL,	true,	ON,	&ps.indent_parameters,
7624647Smckusick     "nip",	PRO_BOOL,	true,	OFF,	&ps.indent_parameters,
7724647Smckusick  /* see set_defaults for initialization of -cli */
7824647Smckusick     "cli",	PRO_SPECIAL,	0,	CLI,	0,
7924647Smckusick     "ci",	PRO_INT,	0,	0,	&continuation_indent,
8024647Smckusick     "cdb",	PRO_BOOL,	true,	ON,  &comment_delimiter_on_blankline,
8124647Smckusick     "ncdb",	PRO_BOOL,	true,	OFF, &comment_delimiter_on_blankline,
8224647Smckusick     "i",	PRO_INT,	8,	0,	&ps.ind_size,
8324647Smckusick     "cd",	PRO_INT,	0,	0,	&ps.decl_com_ind,
8424647Smckusick     "ce",	PRO_BOOL,	true,	ON,	&cuddle_else,
8524647Smckusick     "nce",	PRO_BOOL,	true,	OFF,	&cuddle_else,
8624647Smckusick     "c",	PRO_INT,	33,	0,	&ps.com_ind,
8724647Smckusick     "v",	PRO_BOOL,	false,	ON,	&verbose,
8824647Smckusick     "nv",	PRO_BOOL,	false,	OFF,	&verbose,
8924647Smckusick     "dj",	PRO_BOOL,	false,	ON,	&ps.ljust_decl,
9024647Smckusick     "ndj",	PRO_BOOL,	false,	OFF,	&ps.ljust_decl,
9124647Smckusick  /* don't ask *me* why -bc/-nbc is backwards.... */
9224647Smckusick     "bc",	PRO_BOOL,	true,	OFF,	&ps.leave_comma,
9324647Smckusick     "nbc",	PRO_BOOL,	true,	ON,	&ps.leave_comma,
9424647Smckusick     "di",	PRO_INT,	16,	0,	&ps.decl_indent,
9524647Smckusick     "d",	PRO_INT,	0,	0,	&ps.unindent_displace,
9624647Smckusick     "br",	PRO_BOOL,	true,	ON,	&btype_2,
9724647Smckusick     "bl",	PRO_BOOL,	true,	OFF,	&btype_2,
9824647Smckusick     "st",	PRO_SPECIAL,	0,	STDIN,	0,
9924647Smckusick     "ei",	PRO_BOOL,	true,	ON,	&ps.else_if,
10024647Smckusick     "nei",	PRO_BOOL,	true,	OFF,	&ps.else_if,
10124647Smckusick     "sc",	PRO_BOOL,	true,	ON,	&star_comment_cont,
10224647Smckusick     "nsc",	PRO_BOOL,	true,	OFF,	&star_comment_cont,
10324647Smckusick     "bap",	PRO_BOOL,	false,	ON,	&blanklines_after_procs,
10424647Smckusick     "nbap",	PRO_BOOL,	false,	OFF,	&blanklines_after_procs,
10524647Smckusick     "sob",	PRO_BOOL,	false,	ON,	&swallow_optional_blanklines,
10624647Smckusick     "nsob",	PRO_BOOL,	false,	OFF,	&swallow_optional_blanklines,
10724647Smckusick     "bad",	PRO_BOOL,	false,	ON,  &blanklines_after_declarations,
10824647Smckusick     "nbad",	PRO_BOOL,	false,	OFF, &blanklines_after_declarations,
10924647Smckusick     "bbb",	PRO_BOOL,	false,	ON,  &blanklines_before_blockcomments,
11024647Smckusick     "nbbb",	PRO_BOOL,	false,	OFF, &blanklines_before_blockcomments,
11124677Smckusick     "ps",	PRO_BOOL,	false,	ON,	&pointer_as_binop,
11224677Smckusick     "nps",	PRO_BOOL,	false,	OFF,	&pointer_as_binop,
11324647Smckusick     "troff",	PRO_BOOL,	false,	ON,	&troff,
11424647Smckusick     "T",	PRO_SPECIAL,	0,	KEY,	0,
11524647Smckusick  /* whew! */
11624647Smckusick     0,		0,		0,	0,	0
11724647Smckusick };
11824647Smckusick 
11924647Smckusick /*
12024647Smckusick  * set_profile reads $HOME/.indent.pro and ./.indent.pro and
12124647Smckusick  * handles arguments given in these files.
12224647Smckusick  */
12324647Smckusick set_profile()
12424647Smckusick {
12524647Smckusick     register FILE *f;
12624647Smckusick     char fname[BUFSIZ];
12724647Smckusick     static char pro[] = ".indent.pro";
12824647Smckusick 
12924647Smckusick     sprintf(fname, "%s/%s", getenv("HOME"), pro);
13024647Smckusick     if ((f = fopen(fname, "r")) != NULL) {
13124647Smckusick 	scan_profile(f);
13224647Smckusick 	(void) fclose(f);
13324647Smckusick     }
13424647Smckusick     if ((f = fopen(pro, "r")) != NULL) {
13524647Smckusick 	scan_profile(f);
13624647Smckusick 	(void) fclose(f);
13724647Smckusick     }
13824647Smckusick }
13924647Smckusick 
14024647Smckusick scan_profile(f)
14124647Smckusick     register FILE *f;
14224647Smckusick {
14324647Smckusick     register char *p, *arg;
14424647Smckusick     char buf[BUFSIZ];
14524647Smckusick 
14624647Smckusick     while (fgets(buf, sizeof buf, f)) {
14724647Smckusick 	if ((p = index(buf, '\n')) != NULL)
14824647Smckusick 	    *p = 0;
14924647Smckusick 	if (verbose)
15024647Smckusick 	    printf("profile: %s\n", buf);
15124647Smckusick 	p = buf;
15224647Smckusick 	for (;;) {
15324647Smckusick 	    while (isspace(*p))
15424647Smckusick 		p++;
15524647Smckusick 	    if (*p == 0)
15624647Smckusick 		break;
15724647Smckusick 	    arg = p;
15824647Smckusick 	    while (*p) {
15924647Smckusick 		if (isspace(*p)) {
16024647Smckusick 		    *p++ = 0;
16124647Smckusick 		    break;
16224647Smckusick 		}
16324647Smckusick 		p++;
16424647Smckusick 	    }
16524647Smckusick 	    set_option(arg);
16624647Smckusick 	}
16724647Smckusick     }
16824647Smckusick }
16924647Smckusick 
17024647Smckusick char       *param_start;
17124647Smckusick 
17224647Smckusick eqin(s1, s2)
17324647Smckusick     register char *s1;
17424647Smckusick     register char *s2;
17524647Smckusick {
17624647Smckusick     while (*s1) {
17724647Smckusick 	if (*s1++ != *s2++)
17824647Smckusick 	    return (false);
17924647Smckusick     }
18024647Smckusick     param_start = s2;
18124647Smckusick     return (true);
18224647Smckusick }
18324647Smckusick 
18424647Smckusick /*
18524647Smckusick  * Set the defaults.
18624647Smckusick  */
18724647Smckusick set_defaults()
18824647Smckusick {
18924647Smckusick     register struct pro *p;
19024647Smckusick 
19124647Smckusick     /*
19224647Smckusick      * Because ps.case_indent is a float, we can't initialize it
19324647Smckusick      * from the table:
19424647Smckusick      */
19524647Smckusick     ps.case_indent = 0.0;	/* -cli0.0 */
19624647Smckusick     for (p = pro; p->p_name; p++)
19724647Smckusick 	if (p->p_type != PRO_SPECIAL)
19824647Smckusick 	    *p->p_obj = p->p_default;
19924647Smckusick }
20024647Smckusick 
20124647Smckusick set_option(arg)
20224647Smckusick     register char *arg;
20324647Smckusick {
20424647Smckusick     register struct pro *p;
20524647Smckusick     extern double atof();
20624647Smckusick 
20724647Smckusick     arg++;			/* ignore leading "-" */
20824647Smckusick     for (p = pro; p->p_name; p++)
20924647Smckusick 	if (*p->p_name == *arg && eqin(p->p_name, arg))
21024647Smckusick 	    goto found;
21124647Smckusick     fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
21224647Smckusick     exit(1);
21324647Smckusick found:
21424647Smckusick     switch (p->p_type) {
21524647Smckusick 
21624647Smckusick 	case PRO_SPECIAL:
21724647Smckusick 	    switch (p->p_special) {
21824647Smckusick 
21924647Smckusick 		case IGN:
22024647Smckusick 		    break;
22124647Smckusick 
22224647Smckusick 		case CLI:
22324647Smckusick 		    if (*param_start == 0)
22424647Smckusick 			goto need_param;
22524647Smckusick 		    ps.case_indent = atof(param_start);
22624647Smckusick 		    break;
22724647Smckusick 
22824647Smckusick 		case STDIN:
22924647Smckusick 		    if (input == 0)
23024647Smckusick 			input = stdin;
23124647Smckusick 		    if (output == 0)
23224647Smckusick 			output = stdout;
23324647Smckusick 		    break;
23424647Smckusick 
23524647Smckusick 		case KEY:
23624647Smckusick 		    if (*param_start == 0)
23724647Smckusick 			goto need_param;
23824647Smckusick 		    addkey(param_start, 4);
23924647Smckusick 		    break;
24024647Smckusick 
24124647Smckusick 		default:
24224647Smckusick 		    fprintf(stderr, "\
24324647Smckusick indent: set_option: internal error: p_special %d\n", p->p_special);
24424647Smckusick 		    exit(1);
24524647Smckusick 	    }
24624647Smckusick 	    break;
24724647Smckusick 
24824647Smckusick 	case PRO_BOOL:
24924647Smckusick 	    if (p->p_special == OFF)
25024647Smckusick 		*p->p_obj = false;
25124647Smckusick 	    else
25224647Smckusick 		*p->p_obj = true;
25324647Smckusick 	    break;
25424647Smckusick 
25524647Smckusick 	case PRO_INT:
25624647Smckusick 	    if (*param_start == 0) {
25724647Smckusick need_param:
25824647Smckusick 		fprintf(stderr, "indent: ``%s'' requires a parameter\n",
25924647Smckusick 			arg - 1);
26024647Smckusick 		exit(1);
26124647Smckusick 	    }
26224647Smckusick 	    *p->p_obj = atoi(param_start);
26324647Smckusick 	    break;
26424647Smckusick 
26524647Smckusick 	default:
26624647Smckusick 	    fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
26724647Smckusick 		    p->p_type);
26824647Smckusick 	    exit(1);
26924647Smckusick     }
27024647Smckusick }
271