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