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