option.c revision 330571
1238730Sdelphij/* 2330571Sdelphij * Copyright (C) 1984-2017 Mark Nudelman 3238730Sdelphij * 4238730Sdelphij * You may distribute under the terms of either the GNU General Public 5238730Sdelphij * License or the Less License, as specified in the README file. 6238730Sdelphij * 7238730Sdelphij * For more information, see the README file. 8238730Sdelphij */ 960786Sps 1060786Sps 1160786Sps/* 1260786Sps * Process command line options. 1360786Sps * 1460786Sps * Each option is a single letter which controls a program variable. 1560786Sps * The options have defaults which may be changed via 1660786Sps * the command line option, toggled via the "-" command, 1760786Sps * or queried via the "_" command. 1860786Sps */ 1960786Sps 2060786Sps#include "less.h" 2160786Sps#include "option.h" 2260786Sps 23128345Stjrstatic struct loption *pendopt; 2460786Spspublic int plusoption = FALSE; 2560786Sps 2660786Spsstatic char *optstring(); 2760786Spsstatic int flip_triple(); 2860786Sps 2960786Spsextern int screen_trashed; 30170256Sdelphijextern int less_is_more; 31170256Sdelphijextern int quit_at_eof; 3260786Spsextern char *every_first_cmd; 33250592Sdelphijextern int opt_use_backslash; 3460786Sps 35221715Sdelphij/* 36221715Sdelphij * Return a printable description of an option. 37221715Sdelphij */ 38221715Sdelphij static char * 39221715Sdelphijopt_desc(o) 40221715Sdelphij struct loption *o; 41221715Sdelphij{ 42221715Sdelphij static char buf[OPTNAME_MAX + 10]; 43221715Sdelphij if (o->oletter == OLETTER_NONE) 44221715Sdelphij SNPRINTF1(buf, sizeof(buf), "--%s", o->onames->oname); 45221715Sdelphij else 46221715Sdelphij SNPRINTF2(buf, sizeof(buf), "-%c (--%s)", o->oletter, o->onames->oname); 47221715Sdelphij return (buf); 48221715Sdelphij} 49221715Sdelphij 50221715Sdelphij/* 51221715Sdelphij * Return a string suitable for printing as the "name" of an option. 52221715Sdelphij * For example, if the option letter is 'x', just return "-x". 53221715Sdelphij */ 54221715Sdelphij public char * 55221715Sdelphijpropt(c) 56221715Sdelphij int c; 57221715Sdelphij{ 58221715Sdelphij static char buf[8]; 59221715Sdelphij 60221715Sdelphij sprintf(buf, "-%s", prchar(c)); 61221715Sdelphij return (buf); 62221715Sdelphij} 63221715Sdelphij 6460786Sps/* 6560786Sps * Scan an argument (either from the command line or from the 6660786Sps * LESS environment variable) and process it. 6760786Sps */ 6860786Sps public void 6960786Spsscan_option(s) 7060786Sps char *s; 7160786Sps{ 72330571Sdelphij struct loption *o; 73330571Sdelphij int optc; 7460786Sps char *optname; 7560786Sps char *printopt; 7660786Sps char *str; 7760786Sps int set_default; 7860786Sps int lc; 7960786Sps int err; 8060786Sps PARG parg; 8160786Sps 8260786Sps if (s == NULL) 8360786Sps return; 8460786Sps 8560786Sps /* 8660786Sps * If we have a pending option which requires an argument, 8760786Sps * handle it now. 8860786Sps * This happens if the previous option was, for example, "-P" 8960786Sps * without a following string. In that case, the current 9060786Sps * option is simply the argument for the previous option. 9160786Sps */ 9260786Sps if (pendopt != NULL) 9360786Sps { 9460786Sps switch (pendopt->otype & OTYPE) 9560786Sps { 9660786Sps case STRING: 9760786Sps (*pendopt->ofunc)(INIT, s); 9860786Sps break; 9960786Sps case NUMBER: 100221715Sdelphij printopt = opt_desc(pendopt); 10160786Sps *(pendopt->ovar) = getnum(&s, printopt, (int*)NULL); 10260786Sps break; 10360786Sps } 10460786Sps pendopt = NULL; 10560786Sps return; 10660786Sps } 10760786Sps 10860786Sps set_default = FALSE; 10960786Sps optname = NULL; 11060786Sps 11160786Sps while (*s != '\0') 11260786Sps { 11360786Sps /* 11460786Sps * Check some special cases first. 11560786Sps */ 11660786Sps switch (optc = *s++) 11760786Sps { 11860786Sps case ' ': 11960786Sps case '\t': 12060786Sps case END_OPTION_STRING: 12160786Sps continue; 12260786Sps case '-': 12360786Sps /* 12460786Sps * "--" indicates an option name instead of a letter. 12560786Sps */ 12660786Sps if (*s == '-') 12760786Sps { 12860786Sps optname = ++s; 12960786Sps break; 13060786Sps } 13160786Sps /* 13260786Sps * "-+" means set these options back to their defaults. 13360786Sps * (They may have been set otherwise by previous 13460786Sps * options.) 13560786Sps */ 13660786Sps set_default = (*s == '+'); 13760786Sps if (set_default) 13860786Sps s++; 13960786Sps continue; 14060786Sps case '+': 14160786Sps /* 14260786Sps * An option prefixed by a "+" is ungotten, so 14360786Sps * that it is interpreted as less commands 14460786Sps * processed at the start of the first input file. 14560786Sps * "++" means process the commands at the start of 14660786Sps * EVERY input file. 14760786Sps */ 14860786Sps plusoption = TRUE; 149128345Stjr s = optstring(s, &str, propt('+'), NULL); 150242584Sdelphij if (s == NULL) 151242584Sdelphij return; 15289019Sps if (*str == '+') 153243829Sdelphij every_first_cmd = save(str+1); 15460786Sps else 155294286Sdelphij { 156294286Sdelphij ungetcc(CHAR_END_COMMAND); 15789019Sps ungetsc(str); 158294286Sdelphij } 159242584Sdelphij free(str); 16060786Sps continue; 16160786Sps case '0': case '1': case '2': case '3': case '4': 16260786Sps case '5': case '6': case '7': case '8': case '9': 16360786Sps /* 16460786Sps * Special "more" compatibility form "-<number>" 16560786Sps * instead of -z<number> to set the scrolling 16660786Sps * window size. 16760786Sps */ 16860786Sps s--; 16960786Sps optc = 'z'; 17060786Sps break; 171170256Sdelphij case 'n': 172170256Sdelphij if (less_is_more) 173170256Sdelphij optc = 'z'; 174170256Sdelphij break; 17560786Sps } 17660786Sps 17760786Sps /* 17860786Sps * Not a special case. 17960786Sps * Look up the option letter in the option table. 18060786Sps */ 18160786Sps err = 0; 18260786Sps if (optname == NULL) 18360786Sps { 18460786Sps printopt = propt(optc); 185161475Sdelphij lc = ASCII_IS_LOWER(optc); 18660786Sps o = findopt(optc); 18760786Sps } else 18860786Sps { 18960786Sps printopt = optname; 190161475Sdelphij lc = ASCII_IS_LOWER(optname[0]); 19160786Sps o = findopt_name(&optname, NULL, &err); 19260786Sps s = optname; 19360786Sps optname = NULL; 19460786Sps if (*s == '\0' || *s == ' ') 19560786Sps { 19660786Sps /* 19760786Sps * The option name matches exactly. 19860786Sps */ 19960786Sps ; 20060786Sps } else if (*s == '=') 20160786Sps { 20260786Sps /* 20360786Sps * The option name is followed by "=value". 20460786Sps */ 20560786Sps if (o != NULL && 20660786Sps (o->otype & OTYPE) != STRING && 20760786Sps (o->otype & OTYPE) != NUMBER) 20860786Sps { 20960786Sps parg.p_string = printopt; 21060786Sps error("The %s option should not be followed by =", 21160786Sps &parg); 212242584Sdelphij return; 21360786Sps } 21460786Sps s++; 21560786Sps } else 21660786Sps { 21760786Sps /* 21860786Sps * The specified name is longer than the 21960786Sps * real option name. 22060786Sps */ 22160786Sps o = NULL; 22260786Sps } 22360786Sps } 22460786Sps if (o == NULL) 22560786Sps { 22660786Sps parg.p_string = printopt; 22760786Sps if (err == OPT_AMBIG) 22860786Sps error("%s is an ambiguous abbreviation (\"less --help\" for help)", 22960786Sps &parg); 23060786Sps else 23160786Sps error("There is no %s option (\"less --help\" for help)", 23260786Sps &parg); 233242584Sdelphij return; 23460786Sps } 23560786Sps 23660786Sps str = NULL; 23760786Sps switch (o->otype & OTYPE) 23860786Sps { 23960786Sps case BOOL: 24060786Sps if (set_default) 24160786Sps *(o->ovar) = o->odefault; 24260786Sps else 24360786Sps *(o->ovar) = ! o->odefault; 24460786Sps break; 24560786Sps case TRIPLE: 24660786Sps if (set_default) 24760786Sps *(o->ovar) = o->odefault; 24860786Sps else 24960786Sps *(o->ovar) = flip_triple(o->odefault, lc); 25060786Sps break; 25160786Sps case STRING: 25260786Sps if (*s == '\0') 25360786Sps { 25460786Sps /* 25560786Sps * Set pendopt and return. 25660786Sps * We will get the string next time 25760786Sps * scan_option is called. 25860786Sps */ 25960786Sps pendopt = o; 26060786Sps return; 26160786Sps } 26260786Sps /* 26360786Sps * Don't do anything here. 26460786Sps * All processing of STRING options is done by 26560786Sps * the handling function. 26660786Sps */ 267128345Stjr while (*s == ' ') 268128345Stjr s++; 269128345Stjr s = optstring(s, &str, printopt, o->odesc[1]); 270242584Sdelphij if (s == NULL) 271242584Sdelphij return; 27260786Sps break; 27360786Sps case NUMBER: 27460786Sps if (*s == '\0') 27560786Sps { 27660786Sps pendopt = o; 27760786Sps return; 27860786Sps } 27960786Sps *(o->ovar) = getnum(&s, printopt, (int*)NULL); 28060786Sps break; 28160786Sps } 28260786Sps /* 28360786Sps * If the option has a handling function, call it. 28460786Sps */ 28560786Sps if (o->ofunc != NULL) 28660786Sps (*o->ofunc)(INIT, str); 287242584Sdelphij if (str != NULL) 288242584Sdelphij free(str); 28960786Sps } 29060786Sps} 29160786Sps 29260786Sps/* 29360786Sps * Toggle command line flags from within the program. 29460786Sps * Used by the "-" and "_" commands. 29560786Sps * how_toggle may be: 29660786Sps * OPT_NO_TOGGLE just report the current setting, without changing it. 29760786Sps * OPT_TOGGLE invert the current setting 29860786Sps * OPT_UNSET set to the default value 29960786Sps * OPT_SET set to the inverse of the default value 30060786Sps */ 30160786Sps public void 302221715Sdelphijtoggle_option(o, lower, s, how_toggle) 303221715Sdelphij struct loption *o; 304221715Sdelphij int lower; 30560786Sps char *s; 30660786Sps int how_toggle; 30760786Sps{ 308330571Sdelphij int num; 30960786Sps int no_prompt; 31060786Sps int err; 31160786Sps PARG parg; 31260786Sps 31360786Sps no_prompt = (how_toggle & OPT_NO_PROMPT); 31460786Sps how_toggle &= ~OPT_NO_PROMPT; 31560786Sps 31660786Sps if (o == NULL) 31760786Sps { 318221715Sdelphij error("No such option", NULL_PARG); 31960786Sps return; 32060786Sps } 32160786Sps 32260786Sps if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) 32360786Sps { 324221715Sdelphij parg.p_string = opt_desc(o); 32560786Sps error("Cannot change the %s option", &parg); 32660786Sps return; 327221715Sdelphij } 32860786Sps 32960786Sps if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) 33060786Sps { 331221715Sdelphij parg.p_string = opt_desc(o); 33260786Sps error("Cannot query the %s option", &parg); 33360786Sps return; 33460786Sps } 33560786Sps 33660786Sps /* 33760786Sps * Check for something which appears to be a do_toggle 33860786Sps * (because the "-" command was used), but really is not. 33960786Sps * This could be a string option with no string, or 34060786Sps * a number option with no number. 34160786Sps */ 34260786Sps switch (o->otype & OTYPE) 34360786Sps { 34460786Sps case STRING: 34560786Sps case NUMBER: 34660786Sps if (how_toggle == OPT_TOGGLE && *s == '\0') 34760786Sps how_toggle = OPT_NO_TOGGLE; 34860786Sps break; 34960786Sps } 35060786Sps 35160786Sps#if HILITE_SEARCH 35260786Sps if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) 35360786Sps repaint_hilite(0); 35460786Sps#endif 35560786Sps 35660786Sps /* 35760786Sps * Now actually toggle (change) the variable. 35860786Sps */ 35960786Sps if (how_toggle != OPT_NO_TOGGLE) 36060786Sps { 36160786Sps switch (o->otype & OTYPE) 36260786Sps { 36360786Sps case BOOL: 36460786Sps /* 36560786Sps * Boolean. 36660786Sps */ 36760786Sps switch (how_toggle) 36860786Sps { 36960786Sps case OPT_TOGGLE: 37060786Sps *(o->ovar) = ! *(o->ovar); 37160786Sps break; 37260786Sps case OPT_UNSET: 37360786Sps *(o->ovar) = o->odefault; 37460786Sps break; 37560786Sps case OPT_SET: 37660786Sps *(o->ovar) = ! o->odefault; 37760786Sps break; 37860786Sps } 37960786Sps break; 38060786Sps case TRIPLE: 38160786Sps /* 38260786Sps * Triple: 38360786Sps * If user gave the lower case letter, then switch 38460786Sps * to 1 unless already 1, in which case make it 0. 38560786Sps * If user gave the upper case letter, then switch 38660786Sps * to 2 unless already 2, in which case make it 0. 38760786Sps */ 38860786Sps switch (how_toggle) 38960786Sps { 39060786Sps case OPT_TOGGLE: 391221715Sdelphij *(o->ovar) = flip_triple(*(o->ovar), lower); 39260786Sps break; 39360786Sps case OPT_UNSET: 39460786Sps *(o->ovar) = o->odefault; 39560786Sps break; 39660786Sps case OPT_SET: 397221715Sdelphij *(o->ovar) = flip_triple(o->odefault, lower); 39860786Sps break; 39960786Sps } 40060786Sps break; 40160786Sps case STRING: 40260786Sps /* 40360786Sps * String: don't do anything here. 40460786Sps * The handling function will do everything. 40560786Sps */ 40660786Sps switch (how_toggle) 40760786Sps { 40860786Sps case OPT_SET: 40960786Sps case OPT_UNSET: 41060786Sps error("Cannot use \"-+\" or \"--\" for a string option", 41160786Sps NULL_PARG); 41260786Sps return; 41360786Sps } 41460786Sps break; 41560786Sps case NUMBER: 41660786Sps /* 41760786Sps * Number: set the variable to the given number. 41860786Sps */ 41960786Sps switch (how_toggle) 42060786Sps { 42160786Sps case OPT_TOGGLE: 422128345Stjr num = getnum(&s, NULL, &err); 42360786Sps if (!err) 42460786Sps *(o->ovar) = num; 42560786Sps break; 42660786Sps case OPT_UNSET: 42760786Sps *(o->ovar) = o->odefault; 42860786Sps break; 42960786Sps case OPT_SET: 43060786Sps error("Can't use \"-!\" for a numeric option", 43160786Sps NULL_PARG); 43260786Sps return; 43360786Sps } 43460786Sps break; 43560786Sps } 43660786Sps } 43760786Sps 43860786Sps /* 43960786Sps * Call the handling function for any special action 44060786Sps * specific to this option. 44160786Sps */ 44260786Sps if (o->ofunc != NULL) 44360786Sps (*o->ofunc)((how_toggle==OPT_NO_TOGGLE) ? QUERY : TOGGLE, s); 44460786Sps 44560786Sps#if HILITE_SEARCH 44660786Sps if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) 44760786Sps chg_hilite(); 44860786Sps#endif 44960786Sps 45060786Sps if (!no_prompt) 45160786Sps { 45260786Sps /* 45360786Sps * Print a message describing the new setting. 45460786Sps */ 45560786Sps switch (o->otype & OTYPE) 45660786Sps { 45760786Sps case BOOL: 45860786Sps case TRIPLE: 45960786Sps /* 46060786Sps * Print the odesc message. 46160786Sps */ 46260786Sps error(o->odesc[*(o->ovar)], NULL_PARG); 46360786Sps break; 46460786Sps case NUMBER: 46560786Sps /* 46660786Sps * The message is in odesc[1] and has a %d for 46760786Sps * the value of the variable. 46860786Sps */ 46960786Sps parg.p_int = *(o->ovar); 47060786Sps error(o->odesc[1], &parg); 47160786Sps break; 47260786Sps case STRING: 47360786Sps /* 47460786Sps * Message was already printed by the handling function. 47560786Sps */ 47660786Sps break; 47760786Sps } 47860786Sps } 47960786Sps 48060786Sps if (how_toggle != OPT_NO_TOGGLE && (o->otype & REPAINT)) 48160786Sps screen_trashed = TRUE; 48260786Sps} 48360786Sps 48460786Sps/* 48560786Sps * "Toggle" a triple-valued option. 48660786Sps */ 48760786Sps static int 48860786Spsflip_triple(val, lc) 48960786Sps int val; 49060786Sps int lc; 49160786Sps{ 49260786Sps if (lc) 49360786Sps return ((val == OPT_ON) ? OPT_OFF : OPT_ON); 49460786Sps else 49560786Sps return ((val == OPT_ONPLUS) ? OPT_OFF : OPT_ONPLUS); 49660786Sps} 49760786Sps 49860786Sps/* 499221715Sdelphij * Determine if an option takes a parameter. 50060786Sps */ 50160786Sps public int 502221715Sdelphijopt_has_param(o) 503221715Sdelphij struct loption *o; 50460786Sps{ 50560786Sps if (o == NULL) 506221715Sdelphij return (0); 507221715Sdelphij if (o->otype & (BOOL|TRIPLE|NOVAR|NO_TOGGLE)) 508221715Sdelphij return (0); 509221715Sdelphij return (1); 51060786Sps} 51160786Sps 51260786Sps/* 51360786Sps * Return the prompt to be used for a given option letter. 51460786Sps * Only string and number valued options have prompts. 51560786Sps */ 51660786Sps public char * 517221715Sdelphijopt_prompt(o) 518221715Sdelphij struct loption *o; 51960786Sps{ 52060786Sps if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) 521221715Sdelphij return ("?"); 52260786Sps return (o->odesc[0]); 52360786Sps} 52460786Sps 52560786Sps/* 52660786Sps * Return whether or not there is a string option pending; 52760786Sps * that is, if the previous option was a string-valued option letter 52860786Sps * (like -P) without a following string. 52960786Sps * In that case, the current option is taken to be the string for 53060786Sps * the previous option. 53160786Sps */ 53260786Sps public int 53360786Spsisoptpending() 53460786Sps{ 53560786Sps return (pendopt != NULL); 53660786Sps} 53760786Sps 53860786Sps/* 53960786Sps * Print error message about missing string. 54060786Sps */ 54160786Sps static void 54260786Spsnostring(printopt) 54360786Sps char *printopt; 54460786Sps{ 54560786Sps PARG parg; 54660786Sps parg.p_string = printopt; 54760786Sps error("Value is required after %s", &parg); 54860786Sps} 54960786Sps 55060786Sps/* 55160786Sps * Print error message if a STRING type option is not followed by a string. 55260786Sps */ 55360786Sps public void 55460786Spsnopendopt() 55560786Sps{ 556221715Sdelphij nostring(opt_desc(pendopt)); 55760786Sps} 55860786Sps 55960786Sps/* 56060786Sps * Scan to end of string or to an END_OPTION_STRING character. 56160786Sps * In the latter case, replace the char with a null char. 56260786Sps * Return a pointer to the remainder of the string, if any. 56360786Sps */ 56460786Sps static char * 565128345Stjroptstring(s, p_str, printopt, validchars) 56660786Sps char *s; 567128345Stjr char **p_str; 56860786Sps char *printopt; 56989019Sps char *validchars; 57060786Sps{ 571330571Sdelphij char *p; 572330571Sdelphij char *out; 57360786Sps 57460786Sps if (*s == '\0') 57560786Sps { 57660786Sps nostring(printopt); 577242584Sdelphij return (NULL); 57860786Sps } 579242584Sdelphij /* Alloc could be more than needed, but not worth trimming. */ 580242584Sdelphij *p_str = (char *) ecalloc(strlen(s)+1, sizeof(char)); 581242584Sdelphij out = *p_str; 582242584Sdelphij 58360786Sps for (p = s; *p != '\0'; p++) 584128345Stjr { 585250592Sdelphij if (opt_use_backslash && *p == '\\' && p[1] != '\0') 58660786Sps { 587242584Sdelphij /* Take next char literally. */ 588242584Sdelphij ++p; 589242584Sdelphij } else 590242584Sdelphij { 591242584Sdelphij if (*p == END_OPTION_STRING || 592242584Sdelphij (validchars != NULL && strchr(validchars, *p) == NULL)) 593242584Sdelphij /* End of option string. */ 59489019Sps break; 59560786Sps } 596242584Sdelphij *out++ = *p; 597128345Stjr } 598242584Sdelphij *out = '\0'; 59960786Sps return (p); 60060786Sps} 60160786Sps 60260786Sps/* 603170256Sdelphij */ 604170256Sdelphij static int 605170256Sdelphijnum_error(printopt, errp) 606170256Sdelphij char *printopt; 607170256Sdelphij int *errp; 608170256Sdelphij{ 609170256Sdelphij PARG parg; 610170256Sdelphij 611170256Sdelphij if (errp != NULL) 612170256Sdelphij { 613170256Sdelphij *errp = TRUE; 614170256Sdelphij return (-1); 615170256Sdelphij } 616170256Sdelphij if (printopt != NULL) 617170256Sdelphij { 618170256Sdelphij parg.p_string = printopt; 619170256Sdelphij error("Number is required after %s", &parg); 620170256Sdelphij } 621170256Sdelphij return (-1); 622170256Sdelphij} 623170256Sdelphij 624170256Sdelphij/* 62560786Sps * Translate a string into a number. 62660786Sps * Like atoi(), but takes a pointer to a char *, and updates 62760786Sps * the char * to point after the translated number. 62860786Sps */ 62960786Sps public int 63060786Spsgetnum(sp, printopt, errp) 63160786Sps char **sp; 63260786Sps char *printopt; 63360786Sps int *errp; 63460786Sps{ 635330571Sdelphij char *s; 636330571Sdelphij int n; 637330571Sdelphij int neg; 63860786Sps 63960786Sps s = skipsp(*sp); 64060786Sps neg = FALSE; 64160786Sps if (*s == '-') 64260786Sps { 64360786Sps neg = TRUE; 64460786Sps s++; 64560786Sps } 64660786Sps if (*s < '0' || *s > '9') 647170256Sdelphij return (num_error(printopt, errp)); 64860786Sps 64960786Sps n = 0; 65060786Sps while (*s >= '0' && *s <= '9') 65160786Sps n = 10 * n + *s++ - '0'; 65260786Sps *sp = s; 65360786Sps if (errp != NULL) 65460786Sps *errp = FALSE; 65560786Sps if (neg) 65660786Sps n = -n; 65760786Sps return (n); 65860786Sps} 659170256Sdelphij 660170256Sdelphij/* 661170256Sdelphij * Translate a string into a fraction, represented by the part of a 662170256Sdelphij * number which would follow a decimal point. 663170256Sdelphij * The value of the fraction is returned as parts per NUM_FRAC_DENOM. 664170256Sdelphij * That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM. 665170256Sdelphij */ 666170256Sdelphij public long 667170256Sdelphijgetfraction(sp, printopt, errp) 668170256Sdelphij char **sp; 669170256Sdelphij char *printopt; 670170256Sdelphij int *errp; 671170256Sdelphij{ 672330571Sdelphij char *s; 673170256Sdelphij long frac = 0; 674170256Sdelphij int fraclen = 0; 675170256Sdelphij 676170256Sdelphij s = skipsp(*sp); 677170256Sdelphij if (*s < '0' || *s > '9') 678170256Sdelphij return (num_error(printopt, errp)); 679170256Sdelphij 680170256Sdelphij for ( ; *s >= '0' && *s <= '9'; s++) 681170256Sdelphij { 682170256Sdelphij frac = (frac * 10) + (*s - '0'); 683170256Sdelphij fraclen++; 684170256Sdelphij } 685170256Sdelphij if (fraclen > NUM_LOG_FRAC_DENOM) 686170256Sdelphij while (fraclen-- > NUM_LOG_FRAC_DENOM) 687170256Sdelphij frac /= 10; 688170256Sdelphij else 689170256Sdelphij while (fraclen++ < NUM_LOG_FRAC_DENOM) 690170256Sdelphij frac *= 10; 691170256Sdelphij *sp = s; 692170256Sdelphij if (errp != NULL) 693170256Sdelphij *errp = FALSE; 694170256Sdelphij return (frac); 695170256Sdelphij} 696170256Sdelphij 697170256Sdelphij 698170256Sdelphij/* 699170256Sdelphij * Get the value of the -e flag. 700170256Sdelphij */ 701170256Sdelphij public int 702170256Sdelphijget_quit_at_eof() 703170256Sdelphij{ 704170256Sdelphij if (!less_is_more) 705170256Sdelphij return quit_at_eof; 706170256Sdelphij /* When less_is_more is set, the -e flag semantics are different. */ 707294286Sdelphij return quit_at_eof ? OPT_ONPLUS : OPT_ON; 708170256Sdelphij} 709