=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/option.c,v retrieving revision 1.4 retrieving revision 1.5 diff -c -r1.4 -r1.5 *** src/usr.bin/less/option.c 2003/03/13 09:09:32 1.4 --- src/usr.bin/less/option.c 2003/04/13 18:26:26 1.5 *************** *** 1,29 **** - /* $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. * ! * 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. * ! * 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. */ --- 1,11 ---- /* ! * Copyright (C) 1984-2002 Mark Nudelman * ! * You may distribute under the terms of either the GNU General Public ! * License or the Less License, as specified in the README file. * ! * For more information about less, or for information on how to ! * contact the author, see the README file. */ *************** *** 39,45 **** #include "less.h" #include "option.h" ! static struct option *pendopt; public int plusoption = FALSE; static char *propt(); --- 21,27 ---- #include "less.h" #include "option.h" ! static struct loption *pendopt; public int plusoption = FALSE; static char *propt(); *************** *** 57,92 **** scan_option(s) char *s; { ! struct option *o; ! int c; char *str; int set_default; PARG parg; if (s == NULL) return; /* ! * If we have a pending string-valued option, 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. */ if (pendopt != NULL) { ! (*pendopt->ofunc)(INIT, s); pendopt = NULL; return; } set_default = FALSE; while (*s != '\0') { /* * Check some special cases first. */ ! switch (c = *s++) { case ' ': case '\t': --- 39,89 ---- scan_option(s) char *s; { ! 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 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 argument for the previous option. */ if (pendopt != NULL) { ! 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 (optc = *s++) { case ' ': case '\t': *************** *** 94,104 **** continue; case '-': /* * "-+" means set these options back to their defaults. * (They may have been set otherwise by previous * options.) */ ! if (set_default = (*s == '+')) s++; continue; case '+': --- 91,110 ---- 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.) */ ! set_default = (*s == '+'); ! if (set_default) s++; continue; case '+': *************** *** 110,120 **** * EVERY input file. */ plusoption = TRUE; ! if (*s == '+') ! every_first_cmd = save(++s); else ! ungetsc(s); ! s = optstring(s, c); continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': --- 116,126 ---- * EVERY input file. */ plusoption = TRUE; ! s = optstring(s, &str, propt('+'), NULL); ! if (*str == '+') ! every_first_cmd = save(++str); else ! ungetsc(str); continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *************** *** 124,130 **** * window size. */ s--; ! c = 'z'; break; } --- 130,136 ---- * window size. */ s--; ! optc = 'z'; break; } *************** *** 132,151 **** * Not a special case. * Look up the option letter in the option table. */ ! o = findopt(c); 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 quit(QUIT_ERROR); } switch (o->otype & OTYPE) { case BOOL: --- 138,199 ---- * Not a special case. * Look up the option letter in the option table. */ ! 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 = 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,165 **** if (set_default) *(o->ovar) = o->odefault; else ! *(o->ovar) = flip_triple(o->odefault, ! (o->oletter == c)); break; case STRING: if (*s == '\0') --- 206,212 ---- if (set_default) *(o->ovar) = o->odefault; else ! *(o->ovar) = flip_triple(o->odefault, lc); break; case STRING: if (*s == '\0') *************** *** 177,187 **** * All processing of STRING options is done by * the handling function. */ ! str = s; ! s = optstring(s, c); break; case NUMBER: ! *(o->ovar) = getnum(&s, c, (int*)NULL); break; } /* --- 224,240 ---- * All processing of STRING options is done by * the handling function. */ ! while (*s == ' ') ! s++; ! s = optstring(s, &str, printopt, o->odesc[1]); break; case NUMBER: ! if (*s == '\0') ! { ! pendopt = o; ! return; ! } ! *(o->ovar) = getnum(&s, printopt, (int*)NULL); break; } /* *************** *** 207,217 **** char *s; int how_toggle; { ! struct option *o; ! int num; int err; PARG parg; /* * Look up the option letter in the option table. */ --- 260,274 ---- char *s; int how_toggle; { ! 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,239 **** if (o == NULL) { parg.p_string = propt(c); ! error("There is no %s flag", &parg); return; } if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) { parg.p_string = propt(c); ! error("Cannot change the %s flag", &parg); return; } if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) { parg.p_string = propt(c); ! error("Cannot query the %s flag", &parg); return; } --- 276,296 ---- if (o == NULL) { parg.p_string = propt(c); ! 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 option", &parg); return; } if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) { parg.p_string = propt(c); ! error("Cannot query the %s option", &parg); return; } *************** *** 293,306 **** { case OPT_TOGGLE: *(o->ovar) = flip_triple(*(o->ovar), ! o->oletter == c); break; case OPT_UNSET: *(o->ovar) = o->odefault; break; case OPT_SET: *(o->ovar) = flip_triple(o->odefault, ! o->oletter == c); break; } break; --- 350,363 ---- { case OPT_TOGGLE: *(o->ovar) = flip_triple(*(o->ovar), ! islower(c)); break; case OPT_UNSET: *(o->ovar) = o->odefault; break; case OPT_SET: *(o->ovar) = flip_triple(o->odefault, ! islower(c)); break; } break; *************** *** 313,319 **** { case OPT_SET: case OPT_UNSET: ! error("Can't use \"-+\" or \"--\" for a string flag", NULL_PARG); return; } --- 370,376 ---- { case OPT_SET: case OPT_UNSET: ! error("Cannot use \"-+\" or \"--\" for a string option", NULL_PARG); return; } *************** *** 325,331 **** switch (how_toggle) { case OPT_TOGGLE: ! num = getnum(&s, '\0', &err); if (!err) *(o->ovar) = num; break; --- 382,388 ---- switch (how_toggle) { case OPT_TOGGLE: ! num = getnum(&s, NULL, &err); if (!err) *(o->ovar) = num; break; *************** *** 333,339 **** *(o->ovar) = o->odefault; break; case OPT_SET: ! error("Can't use \"--\" for a numeric flag", NULL_PARG); return; } --- 390,396 ---- *(o->ovar) = o->odefault; break; case OPT_SET: ! error("Can't use \"-!\" for a numeric option", NULL_PARG); return; } *************** *** 353,383 **** chg_hilite(); #endif ! /* ! * Print a message describing the new setting. ! */ ! 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)) --- 410,443 ---- chg_hilite(); #endif ! if (!no_prompt) { /* ! * Print a message describing the new setting. */ ! 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,414 **** { static char buf[8]; ! snprintf(buf, sizeof buf, "-%s", prchar(c)); return (buf); } --- 468,474 ---- { static char buf[8]; ! snprintf(buf, sizeof(buf), "-%s", prchar(c)); return (buf); } *************** *** 420,426 **** single_char_option(c) int c; { ! struct option *o; o = findopt(c); if (o == NULL) --- 480,486 ---- single_char_option(c) int c; { ! register struct loption *o; o = findopt(c); if (o == NULL) *************** *** 436,442 **** opt_prompt(c) int c; { ! struct option *o; o = findopt(c); if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) --- 496,502 ---- opt_prompt(c) int c; { ! register struct loption *o; o = findopt(c); if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) *************** *** 461,472 **** * Print error message about missing string. */ static void ! nostring(c) ! int c; { PARG parg; ! parg.p_string = propt(c); ! error("String is required after %s", &parg); } /* --- 521,532 ---- * Print error message about missing string. */ static void ! nostring(printopt) ! char *printopt; { PARG parg; ! parg.p_string = printopt; ! error("Value is required after %s", &parg); } /* *************** *** 475,481 **** public void nopendopt() { ! nostring(pendopt->oletter); } /* --- 535,541 ---- public void nopendopt() { ! nostring(propt(pendopt->oletter)); } /* *************** *** 484,506 **** * Return a pointer to the remainder of the string, if any. */ static char * ! optstring(s, c) char *s; ! int c; { ! char *p; if (*s == '\0') { ! nostring(c); quit(QUIT_ERROR); } for (p = s; *p != '\0'; p++) ! if (*p == END_OPTION_STRING) { ! *p = '\0'; ! return (p+1); } return (p); } --- 544,585 ---- * Return a pointer to the remainder of the string, if any. */ static char * ! optstring(s, p_str, printopt, validchars) char *s; ! char **p_str; ! char *printopt; ! char *validchars; { ! register char *p; if (*s == '\0') { ! nostring(printopt); quit(QUIT_ERROR); } + *p_str = s; for (p = s; *p != '\0'; p++) ! { ! if (*p == END_OPTION_STRING || ! (validchars != NULL && strchr(validchars, *p) == NULL)) { ! 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,523 **** * the char * to point after the translated number. */ public int ! getnum(sp, c, errp) char **sp; ! int c; int *errp; { ! char *s; ! int n; ! int neg; PARG parg; s = skipsp(*sp); --- 589,602 ---- * the char * to point after the translated number. */ public int ! getnum(sp, printopt, errp) char **sp; ! char *printopt; int *errp; { ! register char *s; ! register int n; ! register int neg; PARG parg; s = skipsp(*sp); *************** *** 534,541 **** *errp = TRUE; return (-1); } ! parg.p_string = propt(c); ! error("Number is required after %s", &parg); quit(QUIT_ERROR); } --- 613,623 ---- *errp = TRUE; return (-1); } ! if (printopt != NULL) ! { ! parg.p_string = printopt; ! error("Number is required after %s", &parg); ! } quit(QUIT_ERROR); }