11590Srgrimes/* 21590Srgrimes * Copyright (c) 1985 Sun Microsystems, Inc. 31590Srgrimes * Copyright (c) 1980, 1993 41590Srgrimes * The Regents of the University of California. All rights reserved. 51590Srgrimes * All rights reserved. 61590Srgrimes * 71590Srgrimes * Redistribution and use in source and binary forms, with or without 81590Srgrimes * modification, are permitted provided that the following conditions 91590Srgrimes * are met: 101590Srgrimes * 1. Redistributions of source code must retain the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer. 121590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131590Srgrimes * notice, this list of conditions and the following disclaimer in the 141590Srgrimes * documentation and/or other materials provided with the distribution. 151590Srgrimes * 3. All advertising materials mentioning features or use of this software 161590Srgrimes * must display the following acknowledgement: 171590Srgrimes * This product includes software developed by the University of 181590Srgrimes * California, Berkeley and its contributors. 191590Srgrimes * 4. Neither the name of the University nor the names of its contributors 201590Srgrimes * may be used to endorse or promote products derived from this software 211590Srgrimes * without specific prior written permission. 221590Srgrimes * 231590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 241590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 251590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 261590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 271590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 281590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 291590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 301590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 311590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 321590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 331590Srgrimes * SUCH DAMAGE. 341590Srgrimes */ 351590Srgrimes 36116390Scharnier#if 0 371590Srgrimes#ifndef lint 381590Srgrimesstatic char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; 39116390Scharnier#endif /* not lint */ 4027419Scharnier#endif 41116390Scharnier 4299112Sobrien#include <sys/cdefs.h> 4399112Sobrien__FBSDID("$FreeBSD$"); 441590Srgrimes 451590Srgrimes/* 461590Srgrimes * Argument scanning and profile reading code. Default parameters are set 471590Srgrimes * here as well. 481590Srgrimes */ 491590Srgrimes 5027419Scharnier#include <ctype.h> 5127419Scharnier#include <err.h> 52135477Sdas#include <limits.h> 531590Srgrimes#include <stdio.h> 541590Srgrimes#include <stdlib.h> 551590Srgrimes#include <string.h> 561590Srgrimes#include "indent_globs.h" 5785632Sschweikh#include "indent.h" 581590Srgrimes 591590Srgrimes/* profile types */ 601590Srgrimes#define PRO_SPECIAL 1 /* special case */ 611590Srgrimes#define PRO_BOOL 2 /* boolean */ 621590Srgrimes#define PRO_INT 3 /* integer */ 631590Srgrimes#define PRO_FONT 4 /* troff font */ 641590Srgrimes 651590Srgrimes/* profile specials for booleans */ 661590Srgrimes#define ON 1 /* turn it on */ 671590Srgrimes#define OFF 0 /* turn it off */ 681590Srgrimes 691590Srgrimes/* profile specials for specials */ 701590Srgrimes#define IGN 1 /* ignore it */ 711590Srgrimes#define CLI 2 /* case label indent (float) */ 721590Srgrimes#define STDIN 3 /* use stdin */ 731590Srgrimes#define KEY 4 /* type (keyword) */ 741590Srgrimes 7585632Sschweikhstatic void scan_profile(FILE *); 7685632Sschweikh 7793440Sdwmaloneconst char *option_source = "?"; 781590Srgrimes 791590Srgrimes/* 801590Srgrimes * N.B.: because of the way the table here is scanned, options whose names are 811590Srgrimes * substrings of other options must occur later; that is, with -lp vs -l, -lp 821590Srgrimes * must be first. Also, while (most) booleans occur more than once, the last 831590Srgrimes * default value is the one actually assigned. 841590Srgrimes */ 851590Srgrimesstruct pro { 86116390Scharnier const char *p_name; /* name, e.g. -bl, -cli */ 871590Srgrimes int p_type; /* type (int, bool, special) */ 881590Srgrimes int p_default; /* the default value (if int) */ 891590Srgrimes int p_special; /* depends on type */ 901590Srgrimes int *p_obj; /* the associated variable */ 911590Srgrimes} pro[] = { 921590Srgrimes 9385632Sschweikh {"T", PRO_SPECIAL, 0, KEY, 0}, 9485632Sschweikh {"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation}, 9585632Sschweikh {"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop}, 9685632Sschweikh {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations}, 9785632Sschweikh {"bap", PRO_BOOL, false, ON, &blanklines_after_procs}, 9885632Sschweikh {"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments}, 9985632Sschweikh {"bc", PRO_BOOL, true, OFF, &ps.leave_comma}, 10085632Sschweikh {"bl", PRO_BOOL, true, OFF, &btype_2}, 10185632Sschweikh {"br", PRO_BOOL, true, ON, &btype_2}, 10285632Sschweikh {"bs", PRO_BOOL, false, ON, &Bill_Shannon}, 10385632Sschweikh {"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline}, 10485632Sschweikh {"cd", PRO_INT, 0, 0, &ps.decl_com_ind}, 10585632Sschweikh {"ce", PRO_BOOL, true, ON, &cuddle_else}, 10685632Sschweikh {"ci", PRO_INT, 0, 0, &continuation_indent}, 10785632Sschweikh {"cli", PRO_SPECIAL, 0, CLI, 0}, 10885632Sschweikh {"c", PRO_INT, 33, 0, &ps.com_ind}, 10985632Sschweikh {"di", PRO_INT, 16, 0, &ps.decl_indent}, 11085632Sschweikh {"dj", PRO_BOOL, false, ON, &ps.ljust_decl}, 11185632Sschweikh {"d", PRO_INT, 0, 0, &ps.unindent_displace}, 11285632Sschweikh {"eei", PRO_BOOL, false, ON, &extra_expression_indent}, 11385632Sschweikh {"ei", PRO_BOOL, true, ON, &ps.else_if}, 11485632Sschweikh {"fbc", PRO_FONT, 0, 0, (int *) &blkcomf}, 115131184Sschweikh {"fbs", PRO_BOOL, true, ON, &function_brace_split}, 11685632Sschweikh {"fbx", PRO_FONT, 0, 0, (int *) &boxcomf}, 11785632Sschweikh {"fb", PRO_FONT, 0, 0, (int *) &bodyf}, 11885632Sschweikh {"fc1", PRO_BOOL, true, ON, &format_col1_comments}, 11985632Sschweikh {"fcb", PRO_BOOL, true, ON, &format_block_comments}, 12085632Sschweikh {"fc", PRO_FONT, 0, 0, (int *) &scomf}, 12185632Sschweikh {"fk", PRO_FONT, 0, 0, (int *) &keywordf}, 12285632Sschweikh {"fs", PRO_FONT, 0, 0, (int *) &stringf}, 12385632Sschweikh {"ip", PRO_BOOL, true, ON, &ps.indent_parameters}, 12485632Sschweikh {"i", PRO_INT, 8, 0, &ps.ind_size}, 12585632Sschweikh {"lc", PRO_INT, 0, 0, &block_comment_max_col}, 126125633Sbde {"ldi", PRO_INT, -1, 0, &ps.local_decl_indent}, 12785632Sschweikh {"lp", PRO_BOOL, true, ON, &lineup_to_parens}, 12885632Sschweikh {"l", PRO_INT, 78, 0, &max_col}, 12985632Sschweikh {"nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation}, 13085632Sschweikh {"nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop}, 13185632Sschweikh {"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations}, 13285632Sschweikh {"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs}, 13385632Sschweikh {"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments}, 13485632Sschweikh {"nbc", PRO_BOOL, true, ON, &ps.leave_comma}, 13585632Sschweikh {"nbs", PRO_BOOL, false, OFF, &Bill_Shannon}, 13685632Sschweikh {"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline}, 13785632Sschweikh {"nce", PRO_BOOL, true, OFF, &cuddle_else}, 13885632Sschweikh {"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl}, 13985632Sschweikh {"neei", PRO_BOOL, false, OFF, &extra_expression_indent}, 14085632Sschweikh {"nei", PRO_BOOL, true, OFF, &ps.else_if}, 141131184Sschweikh {"nfbs", PRO_BOOL, true, OFF, &function_brace_split}, 14285632Sschweikh {"nfc1", PRO_BOOL, true, OFF, &format_col1_comments}, 14385632Sschweikh {"nfcb", PRO_BOOL, true, OFF, &format_block_comments}, 14485632Sschweikh {"nip", PRO_BOOL, true, OFF, &ps.indent_parameters}, 14585632Sschweikh {"nlp", PRO_BOOL, true, OFF, &lineup_to_parens}, 14685632Sschweikh {"npcs", PRO_BOOL, false, OFF, &proc_calls_space}, 14785632Sschweikh {"npro", PRO_SPECIAL, 0, IGN, 0}, 14885632Sschweikh {"npsl", PRO_BOOL, true, OFF, &procnames_start_line}, 14985632Sschweikh {"nps", PRO_BOOL, false, OFF, &pointer_as_binop}, 15085632Sschweikh {"nsc", PRO_BOOL, true, OFF, &star_comment_cont}, 15185632Sschweikh {"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines}, 152131184Sschweikh {"nut", PRO_BOOL, true, OFF, &use_tabs}, 15385632Sschweikh {"nv", PRO_BOOL, false, OFF, &verbose}, 15485632Sschweikh {"pcs", PRO_BOOL, false, ON, &proc_calls_space}, 15585632Sschweikh {"psl", PRO_BOOL, true, ON, &procnames_start_line}, 15685632Sschweikh {"ps", PRO_BOOL, false, ON, &pointer_as_binop}, 15785632Sschweikh {"sc", PRO_BOOL, true, ON, &star_comment_cont}, 15885632Sschweikh {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines}, 15985632Sschweikh {"st", PRO_SPECIAL, 0, STDIN, 0}, 160205989Savg {"ta", PRO_BOOL, false, ON, &auto_typedefs}, 16185632Sschweikh {"troff", PRO_BOOL, false, ON, &troff}, 162131184Sschweikh {"ut", PRO_BOOL, true, ON, &use_tabs}, 16385632Sschweikh {"v", PRO_BOOL, false, ON, &verbose}, 1641590Srgrimes /* whew! */ 16585632Sschweikh {0, 0, 0, 0, 0} 1661590Srgrimes}; 1671590Srgrimes 1681590Srgrimes/* 1691590Srgrimes * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments 1701590Srgrimes * given in these files. 1711590Srgrimes */ 17285632Sschweikhvoid 17385632Sschweikhset_profile(void) 1741590Srgrimes{ 17598771Sjmallett FILE *f; 176135477Sdas char fname[PATH_MAX]; 1771590Srgrimes static char prof[] = ".indent.pro"; 1781590Srgrimes 179135477Sdas snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); 1801590Srgrimes if ((f = fopen(option_source = fname, "r")) != NULL) { 1811590Srgrimes scan_profile(f); 1821590Srgrimes (void) fclose(f); 1831590Srgrimes } 1841590Srgrimes if ((f = fopen(option_source = prof, "r")) != NULL) { 1851590Srgrimes scan_profile(f); 1861590Srgrimes (void) fclose(f); 1871590Srgrimes } 1881590Srgrimes option_source = "Command line"; 1891590Srgrimes} 1901590Srgrimes 19185632Sschweikhstatic void 19298771Sjmallettscan_profile(FILE *f) 1931590Srgrimes{ 194127256Sdes int comment, i; 195127256Sdes char *p; 1961590Srgrimes char buf[BUFSIZ]; 1971590Srgrimes 1981590Srgrimes while (1) { 199127256Sdes p = buf; 200127256Sdes comment = 0; 201127256Sdes while ((i = getc(f)) != EOF) { 202127256Sdes if (i == '*' && !comment && p > buf && p[-1] == '/') { 203127256Sdes comment = p - buf; 204127256Sdes *p++ = i; 205127256Sdes } else if (i == '/' && comment && p > buf && p[-1] == '*') { 206127256Sdes p = buf + comment - 1; 207127256Sdes comment = 0; 208127256Sdes } else if (isspace(i)) { 209127256Sdes if (p > buf && !comment) 210127256Sdes break; 211127256Sdes } else { 212127256Sdes *p++ = i; 213127256Sdes } 214127256Sdes } 2151590Srgrimes if (p != buf) { 2161590Srgrimes *p++ = 0; 2171590Srgrimes if (verbose) 2181590Srgrimes printf("profile: %s\n", buf); 2191590Srgrimes set_option(buf); 2201590Srgrimes } 2211590Srgrimes else if (i == EOF) 2221590Srgrimes return; 2231590Srgrimes } 2241590Srgrimes} 2251590Srgrimes 22693440Sdwmaloneconst char *param_start; 2271590Srgrimes 22885632Sschweikhstatic int 22993440Sdwmaloneeqin(const char *s1, const char *s2) 2301590Srgrimes{ 2311590Srgrimes while (*s1) { 2321590Srgrimes if (*s1++ != *s2++) 2331590Srgrimes return (false); 2341590Srgrimes } 2351590Srgrimes param_start = s2; 2361590Srgrimes return (true); 2371590Srgrimes} 2381590Srgrimes 2391590Srgrimes/* 2401590Srgrimes * Set the defaults. 2411590Srgrimes */ 24285632Sschweikhvoid 24385632Sschweikhset_defaults(void) 2441590Srgrimes{ 24598771Sjmallett struct pro *p; 2461590Srgrimes 2471590Srgrimes /* 2481590Srgrimes * Because ps.case_indent is a float, we can't initialize it from the 2491590Srgrimes * table: 2501590Srgrimes */ 2511590Srgrimes ps.case_indent = 0.0; /* -cli0.0 */ 2521590Srgrimes for (p = pro; p->p_name; p++) 2531590Srgrimes if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) 2541590Srgrimes *p->p_obj = p->p_default; 2551590Srgrimes} 2561590Srgrimes 25785632Sschweikhvoid 25885632Sschweikhset_option(char *arg) 2591590Srgrimes{ 26098771Sjmallett struct pro *p; 2611590Srgrimes 2621590Srgrimes arg++; /* ignore leading "-" */ 2631590Srgrimes for (p = pro; p->p_name; p++) 2641590Srgrimes if (*p->p_name == *arg && eqin(p->p_name, arg)) 2651590Srgrimes goto found; 26627419Scharnier errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); 2671590Srgrimesfound: 2681590Srgrimes switch (p->p_type) { 2691590Srgrimes 2701590Srgrimes case PRO_SPECIAL: 2711590Srgrimes switch (p->p_special) { 2721590Srgrimes 2731590Srgrimes case IGN: 2741590Srgrimes break; 2751590Srgrimes 2761590Srgrimes case CLI: 2771590Srgrimes if (*param_start == 0) 2781590Srgrimes goto need_param; 2791590Srgrimes ps.case_indent = atof(param_start); 2801590Srgrimes break; 2811590Srgrimes 2821590Srgrimes case STDIN: 2831590Srgrimes if (input == 0) 2841590Srgrimes input = stdin; 2851590Srgrimes if (output == 0) 2861590Srgrimes output = stdout; 2871590Srgrimes break; 2881590Srgrimes 2891590Srgrimes case KEY: 2901590Srgrimes if (*param_start == 0) 2911590Srgrimes goto need_param; 2921590Srgrimes { 293135477Sdas char *str = strdup(param_start); 294116390Scharnier if (str == NULL) 295116390Scharnier err(1, NULL); 2961590Srgrimes addkey(str, 4); 2971590Srgrimes } 2981590Srgrimes break; 2991590Srgrimes 3001590Srgrimes default: 30127419Scharnier errx(1, "set_option: internal error: p_special %d", p->p_special); 3021590Srgrimes } 3031590Srgrimes break; 3041590Srgrimes 3051590Srgrimes case PRO_BOOL: 3061590Srgrimes if (p->p_special == OFF) 3071590Srgrimes *p->p_obj = false; 3081590Srgrimes else 3091590Srgrimes *p->p_obj = true; 3101590Srgrimes break; 3111590Srgrimes 3121590Srgrimes case PRO_INT: 3131590Srgrimes if (!isdigit(*param_start)) { 3141590Srgrimes need_param: 31527419Scharnier errx(1, "%s: ``%s'' requires a parameter", option_source, arg - 1); 3161590Srgrimes } 3171590Srgrimes *p->p_obj = atoi(param_start); 3181590Srgrimes break; 3191590Srgrimes 3201590Srgrimes case PRO_FONT: 3211590Srgrimes parsefont((struct fstate *) p->p_obj, param_start); 3221590Srgrimes break; 3231590Srgrimes 3241590Srgrimes default: 32527419Scharnier errx(1, "set_option: internal error: p_type %d", p->p_type); 3261590Srgrimes } 3271590Srgrimes} 328