1 /* $NetBSD: args.c,v 1.7 2002/05/26 22:53:38 wiz Exp $ */ 2 3 /* 4 * Copyright (c) 1980, 1993 5 * The Regents of the University of California. All rights reserved. 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 #include <sys/cdefs.h> 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; 43 #else 44 __RCSID("$NetBSD: args.c,v 1.7 2002/05/26 22:53:38 wiz Exp $"); 45 #endif 46 #endif /* not lint */ 47 48 /* 49 * Argument scanning and profile reading code. Default parameters are set 50 * here as well. 51 */ 52 53 #include <ctype.h> 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include <string.h> 57 #include "indent_globs.h" 58 59 /* profile types */ 60 #define PRO_SPECIAL 1 /* special case */ 61 #define PRO_BOOL 2 /* boolean */ 62 #define PRO_INT 3 /* integer */ 63 #define PRO_FONT 4 /* troff font */ 64 65 /* profile specials for booleans */ 66 #define ON 1 /* turn it on */ 67 #define OFF 0 /* turn it off */ 68 69 /* profile specials for specials */ 70 #define IGN 1 /* ignore it */ 71 #define CLI 2 /* case label indent (float) */ 72 #define STDIN 3 /* use stdin */ 73 #define KEY 4 /* type (keyword) */ 74 75 char *option_source = "?"; 76 77 /* 78 * N.B.: because of the way the table here is scanned, options whose names are 79 * substrings of other options must occur later; that is, with -lp vs -l, -lp 80 * must be first. Also, while (most) booleans occur more than once, the last 81 * default value is the one actually assigned. 82 */ 83 struct pro { 84 char *p_name; /* name, eg -bl, -cli */ 85 int p_type; /* type (int, bool, special) */ 86 int p_default; /* the default value (if int) */ 87 int p_special; /* depends on type */ 88 int *p_obj; /* the associated variable */ 89 } pro[] = { 90 { 91 "T", PRO_SPECIAL, 0, KEY, 0 92 }, 93 { 94 "bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation 95 }, 96 { 97 "badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop 98 }, 99 { 100 "bad", PRO_BOOL, false, ON, &blanklines_after_declarations 101 }, 102 { 103 "bap", PRO_BOOL, false, ON, &blanklines_after_procs 104 }, 105 { 106 "bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments 107 }, 108 { 109 "bc", PRO_BOOL, true, OFF, &ps.leave_comma 110 }, 111 { 112 "bl", PRO_BOOL, true, OFF, &btype_2 113 }, 114 { 115 "br", PRO_BOOL, true, ON, &btype_2 116 }, 117 { 118 "bs", PRO_BOOL, false, ON, &Bill_Shannon 119 }, 120 { 121 "cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline 122 }, 123 { 124 "cd", PRO_INT, 0, 0, &ps.decl_com_ind 125 }, 126 { 127 "ce", PRO_BOOL, true, ON, &cuddle_else 128 }, 129 { 130 "ci", PRO_INT, 0, 0, &continuation_indent 131 }, 132 { 133 "cli", PRO_SPECIAL, 0, CLI, 0 134 }, 135 { 136 "c", PRO_INT, 33, 0, &ps.com_ind 137 }, 138 { 139 "di", PRO_INT, 16, 0, &ps.decl_indent 140 }, 141 { 142 "dj", PRO_BOOL, false, ON, &ps.ljust_decl 143 }, 144 { 145 "d", PRO_INT, 0, 0, &ps.unindent_displace 146 }, 147 { 148 "eei", PRO_BOOL, false, ON, &extra_expression_indent 149 }, 150 { 151 "ei", PRO_BOOL, true, ON, &ps.else_if 152 }, 153 { 154 "fbc", PRO_FONT, 0, 0, (int *) &blkcomf 155 }, 156 { 157 "fbx", PRO_FONT, 0, 0, (int *) &boxcomf 158 }, 159 { 160 "fb", PRO_FONT, 0, 0, (int *) &bodyf 161 }, 162 { 163 "fc1", PRO_BOOL, true, ON, &format_col1_comments 164 }, 165 { 166 "fc", PRO_FONT, 0, 0, (int *) &scomf 167 }, 168 { 169 "fk", PRO_FONT, 0, 0, (int *) &keywordf 170 }, 171 { 172 "fs", PRO_FONT, 0, 0, (int *) &stringf 173 }, 174 { 175 "ip", PRO_BOOL, true, ON, &ps.indent_parameters 176 }, 177 { 178 "i", PRO_INT, 8, 0, &ps.ind_size 179 }, 180 { 181 "lc", PRO_INT, 0, 0, &block_comment_max_col 182 }, 183 { 184 "lp", PRO_BOOL, true, ON, &lineup_to_parens 185 }, 186 { 187 "l", PRO_INT, 78, 0, &max_col 188 }, 189 { 190 "nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation 191 }, 192 { 193 "nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop 194 }, 195 { 196 "nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations 197 }, 198 { 199 "nbap", PRO_BOOL, false, OFF, &blanklines_after_procs 200 }, 201 { 202 "nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments 203 }, 204 { 205 "nbc", PRO_BOOL, true, ON, &ps.leave_comma 206 }, 207 { 208 "nbs", PRO_BOOL, false, OFF, &Bill_Shannon 209 }, 210 { 211 "ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline 212 }, 213 { 214 "nce", PRO_BOOL, true, OFF, &cuddle_else 215 }, 216 { 217 "ndj", PRO_BOOL, false, OFF, &ps.ljust_decl 218 }, 219 { 220 "neei", PRO_BOOL, false, OFF, &extra_expression_indent 221 }, 222 { 223 "nei", PRO_BOOL, true, OFF, &ps.else_if 224 }, 225 { 226 "nfc1", PRO_BOOL, true, OFF, &format_col1_comments 227 }, 228 { 229 "nip", PRO_BOOL, true, OFF, &ps.indent_parameters 230 }, 231 { 232 "nlp", PRO_BOOL, true, OFF, &lineup_to_parens 233 }, 234 { 235 "npcs", PRO_BOOL, false, OFF, &proc_calls_space 236 }, 237 { 238 "npro", PRO_SPECIAL, 0, IGN, 0 239 }, 240 { 241 "npsl", PRO_BOOL, true, OFF, &procnames_start_line 242 }, 243 { 244 "nps", PRO_BOOL, false, OFF, &pointer_as_binop 245 }, 246 { 247 "nsc", PRO_BOOL, true, OFF, &star_comment_cont 248 }, 249 { 250 "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines 251 }, 252 { 253 "nv", PRO_BOOL, false, OFF, &verbose 254 }, 255 { 256 "pcs", PRO_BOOL, false, ON, &proc_calls_space 257 }, 258 { 259 "psl", PRO_BOOL, true, ON, &procnames_start_line 260 }, 261 { 262 "ps", PRO_BOOL, false, ON, &pointer_as_binop 263 }, 264 { 265 "sc", PRO_BOOL, true, ON, &star_comment_cont 266 }, 267 { 268 "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines 269 }, 270 { 271 "st", PRO_SPECIAL, 0, STDIN, 0 272 }, 273 { 274 "troff", PRO_BOOL, false, ON, &troff 275 }, 276 { 277 "v", PRO_BOOL, false, ON, &verbose 278 }, 279 /* whew! */ 280 { 281 0, 0, 0, 0, 0 282 } 283 }; 284 /* 285 * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments 286 * given in these files. 287 */ 288 void 289 set_profile(void) 290 { 291 FILE *f; 292 char fname[BUFSIZ]; 293 static char prof[] = ".indent.pro"; 294 295 sprintf(fname, "%s/%s", getenv("HOME"), prof); 296 if ((f = fopen(option_source = fname, "r")) != NULL) { 297 scan_profile(f); 298 (void) fclose(f); 299 } 300 if ((f = fopen(option_source = prof, "r")) != NULL) { 301 scan_profile(f); 302 (void) fclose(f); 303 } 304 option_source = "Command line"; 305 } 306 307 void 308 scan_profile(FILE *f) 309 { 310 int i; 311 char *p; 312 char buf[BUFSIZ]; 313 314 while (1) { 315 for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p); 316 if (p != buf) { 317 *p++ = 0; 318 if (verbose) 319 printf("profile: %s\n", buf); 320 set_option(buf); 321 } else 322 if (i == EOF) 323 return; 324 } 325 } 326 327 char *param_start; 328 329 int 330 eqin(char *s1, char *s2) 331 { 332 while (*s1) { 333 if (*s1++ != *s2++) 334 return (false); 335 } 336 param_start = s2; 337 return (true); 338 } 339 /* 340 * Set the defaults. 341 */ 342 void 343 set_defaults(void) 344 { 345 struct pro *p; 346 347 /* 348 * Because ps.case_indent is a float, we can't initialize it from the 349 * table: 350 */ 351 ps.case_indent = 0.0; /* -cli0.0 */ 352 for (p = pro; p->p_name; p++) 353 if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) 354 *p->p_obj = p->p_default; 355 } 356 357 void 358 set_option(char *arg) 359 { 360 struct pro *p; 361 362 arg++; /* ignore leading "-" */ 363 for (p = pro; p->p_name; p++) 364 if (*p->p_name == *arg && eqin(p->p_name, arg)) 365 goto found; 366 fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1); 367 exit(1); 368 found: 369 switch (p->p_type) { 370 371 case PRO_SPECIAL: 372 switch (p->p_special) { 373 374 case IGN: 375 break; 376 377 case CLI: 378 if (*param_start == 0) 379 goto need_param; 380 ps.case_indent = atof(param_start); 381 break; 382 383 case STDIN: 384 if (input == 0) 385 input = stdin; 386 if (output == 0) 387 output = stdout; 388 break; 389 390 case KEY: 391 if (*param_start == 0) 392 goto need_param; 393 { 394 char *str = (char *) malloc(strlen(param_start) + 1); 395 strcpy(str, param_start); 396 addkey(str, 4); 397 } 398 break; 399 400 default: 401 fprintf(stderr, "\ 402 indent: set_option: internal error: p_special %d\n", p->p_special); 403 exit(1); 404 } 405 break; 406 407 case PRO_BOOL: 408 if (p->p_special == OFF) 409 *p->p_obj = false; 410 else 411 *p->p_obj = true; 412 break; 413 414 case PRO_INT: 415 if (!isdigit((unsigned char)*param_start)) { 416 need_param: 417 fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n", 418 option_source, arg - 1); 419 exit(1); 420 } 421 *p->p_obj = atoi(param_start); 422 break; 423 424 case PRO_FONT: 425 parsefont((struct fstate *) p->p_obj, param_start); 426 break; 427 428 default: 429 fprintf(stderr, "indent: set_option: internal error: p_type %d\n", 430 p->p_type); 431 exit(1); 432 } 433 } 434