=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/option.c,v retrieving revision 1.9 retrieving revision 1.10 diff -c -r1.9 -r1.10 *** src/usr.bin/less/option.c 2014/04/25 18:07:41 1.9 --- src/usr.bin/less/option.c 2015/11/05 22:08:44 1.10 *************** *** 6,19 **** * * For more information, see the README file. */ - /* * Process command line options. * * Each option is a single letter which controls a program variable. * The options have defaults which may be changed via ! * the command line option, toggled via the "-" command, * or queried via the "_" command. */ --- 6,22 ---- * * For more information, see the README file. */ + /* + * Modified for use with illumos. + * Copyright 2014 Garrett D'Amore + */ /* * Process command line options. * * Each option is a single letter which controls a program variable. * The options have defaults which may be changed via ! * the command line option, toggled via the "-" command, * or queried via the "_" command. */ *************** *** 21,27 **** #include "option.h" static struct loption *pendopt; ! public int plusoption = FALSE; static char *optstring(); static int flip_triple(); --- 24,30 ---- #include "option.h" static struct loption *pendopt; ! int plusoption = FALSE; static char *optstring(); static int flip_triple(); *************** *** 35,49 **** /* * 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); } --- 38,52 ---- /* * Return a printable description of an option. */ ! static char * ! opt_desc(struct loption *o) { static char buf[OPTNAME_MAX + 10]; if (o->oletter == OLETTER_NONE) ! (void) snprintf(buf, sizeof (buf), "--%s", o->onames->oname); else ! (void) snprintf(buf, sizeof (buf), "-%c (--%s)", ! o->oletter, o->onames->oname); return (buf); } *************** *** 51,82 **** * 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]; ! snprintf(buf, sizeof(buf), "-%s", prchar(c)); return (buf); } ! /* ! * Scan an argument (either from the command line or from the * LESS environment variable) and process it. */ ! public void ! 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) --- 54,84 ---- * Return a string suitable for printing as the "name" of an option. * For example, if the option letter is 'x', just return "-x". */ ! char * ! propt(int c) { static char buf[8]; ! (void) snprintf(buf, sizeof (buf), "-%s", prchar(c)); return (buf); } ! /* ! * Scan an argument (either from the command line or from the * LESS environment variable) and process it. */ ! void ! scan_option(char *s) { ! struct loption *o; ! int optc; char *optname; char *printopt; char *str; int set_default; int lc; int err; + int moreopt; PARG parg; if (s == NULL) *************** *** 89,104 **** * 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 = opt_desc(pendopt); ! *(pendopt->ovar) = getnum(&s, printopt, (int*)NULL); break; } pendopt = NULL; --- 91,104 ---- * 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 = opt_desc(pendopt); ! *(pendopt->ovar) = getnum(&s, printopt, NULL); break; } pendopt = NULL; *************** *** 107,148 **** set_default = FALSE; optname = NULL; ! while (*s != '\0') ! { /* * Check some special cases first. */ ! switch (optc = *s++) ! { case ' ': case '\t': case END_OPTION_STRING: continue; case '-': - #if GNU_OPTIONS /* * "--" indicates an option name instead of a letter. */ ! if (*s == '-') ! { ! optname = ++s; break; } - #endif /* * "-+" 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 '+': /* ! * An option prefixed by a "+" is ungotten, so ! * that it is interpreted as less commands * processed at the start of the first input file. * "++" means process the commands at the start of * EVERY input file. --- 107,149 ---- set_default = FALSE; optname = NULL; + moreopt = 0; + o = NULL; ! while (*s != '\0') { /* * Check some special cases first. */ ! switch (optc = *s++) { case ' ': case '\t': case END_OPTION_STRING: continue; case '-': /* * "--" indicates an option name instead of a letter. */ ! if (*s == '-') { ! if (!less_is_more) { ! optname = ++s; ! } break; } /* * "-+" means set these options back to their defaults. ! * (They may have been set otherwise by previous * options.) */ ! if (!less_is_more) { ! set_default = (*s == '+'); ! if (set_default) ! s++; ! } continue; case '+': /* ! * An option prefixed by a "+" is ungotten, so ! * that it is interpreted as less commands * processed at the start of the first input file. * "++" means process the commands at the start of * EVERY input file. *************** *** 161,176 **** case '5': case '6': case '7': case '8': case '9': /* * Special "more" compatibility form "-" ! * instead of -z to set the scrolling * window size. */ s--; optc = 'z'; break; case 'n': ! if (less_is_more) optc = 'z'; break; } /* --- 162,210 ---- case '5': case '6': case '7': case '8': case '9': /* * Special "more" compatibility form "-" ! * instead of -z to set the scrolling * window size. */ s--; optc = 'z'; + moreopt = 1; break; case 'n': ! if (less_is_more) { ! moreopt = 1; optc = 'z'; + } break; + case 'i': + if (less_is_more) { + moreopt = 1; + optc = 'I'; + } + break; + case 'u': + if (less_is_more) { + moreopt = 1; + optc = 'U'; + } + break; + case 'e': + if (less_is_more) { + moreopt = 1; + optc = 'E'; + } + break; + case 'h': + if (less_is_more) { + moreopt = 1; + optc = '?'; + } + break; + case 'd': + if (less_is_more) { + moreopt = 1; + optc = 'M'; + } + break; } /* *************** *** 178,243 **** * Look up the option letter in the option table. */ err = 0; ! if (optname == NULL) ! { printopt = propt(optc); ! lc = ASCII_IS_LOWER(optc); o = findopt(optc); ! } ! #if GNU_OPTIONS ! else ! { printopt = optname; ! lc = ASCII_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); return; } s++; ! } else ! { ! /* ! * The specified name is longer than the ! * real option name. ! */ o = NULL; } } ! #endif ! 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); return; } str = NULL; ! switch (o->otype & OTYPE) ! { case BOOL: if (set_default) *(o->ovar) = o->odefault; --- 212,268 ---- * Look up the option letter in the option table. */ err = 0; ! if (optname == NULL) { printopt = propt(optc); ! lc = islower(optc); o = findopt(optc); ! if (less_is_more && (!moreopt) && (o != NULL) && ! ((o->otype & MORE_OK) == 0)) { ! o = NULL; ! } ! } else { printopt = optname; ! lc = islower(optname[0]); o = findopt_name(&optname, NULL, &err); s = optname; optname = NULL; ! switch (*s) { ! case ' ': /* name matches exactly */ ! case '\0': ! break; ! ! case '=': /* name 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); return; } s++; ! break; ! default: /* name longer than option, bad */ o = NULL; } } ! if (o == NULL) { parg.p_string = printopt; ! if (less_is_more) { ! error("Illegal option %s (more -h for help)", ! &parg); ! } else 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); ! } return; } str = NULL; ! switch (o->otype & OTYPE) { case BOOL: if (set_default) *(o->ovar) = o->odefault; *************** *** 251,258 **** *(o->ovar) = flip_triple(o->odefault, lc); break; case STRING: ! if (*s == '\0') ! { /* * Set pendopt and return. * We will get the string next time --- 276,282 ---- *(o->ovar) = flip_triple(o->odefault, lc); break; case STRING: ! if (*s == '\0') { /* * Set pendopt and return. * We will get the string next time *************** *** 263,269 **** } /* * Don't do anything here. ! * All processing of STRING options is done by * the handling function. */ while (*s == ' ') --- 287,293 ---- } /* * Don't do anything here. ! * All processing of STRING options is done by * the handling function. */ while (*s == ' ') *************** *** 273,284 **** return; break; case NUMBER: ! if (*s == '\0') ! { pendopt = o; return; } ! *(o->ovar) = getnum(&s, printopt, (int*)NULL); break; } /* --- 297,307 ---- return; break; case NUMBER: ! if (*s == '\0') { pendopt = o; return; } ! *(o->ovar) = getnum(&s, printopt, NULL); break; } /* *************** *** 300,313 **** * OPT_UNSET set to the default value * OPT_SET set to the inverse of the default value */ ! public void ! toggle_option(o, lower, s, how_toggle) ! struct loption *o; ! int lower; ! char *s; ! int how_toggle; { ! register int num; int no_prompt; int err; PARG parg; --- 323,332 ---- * OPT_UNSET set to the default value * OPT_SET set to the inverse of the default value */ ! void ! toggle_option(struct loption *o, int lower, char *s, int how_toggle) { ! int num; int no_prompt; int err; PARG parg; *************** *** 315,339 **** no_prompt = (how_toggle & OPT_NO_PROMPT); how_toggle &= ~OPT_NO_PROMPT; ! if (o == NULL) ! { error("No such option", NULL_PARG); return; } ! if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) ! { parg.p_string = opt_desc(o); error("Cannot change the %s option", &parg); return; } ! if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) ! { parg.p_string = opt_desc(o); error("Cannot query the %s option", &parg); return; ! } /* * Check for something which appears to be a do_toggle --- 334,355 ---- no_prompt = (how_toggle & OPT_NO_PROMPT); how_toggle &= ~OPT_NO_PROMPT; ! if (o == NULL) { error("No such option", NULL_PARG); return; } ! if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) { parg.p_string = opt_desc(o); error("Cannot change the %s option", &parg); return; } ! if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) { parg.p_string = opt_desc(o); error("Cannot query the %s option", &parg); return; ! } /* * Check for something which appears to be a do_toggle *************** *** 341,348 **** * This could be a string option with no string, or * a number option with no number. */ ! switch (o->otype & OTYPE) ! { case STRING: case NUMBER: if (how_toggle == OPT_TOGGLE && *s == '\0') --- 357,363 ---- * This could be a string option with no string, or * a number option with no number. */ ! switch (o->otype & OTYPE) { case STRING: case NUMBER: if (how_toggle == OPT_TOGGLE && *s == '\0') *************** *** 350,373 **** break; } - #if HILITE_SEARCH if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) repaint_hilite(0); - #endif /* * Now actually toggle (change) the variable. */ ! if (how_toggle != OPT_NO_TOGGLE) ! { ! switch (o->otype & OTYPE) ! { case BOOL: /* * Boolean. */ ! switch (how_toggle) ! { case OPT_TOGGLE: *(o->ovar) = ! *(o->ovar); break; --- 365,383 ---- break; } if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) repaint_hilite(0); /* * Now actually toggle (change) the variable. */ ! if (how_toggle != OPT_NO_TOGGLE) { ! switch (o->otype & OTYPE) { case BOOL: /* * Boolean. */ ! switch (how_toggle) { case OPT_TOGGLE: *(o->ovar) = ! *(o->ovar); break; *************** *** 382,394 **** case TRIPLE: /* * Triple: ! * If user gave the lower case letter, then switch * to 1 unless already 1, in which case make it 0. * If user gave the upper case letter, then switch * to 2 unless already 2, in which case make it 0. */ ! switch (how_toggle) ! { case OPT_TOGGLE: *(o->ovar) = flip_triple(*(o->ovar), lower); break; --- 392,403 ---- case TRIPLE: /* * Triple: ! * If user gave the lower case letter, then switch * to 1 unless already 1, in which case make it 0. * If user gave the upper case letter, then switch * to 2 unless already 2, in which case make it 0. */ ! switch (how_toggle) { case OPT_TOGGLE: *(o->ovar) = flip_triple(*(o->ovar), lower); break; *************** *** 405,416 **** * String: don't do anything here. * The handling function will do everything. */ ! switch (how_toggle) ! { case OPT_SET: case OPT_UNSET: ! error("Cannot use \"-+\" or \"--\" for a string option", ! NULL_PARG); return; } break; --- 414,424 ---- * String: don't do anything here. * The handling function will do everything. */ ! switch (how_toggle) { case OPT_SET: case OPT_UNSET: ! error("Cannot use \"-+\" or \"--\" " ! "for a string option", NULL_PARG); return; } break; *************** *** 418,425 **** /* * Number: set the variable to the given number. */ ! switch (how_toggle) ! { case OPT_TOGGLE: num = getnum(&s, NULL, &err); if (!err) --- 426,432 ---- /* * Number: set the variable to the given number. */ ! switch (how_toggle) { case OPT_TOGGLE: num = getnum(&s, NULL, &err); if (!err) *************** *** 430,436 **** break; case OPT_SET: error("Can't use \"-!\" for a numeric option", ! NULL_PARG); return; } break; --- 437,443 ---- break; case OPT_SET: error("Can't use \"-!\" for a numeric option", ! NULL_PARG); return; } break; *************** *** 438,461 **** } /* ! * Call the handling function for any special action * specific to this option. */ if (o->ofunc != NULL) ! (*o->ofunc)((how_toggle==OPT_NO_TOGGLE) ? QUERY : TOGGLE, s); - #if HILITE_SEARCH if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) chg_hilite(); - #endif ! if (!no_prompt) ! { /* * Print a message describing the new setting. */ ! switch (o->otype & OTYPE) ! { case BOOL: case TRIPLE: /* --- 445,464 ---- } /* ! * Call the handling function for any special action * specific to this option. */ if (o->ofunc != NULL) ! (*o->ofunc)((how_toggle == OPT_NO_TOGGLE) ? QUERY : TOGGLE, s); if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) chg_hilite(); ! if (!no_prompt) { /* * Print a message describing the new setting. */ ! switch (o->otype & OTYPE) { case BOOL: case TRIPLE: /* *************** *** 465,471 **** break; case NUMBER: /* ! * The message is in odesc[1] and has a %d for * the value of the variable. */ parg.p_int = *(o->ovar); --- 468,474 ---- break; case NUMBER: /* ! * The message is in odesc[1] and has a %d for * the value of the variable. */ parg.p_int = *(o->ovar); *************** *** 486,495 **** /* * "Toggle" a triple-valued option. */ ! static int ! flip_triple(val, lc) ! int val; ! int lc; { if (lc) return ((val == OPT_ON) ? OPT_OFF : OPT_ON); --- 489,496 ---- /* * "Toggle" a triple-valued option. */ ! static int ! flip_triple(int val, int lc) { if (lc) return ((val == OPT_ON) ? OPT_OFF : OPT_ON); *************** *** 500,508 **** /* * Determine if an option takes a parameter. */ ! public int ! opt_has_param(o) ! struct loption *o; { if (o == NULL) return (0); --- 501,508 ---- /* * Determine if an option takes a parameter. */ ! int ! opt_has_param(struct loption *o) { if (o == NULL) return (0); *************** *** 515,523 **** * Return the prompt to be used for a given option letter. * Only string and number valued options have prompts. */ ! public char * ! opt_prompt(o) ! struct loption *o; { if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) return ("?"); --- 515,522 ---- * Return the prompt to be used for a given option letter. * Only string and number valued options have prompts. */ ! char * ! opt_prompt(struct loption *o) { if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) return ("?"); *************** *** 526,538 **** /* * Return whether or not there is a string option pending; ! * that is, if the previous option was a string-valued option letter * (like -P) without a following string. * In that case, the current option is taken to be the string for * the previous option. */ ! public int ! isoptpending() { return (pendopt != NULL); } --- 525,537 ---- /* * Return whether or not there is a string option pending; ! * that is, if the previous option was a string-valued option letter * (like -P) without a following string. * In that case, the current option is taken to be the string for * the previous option. */ ! int ! isoptpending(void) { return (pendopt != NULL); } *************** *** 540,548 **** /* * Print error message about missing string. */ ! static void ! nostring(printopt) ! char *printopt; { PARG parg; parg.p_string = printopt; --- 539,546 ---- /* * Print error message about missing string. */ ! static void ! nostring(char *printopt) { PARG parg; parg.p_string = printopt; *************** *** 552,559 **** /* * Print error message if a STRING type option is not followed by a string. */ ! public void ! nopendopt() { nostring(opt_desc(pendopt)); } --- 550,557 ---- /* * Print error message if a STRING type option is not followed by a string. */ ! void ! nopendopt(void) { nostring(opt_desc(pendopt)); } *************** *** 563,597 **** * In the latter case, replace the char with a null char. * 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; ! register char *out; ! if (*s == '\0') ! { nostring(printopt); return (NULL); } /* Alloc could be more than needed, but not worth trimming. */ ! *p_str = (char *) ecalloc(strlen(s)+1, sizeof(char)); out = *p_str; ! for (p = s; *p != '\0'; p++) ! { ! if (opt_use_backslash && *p == '\\' && p[1] != '\0') ! { /* Take next char literally. */ ++p; ! } else ! { ! if (*p == END_OPTION_STRING || ! (validchars != NULL && strchr(validchars, *p) == NULL)) /* End of option string. */ break; } --- 561,588 ---- * In the latter case, replace the char with a null char. * Return a pointer to the remainder of the string, if any. */ ! static char * ! optstring(char *s, char **p_str, char *printopt, char *validchars) { ! char *p; ! char *out; ! if (*s == '\0') { nostring(printopt); return (NULL); } /* Alloc could be more than needed, but not worth trimming. */ ! *p_str = ecalloc(strlen(s)+1, sizeof (char)); out = *p_str; ! for (p = s; *p != '\0'; p++) { ! if (opt_use_backslash && *p == '\\' && p[1] != '\0') { /* Take next char literally. */ ++p; ! } else { ! if (*p == END_OPTION_STRING || ! (validchars != NULL && ! strchr(validchars, *p) == NULL)) /* End of option string. */ break; } *************** *** 603,622 **** /* */ ! 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); } --- 594,609 ---- /* */ ! static int ! num_error(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); } *************** *** 628,647 **** * Like atoi(), but takes a pointer to a char *, and updates * 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; s = skipsp(*sp); neg = FALSE; ! if (*s == '-') ! { neg = TRUE; s++; } --- 615,630 ---- * Like atoi(), but takes a pointer to a char *, and updates * the char * to point after the translated number. */ ! int ! getnum(char **sp, char *printopt, int *errp) { ! char *s; ! int n; ! int neg; s = skipsp(*sp); neg = FALSE; ! if (*s == '-') { neg = TRUE; s++; } *************** *** 665,677 **** * 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; --- 648,657 ---- * 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. */ ! long ! getfraction(char **sp, char *printopt, int *errp) { ! char *s; long frac = 0; int fraclen = 0; *************** *** 679,686 **** if (*s < '0' || *s > '9') return (num_error(printopt, errp)); ! for ( ; *s >= '0' && *s <= '9'; s++) ! { frac = (frac * 10) + (*s - '0'); fraclen++; } --- 659,665 ---- if (*s < '0' || *s > '9') return (num_error(printopt, errp)); ! for (; *s >= '0' && *s <= '9'; s++) { frac = (frac * 10) + (*s - '0'); fraclen++; } *************** *** 700,710 **** /* * 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_ONPLUS : OPT_ON; } --- 679,686 ---- /* * Get the value of the -e flag. */ ! int ! get_quit_at_eof(void) { ! return (quit_at_eof); }