summaryrefslogtreecommitdiff
path: root/usr.bin/less/option.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-04-13 18:26:27 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-04-13 18:26:27 +0000
commit5569f8a6b6c831077f77d24e2c23d2e2d41fb95f (patch)
treeb79fe763d81906631382fbdc80f3b42a44b6c668 /usr.bin/less/option.c
parent6b9d6b99a4fdda2ee6d9a30dec452d8202fb2017 (diff)
Merge in less-381 w/ local changes and remove obsolete files.
Diffstat (limited to 'usr.bin/less/option.c')
-rw-r--r--usr.bin/less/option.c290
1 files changed, 186 insertions, 104 deletions
diff --git a/usr.bin/less/option.c b/usr.bin/less/option.c
index 694c2baac70..a56a56fb53d 100644
--- a/usr.bin/less/option.c
+++ b/usr.bin/less/option.c
@@ -1,29 +1,11 @@
-/* $OpenBSD: option.c,v 1.4 2003/03/13 09:09:32 deraadt Exp $ */
-
/*
- * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman
- * All rights reserved.
+ * Copyright (C) 1984-2002 Mark Nudelman
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice in the documentation and/or other materials provided with
- * the distribution.
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Less License, as specified in the README file.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * For more information about less, or for information on how to
+ * contact the author, see the README file.
*/
@@ -39,7 +21,7 @@
#include "less.h"
#include "option.h"
-static struct option *pendopt;
+static struct loption *pendopt;
public int plusoption = FALSE;
static char *propt();
@@ -57,36 +39,51 @@ extern char *every_first_cmd;
scan_option(s)
char *s;
{
- struct option *o;
- int c;
+ register struct loption *o;
+ register int optc;
+ char *optname;
+ char *printopt;
char *str;
int set_default;
+ int lc;
+ int err;
PARG parg;
if (s == NULL)
return;
/*
- * If we have a pending string-valued option, handle it now.
+ * If we have a pending option which requires an argument,
+ * handle it now.
* This happens if the previous option was, for example, "-P"
* without a following string. In that case, the current
- * option is simply the string for the previous option.
+ * option is simply the argument for the previous option.
*/
if (pendopt != NULL)
{
- (*pendopt->ofunc)(INIT, s);
+ switch (pendopt->otype & OTYPE)
+ {
+ case STRING:
+ (*pendopt->ofunc)(INIT, s);
+ break;
+ case NUMBER:
+ printopt = propt(pendopt->oletter);
+ *(pendopt->ovar) = getnum(&s, printopt, (int*)NULL);
+ break;
+ }
pendopt = NULL;
return;
}
set_default = FALSE;
+ optname = NULL;
while (*s != '\0')
{
/*
* Check some special cases first.
*/
- switch (c = *s++)
+ switch (optc = *s++)
{
case ' ':
case '\t':
@@ -94,11 +91,20 @@ scan_option(s)
continue;
case '-':
/*
+ * "--" indicates an option name instead of a letter.
+ */
+ if (*s == '-')
+ {
+ optname = ++s;
+ break;
+ }
+ /*
* "-+" means set these options back to their defaults.
* (They may have been set otherwise by previous
* options.)
*/
- if (set_default = (*s == '+'))
+ set_default = (*s == '+');
+ if (set_default)
s++;
continue;
case '+':
@@ -110,11 +116,11 @@ scan_option(s)
* EVERY input file.
*/
plusoption = TRUE;
- if (*s == '+')
- every_first_cmd = save(++s);
+ s = optstring(s, &str, propt('+'), NULL);
+ if (*str == '+')
+ every_first_cmd = save(++str);
else
- ungetsc(s);
- s = optstring(s, c);
+ ungetsc(str);
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -124,7 +130,7 @@ scan_option(s)
* window size.
*/
s--;
- c = 'z';
+ optc = 'z';
break;
}
@@ -132,20 +138,62 @@ scan_option(s)
* Not a special case.
* Look up the option letter in the option table.
*/
- o = findopt(c);
+ err = 0;
+ if (optname == NULL)
+ {
+ printopt = propt(optc);
+ lc = SIMPLE_IS_LOWER(optc);
+ o = findopt(optc);
+ } else
+ {
+ printopt = optname;
+ lc = SIMPLE_IS_LOWER(optname[0]);
+ o = findopt_name(&optname, NULL, &err);
+ s = optname;
+ optname = NULL;
+ if (*s == '\0' || *s == ' ')
+ {
+ /*
+ * The option name matches exactly.
+ */
+ ;
+ } else if (*s == '=')
+ {
+ /*
+ * The option name is followed by "=value".
+ */
+ if (o != NULL &&
+ (o->otype & OTYPE) != STRING &&
+ (o->otype & OTYPE) != NUMBER)
+ {
+ parg.p_string = printopt;
+ error("The %s option should not be followed by =",
+ &parg);
+ quit(QUIT_ERROR);
+ }
+ s++;
+ } else
+ {
+ /*
+ * The specified name is longer than the
+ * real option name.
+ */
+ o = NULL;
+ }
+ }
if (o == NULL)
{
- parg.p_string = propt(c);
-#if MSOFTC || OS2
- error("There is no %s flag (\"less -?\" for help)",
- &parg);
-#else
- error("There is no %s flag (\"less -\\?\" for help)",
- &parg);
-#endif
+ parg.p_string = printopt;
+ if (err == OPT_AMBIG)
+ error("%s is an ambiguous abbreviation (\"less --help\" for help)",
+ &parg);
+ else
+ error("There is no %s option (\"less --help\" for help)",
+ &parg);
quit(QUIT_ERROR);
}
+ str = NULL;
switch (o->otype & OTYPE)
{
case BOOL:
@@ -158,8 +206,7 @@ scan_option(s)
if (set_default)
*(o->ovar) = o->odefault;
else
- *(o->ovar) = flip_triple(o->odefault,
- (o->oletter == c));
+ *(o->ovar) = flip_triple(o->odefault, lc);
break;
case STRING:
if (*s == '\0')
@@ -177,11 +224,17 @@ scan_option(s)
* All processing of STRING options is done by
* the handling function.
*/
- str = s;
- s = optstring(s, c);
+ while (*s == ' ')
+ s++;
+ s = optstring(s, &str, printopt, o->odesc[1]);
break;
case NUMBER:
- *(o->ovar) = getnum(&s, c, (int*)NULL);
+ if (*s == '\0')
+ {
+ pendopt = o;
+ return;
+ }
+ *(o->ovar) = getnum(&s, printopt, (int*)NULL);
break;
}
/*
@@ -207,11 +260,15 @@ toggle_option(c, s, how_toggle)
char *s;
int how_toggle;
{
- struct option *o;
- int num;
+ register struct loption *o;
+ register int num;
+ int no_prompt;
int err;
PARG parg;
+ no_prompt = (how_toggle & OPT_NO_PROMPT);
+ how_toggle &= ~OPT_NO_PROMPT;
+
/*
* Look up the option letter in the option table.
*/
@@ -219,21 +276,21 @@ toggle_option(c, s, how_toggle)
if (o == NULL)
{
parg.p_string = propt(c);
- error("There is no %s flag", &parg);
+ error("There is no %s option", &parg);
return;
}
if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE))
{
parg.p_string = propt(c);
- error("Cannot change the %s flag", &parg);
+ error("Cannot change the %s option", &parg);
return;
}
if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY))
{
parg.p_string = propt(c);
- error("Cannot query the %s flag", &parg);
+ error("Cannot query the %s option", &parg);
return;
}
@@ -293,14 +350,14 @@ toggle_option(c, s, how_toggle)
{
case OPT_TOGGLE:
*(o->ovar) = flip_triple(*(o->ovar),
- o->oletter == c);
+ islower(c));
break;
case OPT_UNSET:
*(o->ovar) = o->odefault;
break;
case OPT_SET:
*(o->ovar) = flip_triple(o->odefault,
- o->oletter == c);
+ islower(c));
break;
}
break;
@@ -313,7 +370,7 @@ toggle_option(c, s, how_toggle)
{
case OPT_SET:
case OPT_UNSET:
- error("Can't use \"-+\" or \"--\" for a string flag",
+ error("Cannot use \"-+\" or \"--\" for a string option",
NULL_PARG);
return;
}
@@ -325,7 +382,7 @@ toggle_option(c, s, how_toggle)
switch (how_toggle)
{
case OPT_TOGGLE:
- num = getnum(&s, '\0', &err);
+ num = getnum(&s, NULL, &err);
if (!err)
*(o->ovar) = num;
break;
@@ -333,7 +390,7 @@ toggle_option(c, s, how_toggle)
*(o->ovar) = o->odefault;
break;
case OPT_SET:
- error("Can't use \"--\" for a numeric flag",
+ error("Can't use \"-!\" for a numeric option",
NULL_PARG);
return;
}
@@ -353,31 +410,34 @@ toggle_option(c, s, how_toggle)
chg_hilite();
#endif
- /*
- * Print a message describing the new setting.
- */
- switch (o->otype & OTYPE)
+ if (!no_prompt)
{
- case BOOL:
- case TRIPLE:
- /*
- * Print the odesc message.
- */
- error(o->odesc[*(o->ovar)], NULL_PARG);
- break;
- case NUMBER:
/*
- * The message is in odesc[1] and has a %d for
- * the value of the variable.
+ * Print a message describing the new setting.
*/
- parg.p_int = *(o->ovar);
- error(o->odesc[1], &parg);
- break;
- case STRING:
- /*
- * Message was already printed by the handling function.
- */
- break;
+ switch (o->otype & OTYPE)
+ {
+ case BOOL:
+ case TRIPLE:
+ /*
+ * Print the odesc message.
+ */
+ error(o->odesc[*(o->ovar)], NULL_PARG);
+ break;
+ case NUMBER:
+ /*
+ * The message is in odesc[1] and has a %d for
+ * the value of the variable.
+ */
+ parg.p_int = *(o->ovar);
+ error(o->odesc[1], &parg);
+ break;
+ case STRING:
+ /*
+ * Message was already printed by the handling function.
+ */
+ break;
+ }
}
if (how_toggle != OPT_NO_TOGGLE && (o->otype & REPAINT))
@@ -408,7 +468,7 @@ propt(c)
{
static char buf[8];
- snprintf(buf, sizeof buf, "-%s", prchar(c));
+ snprintf(buf, sizeof(buf), "-%s", prchar(c));
return (buf);
}
@@ -420,7 +480,7 @@ propt(c)
single_char_option(c)
int c;
{
- struct option *o;
+ register struct loption *o;
o = findopt(c);
if (o == NULL)
@@ -436,7 +496,7 @@ single_char_option(c)
opt_prompt(c)
int c;
{
- struct option *o;
+ register struct loption *o;
o = findopt(c);
if (o == NULL || (o->otype & (STRING|NUMBER)) == 0)
@@ -461,12 +521,12 @@ isoptpending()
* Print error message about missing string.
*/
static void
-nostring(c)
- int c;
+nostring(printopt)
+ char *printopt;
{
PARG parg;
- parg.p_string = propt(c);
- error("String is required after %s", &parg);
+ parg.p_string = printopt;
+ error("Value is required after %s", &parg);
}
/*
@@ -475,7 +535,7 @@ nostring(c)
public void
nopendopt()
{
- nostring(pendopt->oletter);
+ nostring(propt(pendopt->oletter));
}
/*
@@ -484,23 +544,42 @@ nopendopt()
* Return a pointer to the remainder of the string, if any.
*/
static char *
-optstring(s, c)
+optstring(s, p_str, printopt, validchars)
char *s;
- int c;
+ char **p_str;
+ char *printopt;
+ char *validchars;
{
- char *p;
+ register char *p;
if (*s == '\0')
{
- nostring(c);
+ nostring(printopt);
quit(QUIT_ERROR);
}
+ *p_str = s;
for (p = s; *p != '\0'; p++)
- if (*p == END_OPTION_STRING)
+ {
+ if (*p == END_OPTION_STRING ||
+ (validchars != NULL && strchr(validchars, *p) == NULL))
{
- *p = '\0';
- return (p+1);
+ switch (*p)
+ {
+ case END_OPTION_STRING:
+ case ' ': case '\t': case '-':
+ /* Replace the char with a null to terminate string. */
+ *p++ = '\0';
+ break;
+ default:
+ /* Cannot replace char; make a copy of the string. */
+ *p_str = (char *) ecalloc(p-s+1, sizeof(char));
+ strncpy(*p_str, s, p-s);
+ (*p_str)[p-s] = '\0';
+ break;
+ }
+ break;
}
+ }
return (p);
}
@@ -510,14 +589,14 @@ optstring(s, c)
* the char * to point after the translated number.
*/
public int
-getnum(sp, c, errp)
+getnum(sp, printopt, errp)
char **sp;
- int c;
+ char *printopt;
int *errp;
{
- char *s;
- int n;
- int neg;
+ register char *s;
+ register int n;
+ register int neg;
PARG parg;
s = skipsp(*sp);
@@ -534,8 +613,11 @@ getnum(sp, c, errp)
*errp = TRUE;
return (-1);
}
- parg.p_string = propt(c);
- error("Number is required after %s", &parg);
+ if (printopt != NULL)
+ {
+ parg.p_string = printopt;
+ error("Number is required after %s", &parg);
+ }
quit(QUIT_ERROR);
}