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