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