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