124647Smckusick /*
235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc.
3*62037Sbostic * Copyright (c) 1980, 1993
4*62037Sbostic * The Regents of the University of California. All rights reserved.
533767Sbostic * All rights reserved.
633767Sbostic *
742687Sbostic * %sccs.include.redist.c%
824647Smckusick */
924647Smckusick
1024647Smckusick #ifndef lint
11*62037Sbostic static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 06/06/93";
1233767Sbostic #endif /* not lint */
1324647Smckusick
1424647Smckusick /*
1535500Sbostic * Argument scanning and profile reading code. Default parameters are set
1635500Sbostic * here as well.
1724647Smckusick */
1824647Smckusick
1946695Sbostic #include <stdio.h>
2046695Sbostic #include <ctype.h>
2146695Sbostic #include <stdlib.h>
2246695Sbostic #include <string.h>
2324647Smckusick #include "indent_globs.h"
2424647Smckusick
2524647Smckusick /* profile types */
2624647Smckusick #define PRO_SPECIAL 1 /* special case */
2724647Smckusick #define PRO_BOOL 2 /* boolean */
2824647Smckusick #define PRO_INT 3 /* integer */
2935500Sbostic #define PRO_FONT 4 /* troff font */
3024647Smckusick
3124647Smckusick /* profile specials for booleans */
3224647Smckusick #define ON 1 /* turn it on */
3324647Smckusick #define OFF 0 /* turn it off */
3424647Smckusick
3524647Smckusick /* profile specials for specials */
3624647Smckusick #define IGN 1 /* ignore it */
3724647Smckusick #define CLI 2 /* case label indent (float) */
3824647Smckusick #define STDIN 3 /* use stdin */
3924647Smckusick #define KEY 4 /* type (keyword) */
4024647Smckusick
4138011Sbostic char *option_source = "?";
4238011Sbostic
4324647Smckusick /*
4435500Sbostic * N.B.: because of the way the table here is scanned, options whose names are
4535500Sbostic * substrings of other options must occur later; that is, with -lp vs -l, -lp
4635500Sbostic * must be first. Also, while (most) booleans occur more than once, the last
4735500Sbostic * default value is the one actually assigned.
4824647Smckusick */
4924647Smckusick struct pro {
5035500Sbostic char *p_name; /* name, eg -bl, -cli */
5135500Sbostic int p_type; /* type (int, bool, special) */
5235500Sbostic int p_default; /* the default value (if int) */
5335500Sbostic int p_special; /* depends on type */
5435500Sbostic int *p_obj; /* the associated variable */
5535500Sbostic } pro[] = {
5635500Sbostic
5735500Sbostic "T", PRO_SPECIAL, 0, KEY, 0,
5835500Sbostic "bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation,
5935500Sbostic "badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop,
6035500Sbostic "bad", PRO_BOOL, false, ON, &blanklines_after_declarations,
6135500Sbostic "bap", PRO_BOOL, false, ON, &blanklines_after_procs,
6235500Sbostic "bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments,
6335500Sbostic "bc", PRO_BOOL, true, OFF, &ps.leave_comma,
6435500Sbostic "bl", PRO_BOOL, true, OFF, &btype_2,
6535500Sbostic "br", PRO_BOOL, true, ON, &btype_2,
6635500Sbostic "bs", PRO_BOOL, false, ON, &Bill_Shannon,
6735500Sbostic "cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline,
6835500Sbostic "cd", PRO_INT, 0, 0, &ps.decl_com_ind,
6935500Sbostic "ce", PRO_BOOL, true, ON, &cuddle_else,
7035500Sbostic "ci", PRO_INT, 0, 0, &continuation_indent,
7135500Sbostic "cli", PRO_SPECIAL, 0, CLI, 0,
7235500Sbostic "c", PRO_INT, 33, 0, &ps.com_ind,
7335500Sbostic "di", PRO_INT, 16, 0, &ps.decl_indent,
7435500Sbostic "dj", PRO_BOOL, false, ON, &ps.ljust_decl,
7535500Sbostic "d", PRO_INT, 0, 0, &ps.unindent_displace,
7635500Sbostic "eei", PRO_BOOL, false, ON, &extra_expression_indent,
7735500Sbostic "ei", PRO_BOOL, true, ON, &ps.else_if,
7835500Sbostic "fbc", PRO_FONT, 0, 0, (int *) &blkcomf,
7935500Sbostic "fbx", PRO_FONT, 0, 0, (int *) &boxcomf,
8035500Sbostic "fb", PRO_FONT, 0, 0, (int *) &bodyf,
8135500Sbostic "fc1", PRO_BOOL, true, ON, &format_col1_comments,
8235500Sbostic "fc", PRO_FONT, 0, 0, (int *) &scomf,
8335500Sbostic "fk", PRO_FONT, 0, 0, (int *) &keywordf,
8435500Sbostic "fs", PRO_FONT, 0, 0, (int *) &stringf,
8535500Sbostic "ip", PRO_BOOL, true, ON, &ps.indent_parameters,
8635500Sbostic "i", PRO_INT, 8, 0, &ps.ind_size,
8735500Sbostic "lc", PRO_INT, 0, 0, &block_comment_max_col,
8835500Sbostic "lp", PRO_BOOL, true, ON, &lineup_to_parens,
8935500Sbostic "l", PRO_INT, 78, 0, &max_col,
9035500Sbostic "nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation,
9135500Sbostic "nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop,
9235500Sbostic "nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations,
9335500Sbostic "nbap", PRO_BOOL, false, OFF, &blanklines_after_procs,
9435500Sbostic "nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments,
9535500Sbostic "nbc", PRO_BOOL, true, ON, &ps.leave_comma,
9635500Sbostic "nbs", PRO_BOOL, false, OFF, &Bill_Shannon,
9735500Sbostic "ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline,
9835500Sbostic "nce", PRO_BOOL, true, OFF, &cuddle_else,
9935500Sbostic "ndj", PRO_BOOL, false, OFF, &ps.ljust_decl,
10035500Sbostic "neei", PRO_BOOL, false, OFF, &extra_expression_indent,
10135500Sbostic "nei", PRO_BOOL, true, OFF, &ps.else_if,
10235500Sbostic "nfc1", PRO_BOOL, true, OFF, &format_col1_comments,
10335500Sbostic "nip", PRO_BOOL, true, OFF, &ps.indent_parameters,
10435500Sbostic "nlp", PRO_BOOL, true, OFF, &lineup_to_parens,
10535500Sbostic "npcs", PRO_BOOL, false, OFF, &proc_calls_space,
10635500Sbostic "npro", PRO_SPECIAL, 0, IGN, 0,
10735500Sbostic "npsl", PRO_BOOL, true, OFF, &procnames_start_line,
10835500Sbostic "nps", PRO_BOOL, false, OFF, &pointer_as_binop,
10935500Sbostic "nsc", PRO_BOOL, true, OFF, &star_comment_cont,
11035500Sbostic "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines,
11135500Sbostic "nv", PRO_BOOL, false, OFF, &verbose,
11235500Sbostic "pcs", PRO_BOOL, false, ON, &proc_calls_space,
11335500Sbostic "psl", PRO_BOOL, true, ON, &procnames_start_line,
11435500Sbostic "ps", PRO_BOOL, false, ON, &pointer_as_binop,
11535500Sbostic "sc", PRO_BOOL, true, ON, &star_comment_cont,
11635500Sbostic "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines,
11735500Sbostic "st", PRO_SPECIAL, 0, STDIN, 0,
11835500Sbostic "troff", PRO_BOOL, false, ON, &troff,
11935500Sbostic "v", PRO_BOOL, false, ON, &verbose,
12035500Sbostic /* whew! */
12135500Sbostic 0, 0, 0, 0, 0
12224647Smckusick };
12324647Smckusick
12424647Smckusick /*
12535500Sbostic * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
12635500Sbostic * given in these files.
12724647Smckusick */
set_profile()12824647Smckusick set_profile()
12924647Smckusick {
13024647Smckusick register FILE *f;
13135500Sbostic char fname[BUFSIZ];
13235508Sbostic static char prof[] = ".indent.pro";
13324647Smckusick
13435508Sbostic sprintf(fname, "%s/%s", getenv("HOME"), prof);
13538011Sbostic if ((f = fopen(option_source = fname, "r")) != NULL) {
13624647Smckusick scan_profile(f);
13724647Smckusick (void) fclose(f);
13824647Smckusick }
13938011Sbostic if ((f = fopen(option_source = prof, "r")) != NULL) {
14024647Smckusick scan_profile(f);
14124647Smckusick (void) fclose(f);
14224647Smckusick }
14338011Sbostic option_source = "Command line";
14424647Smckusick }
14524647Smckusick
scan_profile(f)14624647Smckusick scan_profile(f)
14724647Smckusick register FILE *f;
14824647Smckusick {
14935508Sbostic register int i;
15035500Sbostic register char *p;
15135500Sbostic char buf[BUFSIZ];
15224647Smckusick
15335500Sbostic while (1) {
15435508Sbostic for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
15535500Sbostic if (p != buf) {
15635500Sbostic *p++ = 0;
15735500Sbostic if (verbose)
15835500Sbostic printf("profile: %s\n", buf);
15935500Sbostic set_option(buf);
16024647Smckusick }
16135508Sbostic else if (i == EOF)
16235500Sbostic return;
16324647Smckusick }
16424647Smckusick }
16524647Smckusick
16624647Smckusick char *param_start;
16724647Smckusick
eqin(s1,s2)16824647Smckusick eqin(s1, s2)
16924647Smckusick register char *s1;
17024647Smckusick register char *s2;
17124647Smckusick {
17224647Smckusick while (*s1) {
17324647Smckusick if (*s1++ != *s2++)
17424647Smckusick return (false);
17524647Smckusick }
17624647Smckusick param_start = s2;
17724647Smckusick return (true);
17824647Smckusick }
17924647Smckusick
18024647Smckusick /*
18124647Smckusick * Set the defaults.
18224647Smckusick */
set_defaults()18324647Smckusick set_defaults()
18424647Smckusick {
18524647Smckusick register struct pro *p;
18624647Smckusick
18724647Smckusick /*
18835500Sbostic * Because ps.case_indent is a float, we can't initialize it from the
18935500Sbostic * table:
19024647Smckusick */
19124647Smckusick ps.case_indent = 0.0; /* -cli0.0 */
19224647Smckusick for (p = pro; p->p_name; p++)
19335500Sbostic if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
19424647Smckusick *p->p_obj = p->p_default;
19524647Smckusick }
19624647Smckusick
set_option(arg)19724647Smckusick set_option(arg)
19824647Smckusick register char *arg;
19924647Smckusick {
20024647Smckusick register struct pro *p;
20124647Smckusick extern double atof();
20224647Smckusick
20324647Smckusick arg++; /* ignore leading "-" */
20424647Smckusick for (p = pro; p->p_name; p++)
20524647Smckusick if (*p->p_name == *arg && eqin(p->p_name, arg))
20624647Smckusick goto found;
20738011Sbostic fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1);
20824647Smckusick exit(1);
20924647Smckusick found:
21024647Smckusick switch (p->p_type) {
21124647Smckusick
21235500Sbostic case PRO_SPECIAL:
21335500Sbostic switch (p->p_special) {
21424647Smckusick
21535500Sbostic case IGN:
21635500Sbostic break;
21724647Smckusick
21835500Sbostic case CLI:
21935500Sbostic if (*param_start == 0)
22035500Sbostic goto need_param;
22135500Sbostic ps.case_indent = atof(param_start);
22224647Smckusick break;
22324647Smckusick
22435500Sbostic case STDIN:
22535500Sbostic if (input == 0)
22635500Sbostic input = stdin;
22735500Sbostic if (output == 0)
22835500Sbostic output = stdout;
22924647Smckusick break;
23024647Smckusick
23135500Sbostic case KEY:
23235500Sbostic if (*param_start == 0)
23335500Sbostic goto need_param;
23435500Sbostic {
23535500Sbostic register char *str = (char *) malloc(strlen(param_start) + 1);
23635500Sbostic strcpy(str, param_start);
23735500Sbostic addkey(str, 4);
23824647Smckusick }
23924647Smckusick break;
24024647Smckusick
24124647Smckusick default:
24235500Sbostic fprintf(stderr, "\
24335500Sbostic indent: set_option: internal error: p_special %d\n", p->p_special);
24424647Smckusick exit(1);
24535500Sbostic }
24635500Sbostic break;
24735500Sbostic
24835500Sbostic case PRO_BOOL:
24935500Sbostic if (p->p_special == OFF)
25035500Sbostic *p->p_obj = false;
25135500Sbostic else
25235500Sbostic *p->p_obj = true;
25335500Sbostic break;
25435500Sbostic
25535500Sbostic case PRO_INT:
25638011Sbostic if (!isdigit(*param_start)) {
25735500Sbostic need_param:
25838011Sbostic fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n",
25938011Sbostic option_source, arg - 1);
26035500Sbostic exit(1);
26135500Sbostic }
26235500Sbostic *p->p_obj = atoi(param_start);
26335500Sbostic break;
26435500Sbostic
26535500Sbostic case PRO_FONT:
26635500Sbostic parsefont((struct fstate *) p->p_obj, param_start);
26735500Sbostic break;
26835500Sbostic
26935500Sbostic default:
27035500Sbostic fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
27135500Sbostic p->p_type);
27235500Sbostic exit(1);
27324647Smckusick }
27424647Smckusick }
275