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