mirror of
git://git.psyced.org/git/psyclpc
synced 2024-08-15 03:20:16 +00:00
417 lines
13 KiB
C
417 lines
13 KiB
C
|
/*
|
||
|
* Copyright (c) 1985 Sun Microsystems, Inc.
|
||
|
* Copyright (c) 1980 The Regents of the University of California.
|
||
|
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms are permitted
|
||
|
* provided that the above copyright notice and this paragraph are
|
||
|
* duplicated in all such forms and that any documentation,
|
||
|
* advertising materials, and other materials related to such
|
||
|
* distribution and use acknowledge that the software was developed
|
||
|
* by the University of California, Berkeley, the University of Illinois,
|
||
|
* Urbana, and Sun Microsystems, Inc. The name of either University
|
||
|
* or Sun Microsystems may not be used to endorse or promote products
|
||
|
* derived from this software without specific prior written permission.
|
||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
*/
|
||
|
|
||
|
#ifndef lint
|
||
|
static char sccsid[] = "@(#)args.c 5.6 (Berkeley) 9/15/88";
|
||
|
#endif /* not lint */
|
||
|
|
||
|
/*
|
||
|
* Argument scanning and profile reading code. Default parameters are set
|
||
|
* here as well.
|
||
|
*/
|
||
|
|
||
|
#include "indent_globs.h"
|
||
|
#include <ctype.h>
|
||
|
#include "version.h"
|
||
|
|
||
|
int else_endif_col;
|
||
|
|
||
|
extern char *in_name;
|
||
|
|
||
|
char *getenv();
|
||
|
|
||
|
/* profile types */
|
||
|
enum profile {PRO_BOOL, /* boolean */
|
||
|
PRO_INT, /* integer */
|
||
|
PRO_FONT, /* troff font */
|
||
|
PRO_IGN, /* ignore it */
|
||
|
PRO_STDIN, /* -st switch */
|
||
|
PRO_KEY, /* -T switch */
|
||
|
PRO_SETTINGS, /* bundled set of settings */
|
||
|
PRO_PRSTRING /* Print string and exit */
|
||
|
};
|
||
|
|
||
|
/* profile specials for booleans */
|
||
|
enum on_or_off {OFF,ON};
|
||
|
|
||
|
/* Explicit flags for each option. */
|
||
|
static int exp_T = 0;
|
||
|
static int exp_bacc = 0;
|
||
|
static int exp_badp = 0;
|
||
|
static int exp_bad = 0;
|
||
|
static int exp_bap = 0;
|
||
|
static int exp_bbb = 0;
|
||
|
static int exp_bc = 0;
|
||
|
static int exp_bli = 0;
|
||
|
static int exp_bl = 0;
|
||
|
static int exp_bs = 0;
|
||
|
static int exp_cdb = 0;
|
||
|
static int exp_cd = 0;
|
||
|
static int exp_ce = 0;
|
||
|
static int exp_ci = 0;
|
||
|
static int exp_cli = 0;
|
||
|
static int exp_cp = 0;
|
||
|
static int exp_c = 0;
|
||
|
static int exp_di = 0;
|
||
|
static int exp_dj = 0;
|
||
|
static int exp_d = 0;
|
||
|
static int exp_eei = 0;
|
||
|
static int exp_ei = 0;
|
||
|
static int exp_fbc = 0;
|
||
|
static int exp_fbx = 0;
|
||
|
static int exp_fb = 0;
|
||
|
static int exp_fc1 = 0;
|
||
|
static int exp_fca = 0;
|
||
|
static int exp_fc = 0;
|
||
|
static int exp_fk = 0;
|
||
|
static int exp_fs = 0;
|
||
|
static int exp_gnu = 0;
|
||
|
static int exp_ip = 0;
|
||
|
static int exp_i = 0;
|
||
|
static int exp_lc = 0;
|
||
|
static int exp_lp = 0;
|
||
|
static int exp_l = 0;
|
||
|
static int exp_pcs = 0;
|
||
|
static int exp_psl = 0;
|
||
|
static int exp_pro = 0;
|
||
|
static int exp_ps = 0;
|
||
|
static int exp_kr = 0;
|
||
|
static int exp_sc = 0;
|
||
|
static int exp_sob = 0;
|
||
|
static int exp_ss = 0;
|
||
|
static int exp_st = 0;
|
||
|
static int exp_troff = 0;
|
||
|
static int exp_v = 0;
|
||
|
static int exp_version = 0;
|
||
|
static int exp_lpc = 0;
|
||
|
|
||
|
/* The following variables are controlled by command line parameters and
|
||
|
their meaning is explained in indent_globs.h. */
|
||
|
int leave_comma;
|
||
|
int decl_com_ind;
|
||
|
int case_indent;
|
||
|
int com_ind;
|
||
|
int decl_indent;
|
||
|
int ljust_decl;
|
||
|
int unindent_displace;
|
||
|
int else_if;
|
||
|
int indent_parameters;
|
||
|
int ind_size;
|
||
|
int blanklines_after_procs;
|
||
|
int lpc;
|
||
|
int noarrowspace;
|
||
|
|
||
|
/*
|
||
|
* N.B.: because of the way the table here is scanned, options whose names are
|
||
|
* substrings of other options must occur later; that is, with -lp vs -l, -lp
|
||
|
* must be first. Also, while (most) booleans occur more than once, the last
|
||
|
* default value is the one actually assigned.
|
||
|
*/
|
||
|
struct pro {
|
||
|
char *p_name; /* name, eg -bl, -cli */
|
||
|
enum profile p_type;
|
||
|
int p_default; /* the default value (if int) */
|
||
|
|
||
|
/* If p_type == PRO_BOOL, ON or OFF to tell how this switch affects
|
||
|
the variable.
|
||
|
Not used for other p_type's. */
|
||
|
enum on_or_off p_special;
|
||
|
|
||
|
/* if p_type == PRO_SETTINGS, a (char *) pointing to a list of the
|
||
|
switches to set, separated by NULs, terminated by 2 NULs.
|
||
|
if p_type == PRO_BOOL, PRO_INT, or PRO_FONT, address of the
|
||
|
variable that gets set by the option.
|
||
|
if p_type == PRO_PRSTRING, a (char *) pointing to the string. */
|
||
|
int *p_obj;
|
||
|
|
||
|
/* Points to a nonzero value (allocated statically for all options)
|
||
|
if the option has been specified explicitly. This is necessary
|
||
|
because for boolean options, the options to set and reset the
|
||
|
variable must share the explicit flag. */
|
||
|
int* p_explicit;
|
||
|
};
|
||
|
|
||
|
struct pro pro[] = {
|
||
|
|
||
|
{"T", PRO_KEY, 0, 0, 0, &exp_T},
|
||
|
{"bacc", PRO_BOOL, false, ON,
|
||
|
&blanklines_around_conditional_compilation, &exp_bacc},
|
||
|
{"badp", PRO_BOOL, false, ON,
|
||
|
&blanklines_after_declarations_at_proctop, &exp_badp},
|
||
|
{"bad", PRO_BOOL, false, ON, &blanklines_after_declarations, &exp_bad},
|
||
|
{"bap", PRO_BOOL, false, ON, &blanklines_after_procs, &exp_bap},
|
||
|
{"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments, &exp_bbb},
|
||
|
{"bc", PRO_BOOL, true, OFF, &leave_comma, &exp_bc},
|
||
|
{"bli", PRO_INT, 0, 0, &brace_indent, &exp_bli},
|
||
|
{"bl", PRO_BOOL, true, OFF, &btype_2, &exp_bl},
|
||
|
{"br", PRO_BOOL, true, ON, &btype_2, &exp_bl},
|
||
|
{"bs", PRO_BOOL, false, ON, &Bill_Shannon, &exp_bs},
|
||
|
{"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline, &exp_cdb},
|
||
|
{"cd", PRO_INT, 0, 0, &decl_com_ind, &exp_cd},
|
||
|
{"ce", PRO_BOOL, true, ON, &cuddle_else, &exp_ce},
|
||
|
{"ci", PRO_INT, 0, 0, &continuation_indent, &exp_ci},
|
||
|
{"cli", PRO_INT, 0, 0, &case_indent, &exp_cli},
|
||
|
{"cp", PRO_INT, 33, 0, &else_endif_col, &exp_cp},
|
||
|
{"c", PRO_INT, 33, 0, &com_ind, &exp_c},
|
||
|
{"di", PRO_INT, 16, 0, &decl_indent, &exp_di},
|
||
|
{"dj", PRO_BOOL, false, ON, &ljust_decl, &exp_dj},
|
||
|
{"d", PRO_INT, 0, 0, &unindent_displace, &exp_d},
|
||
|
{"eei", PRO_BOOL, false, ON, &extra_expression_indent, &exp_eei},
|
||
|
{"ei", PRO_BOOL, true, ON, &else_if, &exp_ei},
|
||
|
{"fbc", PRO_FONT, 0, 0, (int *) &blkcomf, &exp_fbc},
|
||
|
{"fbx", PRO_FONT, 0, 0, (int *) &boxcomf, &exp_fbx},
|
||
|
{"fb", PRO_FONT, 0, 0, (int *) &bodyf, &exp_fb},
|
||
|
{"fc1", PRO_BOOL, true, ON, &format_col1_comments, &exp_fc1},
|
||
|
{"fca", PRO_BOOL, true, ON, &format_comments, &exp_fca},
|
||
|
{"fc", PRO_FONT, 0, 0, (int *) &scomf, &exp_fc},
|
||
|
{"fk", PRO_FONT, 0, 0, (int *) &keywordf, &exp_fk},
|
||
|
{"fs", PRO_FONT, 0, 0, (int *) &stringf, &exp_fs},
|
||
|
{"gnu", PRO_SETTINGS, 0, 0,
|
||
|
(int *)"-nbad\0-bap\0-nbbb\0-nbc\0-bl\0-ncdb\0-nce\0-di0\0-ndj\0\
|
||
|
-ei\0-nfc1\0-i2\0-ip5\0-lp\0-pcs\0-nps\0-psl\0-nsc\0-nsob\0-bli2\0-ss\0\
|
||
|
-cp1\0-nfca\0", &exp_gnu},
|
||
|
{"ip", PRO_INT, 4, ON, &indent_parameters, &exp_ip},
|
||
|
{"i", PRO_INT, 4, 0, &ind_size, &exp_i},
|
||
|
{"kr", PRO_SETTINGS, 0, 0,
|
||
|
(int *)"-nbad\0-bap\0-nbbb\0-nbc\0-br\0-c33\0-cd33\0-ncdb\0-ce\0\
|
||
|
-ci4\0-cli0\0-d0\0-di1\0-nfc1\0-i4\0-ip0\0-l75\0-lp\0-npcs\0-npsl\0\
|
||
|
-nsc\0-nsc\0-nsob\0-nfca\0-cp33\0-nss\0", &exp_kr},
|
||
|
{"lpc", PRO_BOOL, false, ON, &lpc, &exp_lpc},
|
||
|
{"lc", PRO_INT, 0, 0, &block_comment_max_col, &exp_lc},
|
||
|
{"lp", PRO_BOOL, true, ON, &lineup_to_parens, &exp_lp},
|
||
|
{"l", PRO_INT, 78, 0, &max_col, &exp_l},
|
||
|
{"nbacc", PRO_BOOL, false, ON,
|
||
|
&blanklines_around_conditional_compilation, &exp_bacc},
|
||
|
{"nbadp", PRO_BOOL, false, OFF,
|
||
|
&blanklines_after_declarations_at_proctop, &exp_badp},
|
||
|
{"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations, &exp_bad},
|
||
|
{"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs, &exp_bap},
|
||
|
{"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments, &exp_bbb},
|
||
|
{"nbc", PRO_BOOL, true, ON, &leave_comma, &exp_bc},
|
||
|
{"nbs", PRO_BOOL, false, OFF, &Bill_Shannon, &exp_bs},
|
||
|
{"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline, &exp_cdb},
|
||
|
{"nce", PRO_BOOL, true, OFF, &cuddle_else, &exp_ce},
|
||
|
{"ndj", PRO_BOOL, false, OFF, &ljust_decl, &exp_dj},
|
||
|
{"neei", PRO_BOOL, false, OFF, &extra_expression_indent, &exp_eei},
|
||
|
{"nei", PRO_BOOL, true, OFF, &else_if, &exp_ei},
|
||
|
{"nfc1", PRO_BOOL, true, OFF, &format_col1_comments, &exp_fc1},
|
||
|
{"nfca", PRO_BOOL, true, OFF, &format_comments, &exp_fca},
|
||
|
{"nlp", PRO_BOOL, true, OFF, &lineup_to_parens, &exp_lp},
|
||
|
{"npcs", PRO_BOOL, false, OFF, &proc_calls_space, &exp_pcs},
|
||
|
{"npro", PRO_IGN, 0, 0, 0, &exp_pro},
|
||
|
{"npsl", PRO_BOOL, true, OFF, &procnames_start_line, &exp_psl},
|
||
|
{"nps", PRO_BOOL, false, OFF, &pointer_as_binop, &exp_ps},
|
||
|
{"nsc", PRO_BOOL, true, OFF, &star_comment_cont, &exp_sc},
|
||
|
{"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines, &exp_sob},
|
||
|
{"nss", PRO_BOOL, false, OFF, &space_sp_semicolon, &exp_ss},
|
||
|
{"nv", PRO_BOOL, false, OFF, &verbose, &exp_v},
|
||
|
{"pcs", PRO_BOOL, false, ON, &proc_calls_space, &exp_pcs},
|
||
|
{"psl", PRO_BOOL, true, ON, &procnames_start_line, &exp_psl},
|
||
|
{"ps", PRO_BOOL, false, ON, &pointer_as_binop, &exp_ps},
|
||
|
{"sc", PRO_BOOL, true, ON, &star_comment_cont, &exp_sc},
|
||
|
{"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines, &exp_sob},
|
||
|
{"ss", PRO_BOOL, false, ON, &space_sp_semicolon, &exp_ss},
|
||
|
{"st", PRO_STDIN, 0, 0, 0, &exp_st},
|
||
|
{"troff", PRO_BOOL, false, ON, &troff, &exp_troff},
|
||
|
{"version", PRO_PRSTRING, 0, 0, (int *)VERSION_STRING, &exp_version},
|
||
|
{"v", PRO_BOOL, false, ON, &verbose, &exp_v},
|
||
|
|
||
|
/* Signify end of structure. */
|
||
|
{0, 0, 0, 0, 0, 0}
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
|
||
|
* given in these files.
|
||
|
*/
|
||
|
set_profile()
|
||
|
{
|
||
|
register FILE *f;
|
||
|
char *fname;
|
||
|
#ifndef MSDOS
|
||
|
static char prof[] = ".indent.pro";
|
||
|
#else
|
||
|
static char prof[] = "indent.pro";
|
||
|
#endif
|
||
|
char *homedir;
|
||
|
|
||
|
homedir = getenv("HOME");
|
||
|
fname = xmalloc(strlen(homedir) + 10 + sizeof prof);
|
||
|
sprintf(fname, "%s/%s", homedir, prof);
|
||
|
if ((f = fopen(prof, "r")) != NULL) {
|
||
|
scan_profile(f);
|
||
|
(void) fclose(f);
|
||
|
}
|
||
|
if ((f = fopen(fname, "r")) != NULL) {
|
||
|
scan_profile(f);
|
||
|
(void) fclose(f);
|
||
|
}
|
||
|
free (fname);
|
||
|
}
|
||
|
|
||
|
scan_profile(f)
|
||
|
register FILE *f;
|
||
|
{
|
||
|
register int i;
|
||
|
register char *p;
|
||
|
char buf[BUFSIZ];
|
||
|
|
||
|
while (1) {
|
||
|
for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
|
||
|
if (p != buf) {
|
||
|
*p++ = 0;
|
||
|
if (verbose)
|
||
|
printf("profile: %s\n", buf);
|
||
|
set_option(buf, 1);
|
||
|
}
|
||
|
else if (i == EOF)
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* S1 should be a string. S2 should be a string, perhaps followed by
|
||
|
an argument. Compare the two, returning true if they are equal,
|
||
|
and if they are equal set *START_PARAM to point to the argument
|
||
|
in S2. */
|
||
|
eqin(s1, s2, start_param)
|
||
|
register char *s1;
|
||
|
register char *s2;
|
||
|
char **start_param;
|
||
|
{
|
||
|
while (*s1) {
|
||
|
if (*s1++ != *s2++)
|
||
|
return (false);
|
||
|
}
|
||
|
*start_param = s2;
|
||
|
return (true);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Set the defaults.
|
||
|
*/
|
||
|
set_defaults()
|
||
|
{
|
||
|
register struct pro *p;
|
||
|
|
||
|
for (p = pro; p->p_name; p++)
|
||
|
if (p->p_type == PRO_BOOL || p->p_type == PRO_INT)
|
||
|
*p->p_obj = p->p_default;
|
||
|
}
|
||
|
|
||
|
/* Process an option ARG (e.g. "-l60").
|
||
|
EXPLICIT should be nonzero iff the argument is being explicitly
|
||
|
specified (as opposed to being taken from a PRO_SETTINGS group of
|
||
|
settings). */
|
||
|
|
||
|
set_option (arg, explicit)
|
||
|
char *arg;
|
||
|
int explicit;
|
||
|
{
|
||
|
struct pro *p;
|
||
|
char *param_start;
|
||
|
|
||
|
arg++; /* ignore leading "-" */
|
||
|
for (p = pro; p->p_name; p++)
|
||
|
if (*p->p_name == *arg && eqin(p->p_name, arg, ¶m_start))
|
||
|
goto found;
|
||
|
fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
|
||
|
exit(1);
|
||
|
found:
|
||
|
/* If the parameter has been explicitly specified, we don't */
|
||
|
/* want a group of bundled settings to override the explicit */
|
||
|
/* setting. */
|
||
|
if (explicit || !*(p->p_explicit))
|
||
|
{
|
||
|
if (explicit)
|
||
|
*(p->p_explicit) = 1;
|
||
|
|
||
|
switch (p->p_type) {
|
||
|
|
||
|
case PRO_PRSTRING:
|
||
|
puts ((char *)p->p_obj);
|
||
|
exit (0);
|
||
|
|
||
|
case PRO_SETTINGS:
|
||
|
{
|
||
|
char *t; /* current position */
|
||
|
|
||
|
t = (char *)p->p_obj;
|
||
|
do
|
||
|
{
|
||
|
set_option(t, 0);
|
||
|
/* advance to character following next NUL */
|
||
|
while (*t++) ;
|
||
|
}
|
||
|
while (*t);
|
||
|
}
|
||
|
|
||
|
case PRO_IGN:
|
||
|
break;
|
||
|
|
||
|
case PRO_STDIN:
|
||
|
if (in_name == 0)
|
||
|
{
|
||
|
read_stdin();
|
||
|
/* Let it be known that we have an input file. */
|
||
|
in_name = "Standard Input";
|
||
|
}
|
||
|
if (output == 0)
|
||
|
output = stdout;
|
||
|
break;
|
||
|
|
||
|
case PRO_KEY:
|
||
|
if (*param_start == 0)
|
||
|
goto need_param;
|
||
|
{
|
||
|
register char *str = (char *) xmalloc(strlen(param_start) + 1);
|
||
|
strcpy(str, param_start);
|
||
|
addkey(str, 4);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case PRO_BOOL:
|
||
|
if (p->p_special == OFF)
|
||
|
*p->p_obj = false;
|
||
|
else
|
||
|
*p->p_obj = true;
|
||
|
break;
|
||
|
|
||
|
case PRO_INT:
|
||
|
if (*param_start == 0) {
|
||
|
need_param:
|
||
|
fprintf(stderr, "indent: ``%s'' requires a parameter\n",
|
||
|
arg - 1);
|
||
|
exit(1);
|
||
|
}
|
||
|
*p->p_obj = atoi(param_start);
|
||
|
break;
|
||
|
|
||
|
case PRO_FONT:
|
||
|
parsefont((struct fstate *) p->p_obj, param_start);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
|
||
|
p->p_type);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
}
|