version 1.1.1.2, 2003/04/13 18:21:21 |
version 1.1.1.3, 2011/09/16 17:47:07 |
|
|
/* |
/* |
* Copyright (C) 1984-2002 Mark Nudelman |
* Copyright (C) 1984-2011 Mark Nudelman |
* |
* |
* You may distribute under the terms of either the GNU General Public |
* You may distribute under the terms of either the GNU General Public |
* License or the Less License, as specified in the README file. |
* License or the Less License, as specified in the README file. |
|
|
static struct loption *pendopt; |
static struct loption *pendopt; |
public int plusoption = FALSE; |
public int plusoption = FALSE; |
|
|
static char *propt(); |
|
static char *optstring(); |
static char *optstring(); |
static int flip_triple(); |
static int flip_triple(); |
|
|
extern int screen_trashed; |
extern int screen_trashed; |
|
extern int less_is_more; |
|
extern int quit_at_eof; |
extern char *every_first_cmd; |
extern char *every_first_cmd; |
|
|
|
/* |
|
* Return a printable description of an option. |
|
*/ |
|
static char * |
|
opt_desc(o) |
|
struct loption *o; |
|
{ |
|
static char buf[OPTNAME_MAX + 10]; |
|
if (o->oletter == OLETTER_NONE) |
|
SNPRINTF1(buf, sizeof(buf), "--%s", o->onames->oname); |
|
else |
|
SNPRINTF2(buf, sizeof(buf), "-%c (--%s)", o->oletter, o->onames->oname); |
|
return (buf); |
|
} |
|
|
|
/* |
|
* Return a string suitable for printing as the "name" of an option. |
|
* For example, if the option letter is 'x', just return "-x". |
|
*/ |
|
public char * |
|
propt(c) |
|
int c; |
|
{ |
|
static char buf[8]; |
|
|
|
sprintf(buf, "-%s", prchar(c)); |
|
return (buf); |
|
} |
|
|
/* |
/* |
* Scan an argument (either from the command line or from the |
* Scan an argument (either from the command line or from the |
* LESS environment variable) and process it. |
* LESS environment variable) and process it. |
|
|
(*pendopt->ofunc)(INIT, s); |
(*pendopt->ofunc)(INIT, s); |
break; |
break; |
case NUMBER: |
case NUMBER: |
printopt = propt(pendopt->oletter); |
printopt = opt_desc(pendopt); |
*(pendopt->ovar) = getnum(&s, printopt, (int*)NULL); |
*(pendopt->ovar) = getnum(&s, printopt, (int*)NULL); |
break; |
break; |
} |
} |
|
|
s--; |
s--; |
optc = 'z'; |
optc = 'z'; |
break; |
break; |
|
case 'n': |
|
if (less_is_more) |
|
optc = 'z'; |
|
break; |
} |
} |
|
|
/* |
/* |
|
|
if (optname == NULL) |
if (optname == NULL) |
{ |
{ |
printopt = propt(optc); |
printopt = propt(optc); |
lc = SIMPLE_IS_LOWER(optc); |
lc = ASCII_IS_LOWER(optc); |
o = findopt(optc); |
o = findopt(optc); |
} else |
} else |
{ |
{ |
printopt = optname; |
printopt = optname; |
lc = SIMPLE_IS_LOWER(optname[0]); |
lc = ASCII_IS_LOWER(optname[0]); |
o = findopt_name(&optname, NULL, &err); |
o = findopt_name(&optname, NULL, &err); |
s = optname; |
s = optname; |
optname = NULL; |
optname = NULL; |
|
|
* OPT_SET set to the inverse of the default value |
* OPT_SET set to the inverse of the default value |
*/ |
*/ |
public void |
public void |
toggle_option(c, s, how_toggle) |
toggle_option(o, lower, s, how_toggle) |
int c; |
struct loption *o; |
|
int lower; |
char *s; |
char *s; |
int how_toggle; |
int how_toggle; |
{ |
{ |
register struct loption *o; |
|
register int num; |
register int num; |
int no_prompt; |
int no_prompt; |
int err; |
int err; |
|
|
no_prompt = (how_toggle & OPT_NO_PROMPT); |
no_prompt = (how_toggle & OPT_NO_PROMPT); |
how_toggle &= ~OPT_NO_PROMPT; |
how_toggle &= ~OPT_NO_PROMPT; |
|
|
/* |
|
* Look up the option letter in the option table. |
|
*/ |
|
o = findopt(c); |
|
if (o == NULL) |
if (o == NULL) |
{ |
{ |
parg.p_string = propt(c); |
error("No such option", NULL_PARG); |
error("There is no %s option", &parg); |
|
return; |
return; |
} |
} |
|
|
if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) |
if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) |
{ |
{ |
parg.p_string = propt(c); |
parg.p_string = opt_desc(o); |
error("Cannot change the %s option", &parg); |
error("Cannot change the %s option", &parg); |
return; |
return; |
} |
} |
|
|
if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) |
if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) |
{ |
{ |
parg.p_string = propt(c); |
parg.p_string = opt_desc(o); |
error("Cannot query the %s option", &parg); |
error("Cannot query the %s option", &parg); |
return; |
return; |
} |
} |
|
|
switch (how_toggle) |
switch (how_toggle) |
{ |
{ |
case OPT_TOGGLE: |
case OPT_TOGGLE: |
*(o->ovar) = flip_triple(*(o->ovar), |
*(o->ovar) = flip_triple(*(o->ovar), lower); |
islower(c)); |
|
break; |
break; |
case OPT_UNSET: |
case OPT_UNSET: |
*(o->ovar) = o->odefault; |
*(o->ovar) = o->odefault; |
break; |
break; |
case OPT_SET: |
case OPT_SET: |
*(o->ovar) = flip_triple(o->odefault, |
*(o->ovar) = flip_triple(o->odefault, lower); |
islower(c)); |
|
break; |
break; |
} |
} |
break; |
break; |
|
|
} |
} |
|
|
/* |
/* |
* Return a string suitable for printing as the "name" of an option. |
* Determine if an option takes a parameter. |
* For example, if the option letter is 'x', just return "-x". |
|
*/ |
*/ |
static char * |
|
propt(c) |
|
int c; |
|
{ |
|
static char buf[8]; |
|
|
|
sprintf(buf, "-%s", prchar(c)); |
|
return (buf); |
|
} |
|
|
|
/* |
|
* Determine if an option is a single character option (BOOL or TRIPLE), |
|
* or if it a multi-character option (NUMBER). |
|
*/ |
|
public int |
public int |
single_char_option(c) |
opt_has_param(o) |
int c; |
struct loption *o; |
{ |
{ |
register struct loption *o; |
|
|
|
o = findopt(c); |
|
if (o == NULL) |
if (o == NULL) |
return (TRUE); |
return (0); |
return ((o->otype & (BOOL|TRIPLE|NOVAR|NO_TOGGLE)) != 0); |
if (o->otype & (BOOL|TRIPLE|NOVAR|NO_TOGGLE)) |
|
return (0); |
|
return (1); |
} |
} |
|
|
/* |
/* |
|
|
* Only string and number valued options have prompts. |
* Only string and number valued options have prompts. |
*/ |
*/ |
public char * |
public char * |
opt_prompt(c) |
opt_prompt(o) |
int c; |
struct loption *o; |
{ |
{ |
register struct loption *o; |
|
|
|
o = findopt(c); |
|
if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) |
if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) |
return (NULL); |
return ("?"); |
return (o->odesc[0]); |
return (o->odesc[0]); |
} |
} |
|
|
|
|
public void |
public void |
nopendopt() |
nopendopt() |
{ |
{ |
nostring(propt(pendopt->oletter)); |
nostring(opt_desc(pendopt)); |
} |
} |
|
|
/* |
/* |
|
|
} |
} |
|
|
/* |
/* |
|
*/ |
|
static int |
|
num_error(printopt, errp) |
|
char *printopt; |
|
int *errp; |
|
{ |
|
PARG parg; |
|
|
|
if (errp != NULL) |
|
{ |
|
*errp = TRUE; |
|
return (-1); |
|
} |
|
if (printopt != NULL) |
|
{ |
|
parg.p_string = printopt; |
|
error("Number is required after %s", &parg); |
|
} |
|
quit(QUIT_ERROR); |
|
/* NOTREACHED */ |
|
return (-1); |
|
} |
|
|
|
/* |
* Translate a string into a number. |
* Translate a string into a number. |
* Like atoi(), but takes a pointer to a char *, and updates |
* Like atoi(), but takes a pointer to a char *, and updates |
* the char * to point after the translated number. |
* the char * to point after the translated number. |
|
|
register char *s; |
register char *s; |
register int n; |
register int n; |
register int neg; |
register int neg; |
PARG parg; |
|
|
|
s = skipsp(*sp); |
s = skipsp(*sp); |
neg = FALSE; |
neg = FALSE; |
|
|
s++; |
s++; |
} |
} |
if (*s < '0' || *s > '9') |
if (*s < '0' || *s > '9') |
{ |
return (num_error(printopt, errp)); |
if (errp != NULL) |
|
{ |
|
*errp = TRUE; |
|
return (-1); |
|
} |
|
if (printopt != NULL) |
|
{ |
|
parg.p_string = printopt; |
|
error("Number is required after %s", &parg); |
|
} |
|
quit(QUIT_ERROR); |
|
} |
|
|
|
n = 0; |
n = 0; |
while (*s >= '0' && *s <= '9') |
while (*s >= '0' && *s <= '9') |
|
|
if (neg) |
if (neg) |
n = -n; |
n = -n; |
return (n); |
return (n); |
|
} |
|
|
|
/* |
|
* Translate a string into a fraction, represented by the part of a |
|
* number which would follow a decimal point. |
|
* The value of the fraction is returned as parts per NUM_FRAC_DENOM. |
|
* That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM. |
|
*/ |
|
public long |
|
getfraction(sp, printopt, errp) |
|
char **sp; |
|
char *printopt; |
|
int *errp; |
|
{ |
|
register char *s; |
|
long frac = 0; |
|
int fraclen = 0; |
|
|
|
s = skipsp(*sp); |
|
if (*s < '0' || *s > '9') |
|
return (num_error(printopt, errp)); |
|
|
|
for ( ; *s >= '0' && *s <= '9'; s++) |
|
{ |
|
frac = (frac * 10) + (*s - '0'); |
|
fraclen++; |
|
} |
|
if (fraclen > NUM_LOG_FRAC_DENOM) |
|
while (fraclen-- > NUM_LOG_FRAC_DENOM) |
|
frac /= 10; |
|
else |
|
while (fraclen++ < NUM_LOG_FRAC_DENOM) |
|
frac *= 10; |
|
*sp = s; |
|
if (errp != NULL) |
|
*errp = FALSE; |
|
return (frac); |
|
} |
|
|
|
|
|
/* |
|
* Get the value of the -e flag. |
|
*/ |
|
public int |
|
get_quit_at_eof() |
|
{ |
|
if (!less_is_more) |
|
return quit_at_eof; |
|
/* When less_is_more is set, the -e flag semantics are different. */ |
|
return quit_at_eof ? OPT_ON : OPT_ONPLUS; |
} |
} |