1 /* $NetBSD: args.c,v 1.10 2009/04/12 11:09:49 lukem 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.10 2009/04/12 11:09:49 lukem 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 "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines 278 }, 279 { 280 "nv", PRO_BOOL, false, OFF, &verbose 281 }, 282 { 283 "pcs", PRO_BOOL, false, ON, &proc_calls_space 284 }, 285 { 286 "psl", PRO_BOOL, true, ON, &procnames_start_line 287 }, 288 { 289 "ps", PRO_BOOL, false, ON, &pointer_as_binop 290 }, 291 { 292 "sc", PRO_BOOL, true, ON, &star_comment_cont 293 }, 294 { 295 "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines 296 }, 297 { 298 "st", PRO_SPECIAL, 0, STDIN, 0 299 }, 300 { 301 "troff", PRO_BOOL, false, ON, &troff 302 }, 303 { 304 "v", PRO_BOOL, false, ON, &verbose 305 }, 306 /* whew! */ 307 { 308 0, 0, 0, 0, 0 309 } 310 }; 311 /* 312 * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments 313 * given in these files. 314 */ 315 void 316 set_profile(void) 317 { 318 FILE *f; 319 char fname[BUFSIZ]; 320 static char prof[] = ".indent.pro"; 321 322 snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); 323 if ((f = fopen(option_source = fname, "r")) != NULL) { 324 scan_profile(f); 325 (void) fclose(f); 326 } 327 if ((f = fopen(option_source = prof, "r")) != NULL) { 328 scan_profile(f); 329 (void) fclose(f); 330 } 331 option_source = "Command line"; 332 } 333 334 void 335 scan_profile(FILE *f) 336 { 337 int i; 338 char *p; 339 char buf[BUFSIZ]; 340 341 while (1) { 342 for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p); 343 if (p != buf) { 344 *p++ = 0; 345 if (verbose) 346 printf("profile: %s\n", buf); 347 set_option(buf); 348 } else 349 if (i == EOF) 350 return; 351 } 352 } 353 354 const char *param_start; 355 356 int 357 eqin(const char *s1, const char *s2) 358 { 359 while (*s1) { 360 if (*s1++ != *s2++) 361 return (false); 362 } 363 param_start = s2; 364 return (true); 365 } 366 /* 367 * Set the defaults. 368 */ 369 void 370 set_defaults(void) 371 { 372 struct pro *p; 373 374 /* 375 * Because ps.case_indent is a float, we can't initialize it from the 376 * table: 377 */ 378 ps.case_indent = 0.0; /* -cli0.0 */ 379 for (p = pro; p->p_name; p++) 380 if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) 381 *p->p_obj = p->p_default; 382 } 383 384 void 385 set_option(char *arg) 386 { 387 struct pro *p; 388 389 arg++; /* ignore leading "-" */ 390 for (p = pro; p->p_name; p++) 391 if (*p->p_name == *arg && eqin(p->p_name, arg)) 392 goto found; 393 fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1); 394 exit(1); 395 found: 396 switch (p->p_type) { 397 398 case PRO_SPECIAL: 399 switch (p->p_special) { 400 401 case IGN: 402 break; 403 404 case CLI: 405 if (*param_start == 0) 406 goto need_param; 407 ps.case_indent = atof(param_start); 408 break; 409 410 case STDIN: 411 if (input == 0) 412 input = stdin; 413 if (output == 0) 414 output = stdout; 415 break; 416 417 case KEY: 418 if (*param_start == 0) 419 goto need_param; 420 { 421 char *str; 422 423 str = strdup(param_start); 424 addkey(str, 4); 425 } 426 break; 427 428 default: 429 fprintf(stderr, "\ 430 indent: set_option: internal error: p_special %d\n", p->p_special); 431 exit(1); 432 } 433 break; 434 435 case PRO_BOOL: 436 if (p->p_special == OFF) 437 *p->p_obj = false; 438 else 439 *p->p_obj = true; 440 break; 441 442 case PRO_INT: 443 if (!isdigit((unsigned char)*param_start)) { 444 need_param: 445 fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n", 446 option_source, arg - 1); 447 exit(1); 448 } 449 *p->p_obj = atoi(param_start); 450 break; 451 452 case PRO_FONT: 453 parsefont((struct fstate *) p->p_obj, param_start); 454 break; 455 456 default: 457 fprintf(stderr, "indent: set_option: internal error: p_type %d\n", 458 p->p_type); 459 exit(1); 460 } 461 } 462