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