1 /* $NetBSD: args.c,v 1.13 2016/02/22 21:20:29 ginsbach 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.13 2016/02/22 21:20:29 ginsbach 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 <err.h> 82 #include <stdio.h> 83 #include <stdlib.h> 84 #include <string.h> 85 #include "indent_globs.h" 86 87 /* profile types */ 88 #define PRO_SPECIAL 1 /* special case */ 89 #define PRO_BOOL 2 /* boolean */ 90 #define PRO_INT 3 /* integer */ 91 #define PRO_FONT 4 /* troff font */ 92 93 /* profile specials for booleans */ 94 #define ON 1 /* turn it on */ 95 #define OFF 0 /* turn it off */ 96 97 /* profile specials for specials */ 98 #define IGN 1 /* ignore it */ 99 #define CLI 2 /* case label indent (float) */ 100 #define STDIN 3 /* use stdin */ 101 #define KEY 4 /* type (keyword) */ 102 103 const char *option_source = "?"; 104 105 /* 106 * N.B.: because of the way the table here is scanned, options whose names are 107 * substrings of other options must occur later; that is, with -lp vs -l, -lp 108 * must be first. Also, while (most) booleans occur more than once, the last 109 * default value is the one actually assigned. 110 */ 111 struct pro { 112 const char *p_name; /* name, eg -bl, -cli */ 113 int p_type; /* type (int, bool, special) */ 114 int p_default; /* the default value (if int) */ 115 int p_special; /* depends on type */ 116 int *p_obj; /* the associated variable */ 117 } pro[] = { 118 { 119 "T", PRO_SPECIAL, 0, KEY, 0 120 }, 121 { 122 "bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation 123 }, 124 { 125 "badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop 126 }, 127 { 128 "bad", PRO_BOOL, false, ON, &blanklines_after_declarations 129 }, 130 { 131 "bap", PRO_BOOL, false, ON, &blanklines_after_procs 132 }, 133 { 134 "bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments 135 }, 136 { 137 "bc", PRO_BOOL, true, OFF, &ps.leave_comma 138 }, 139 { 140 "bl", PRO_BOOL, true, OFF, &btype_2 141 }, 142 { 143 "br", PRO_BOOL, true, ON, &btype_2 144 }, 145 { 146 "bs", PRO_BOOL, false, ON, &Bill_Shannon 147 }, 148 { 149 "cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline 150 }, 151 { 152 "cd", PRO_INT, 0, 0, &ps.decl_com_ind 153 }, 154 { 155 "ce", PRO_BOOL, true, ON, &cuddle_else 156 }, 157 { 158 "ci", PRO_INT, 0, 0, &continuation_indent 159 }, 160 { 161 "cli", PRO_SPECIAL, 0, CLI, 0 162 }, 163 { 164 "c", PRO_INT, 33, 0, &ps.com_ind 165 }, 166 { 167 "di", PRO_INT, 16, 0, &ps.decl_indent 168 }, 169 { 170 "dj", PRO_BOOL, false, ON, &ps.ljust_decl 171 }, 172 { 173 "d", PRO_INT, 0, 0, &ps.unindent_displace 174 }, 175 { 176 "eei", PRO_BOOL, false, ON, &extra_expression_indent 177 }, 178 { 179 "ei", PRO_BOOL, true, ON, &ps.else_if 180 }, 181 { 182 "fbc", PRO_FONT, 0, 0, (int *) &blkcomf 183 }, 184 { 185 "fbx", PRO_FONT, 0, 0, (int *) &boxcomf 186 }, 187 { 188 "fb", PRO_FONT, 0, 0, (int *) &bodyf 189 }, 190 { 191 "fc1", PRO_BOOL, true, ON, &format_col1_comments 192 }, 193 { 194 "fc", PRO_FONT, 0, 0, (int *) &scomf 195 }, 196 { 197 "fk", PRO_FONT, 0, 0, (int *) &keywordf 198 }, 199 { 200 "fs", PRO_FONT, 0, 0, (int *) &stringf 201 }, 202 { 203 "ip", PRO_BOOL, true, ON, &ps.indent_parameters 204 }, 205 { 206 "i", PRO_INT, 8, 0, &ps.ind_size 207 }, 208 { 209 "lc", PRO_INT, 0, 0, &block_comment_max_col 210 }, 211 { 212 "lp", PRO_BOOL, true, ON, &lineup_to_parens 213 }, 214 { 215 "l", PRO_INT, 78, 0, &max_col 216 }, 217 { 218 "nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation 219 }, 220 { 221 "nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop 222 }, 223 { 224 "nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations 225 }, 226 { 227 "nbap", PRO_BOOL, false, OFF, &blanklines_after_procs 228 }, 229 { 230 "nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments 231 }, 232 { 233 "nbc", PRO_BOOL, true, ON, &ps.leave_comma 234 }, 235 { 236 "nbs", PRO_BOOL, false, OFF, &Bill_Shannon 237 }, 238 { 239 "ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline 240 }, 241 { 242 "nce", PRO_BOOL, true, OFF, &cuddle_else 243 }, 244 { 245 "ndj", PRO_BOOL, false, OFF, &ps.ljust_decl 246 }, 247 { 248 "neei", PRO_BOOL, false, OFF, &extra_expression_indent 249 }, 250 { 251 "nei", PRO_BOOL, true, OFF, &ps.else_if 252 }, 253 { 254 "nfc1", PRO_BOOL, true, OFF, &format_col1_comments 255 }, 256 { 257 "nip", PRO_BOOL, true, OFF, &ps.indent_parameters 258 }, 259 { 260 "nlp", PRO_BOOL, true, OFF, &lineup_to_parens 261 }, 262 { 263 "npcs", PRO_BOOL, false, OFF, &proc_calls_space 264 }, 265 { 266 "npro", PRO_SPECIAL, 0, IGN, 0 267 }, 268 { 269 "npsl", PRO_BOOL, true, OFF, &procnames_start_line 270 }, 271 { 272 "nps", PRO_BOOL, false, OFF, &pointer_as_binop 273 }, 274 { 275 "nsc", PRO_BOOL, true, OFF, &star_comment_cont 276 }, 277 { 278 "nut", PRO_BOOL, true, OFF, &use_tabs 279 }, 280 { 281 "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines 282 }, 283 { 284 "nv", PRO_BOOL, false, OFF, &verbose 285 }, 286 { 287 "pcs", PRO_BOOL, false, ON, &proc_calls_space 288 }, 289 { 290 "psl", PRO_BOOL, true, ON, &procnames_start_line 291 }, 292 { 293 "ps", PRO_BOOL, false, ON, &pointer_as_binop 294 }, 295 { 296 "sc", PRO_BOOL, true, ON, &star_comment_cont 297 }, 298 { 299 "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines 300 }, 301 { 302 "st", PRO_SPECIAL, 0, STDIN, 0 303 }, 304 { 305 "troff", PRO_BOOL, false, ON, &troff 306 }, 307 { 308 "ut", PRO_BOOL, true, ON, &use_tabs 309 }, 310 { 311 "v", PRO_BOOL, false, ON, &verbose 312 }, 313 /* whew! */ 314 { 315 0, 0, 0, 0, 0 316 } 317 }; 318 /* 319 * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments 320 * given in these files. 321 */ 322 void 323 set_profile(void) 324 { 325 FILE *f; 326 char fname[BUFSIZ]; 327 static char prof[] = ".indent.pro"; 328 329 snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); 330 if ((f = fopen(option_source = fname, "r")) != NULL) { 331 scan_profile(f); 332 (void) fclose(f); 333 } 334 if ((f = fopen(option_source = prof, "r")) != NULL) { 335 scan_profile(f); 336 (void) fclose(f); 337 } 338 option_source = "Command line"; 339 } 340 341 void 342 scan_profile(FILE *f) 343 { 344 int i; 345 char *p; 346 char buf[BUFSIZ]; 347 348 while (1) { 349 for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p); 350 if (p != buf) { 351 *p++ = 0; 352 if (verbose) 353 printf("profile: %s\n", buf); 354 set_option(buf); 355 } else 356 if (i == EOF) 357 return; 358 } 359 } 360 361 const char *param_start; 362 363 int 364 eqin(const char *s1, const char *s2) 365 { 366 while (*s1) { 367 if (*s1++ != *s2++) 368 return (false); 369 } 370 param_start = s2; 371 return (true); 372 } 373 /* 374 * Set the defaults. 375 */ 376 void 377 set_defaults(void) 378 { 379 struct pro *p; 380 381 /* 382 * Because ps.case_indent is a float, we can't initialize it from the 383 * table: 384 */ 385 ps.case_indent = 0.0; /* -cli0.0 */ 386 for (p = pro; p->p_name; p++) 387 if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) 388 *p->p_obj = p->p_default; 389 } 390 391 void 392 set_option(char *arg) 393 { 394 struct pro *p; 395 396 arg++; /* ignore leading "-" */ 397 for (p = pro; p->p_name; p++) 398 if (*p->p_name == *arg && eqin(p->p_name, arg)) 399 goto found; 400 errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 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 errx(1, "set_option: internal error: p_special %d", 436 p->p_special); 437 } 438 break; 439 440 case PRO_BOOL: 441 if (p->p_special == OFF) 442 *p->p_obj = false; 443 else 444 *p->p_obj = true; 445 break; 446 447 case PRO_INT: 448 if (!isdigit((unsigned char)*param_start)) { 449 need_param: 450 errx(1, "%s: ``%s'' requires a parameter", 451 option_source, arg - 1); 452 } 453 *p->p_obj = atoi(param_start); 454 break; 455 456 case PRO_FONT: 457 parsefont((struct fstate *) p->p_obj, param_start); 458 break; 459 460 default: 461 errx(1, "set_option: internal error: p_type %d", p->p_type); 462 } 463 } 464