1a5f0fb15SPaul Saab /* 2a5f0fb15SPaul Saab * Copyright (C) 1984-2000 Mark Nudelman 3a5f0fb15SPaul Saab * 4a5f0fb15SPaul Saab * You may distribute under the terms of either the GNU General Public 5a5f0fb15SPaul Saab * License or the Less License, as specified in the README file. 6a5f0fb15SPaul Saab * 7a5f0fb15SPaul Saab * For more information about less, or for information on how to 8a5f0fb15SPaul Saab * contact the author, see the README file. 9a5f0fb15SPaul Saab */ 10a5f0fb15SPaul Saab 11a5f0fb15SPaul Saab 12a5f0fb15SPaul Saab /* 13a5f0fb15SPaul Saab * Process command line options. 14a5f0fb15SPaul Saab * 15a5f0fb15SPaul Saab * Each option is a single letter which controls a program variable. 16a5f0fb15SPaul Saab * The options have defaults which may be changed via 17a5f0fb15SPaul Saab * the command line option, toggled via the "-" command, 18a5f0fb15SPaul Saab * or queried via the "_" command. 19a5f0fb15SPaul Saab */ 20a5f0fb15SPaul Saab 21a5f0fb15SPaul Saab #include "less.h" 22a5f0fb15SPaul Saab #include "option.h" 23a5f0fb15SPaul Saab 24a5f0fb15SPaul Saab static struct option *pendopt; 25a5f0fb15SPaul Saab public int plusoption = FALSE; 26a5f0fb15SPaul Saab 27a5f0fb15SPaul Saab static char *propt(); 28a5f0fb15SPaul Saab static char *optstring(); 29a5f0fb15SPaul Saab static int flip_triple(); 30a5f0fb15SPaul Saab 31a5f0fb15SPaul Saab extern int screen_trashed; 32a5f0fb15SPaul Saab extern char *every_first_cmd; 33a5f0fb15SPaul Saab 34a5f0fb15SPaul Saab /* 35a5f0fb15SPaul Saab * Scan an argument (either from the command line or from the 36a5f0fb15SPaul Saab * LESS environment variable) and process it. 37a5f0fb15SPaul Saab */ 38a5f0fb15SPaul Saab public void 39a5f0fb15SPaul Saab scan_option(s) 40a5f0fb15SPaul Saab char *s; 41a5f0fb15SPaul Saab { 42a5f0fb15SPaul Saab register struct option *o; 43a5f0fb15SPaul Saab register int optc; 44a5f0fb15SPaul Saab char *optname; 45a5f0fb15SPaul Saab char *printopt; 46a5f0fb15SPaul Saab char *str; 47a5f0fb15SPaul Saab int set_default; 48a5f0fb15SPaul Saab int lc; 49a5f0fb15SPaul Saab int err; 50a5f0fb15SPaul Saab PARG parg; 51a5f0fb15SPaul Saab 52a5f0fb15SPaul Saab if (s == NULL) 53a5f0fb15SPaul Saab return; 54a5f0fb15SPaul Saab 55a5f0fb15SPaul Saab /* 56a5f0fb15SPaul Saab * If we have a pending option which requires an argument, 57a5f0fb15SPaul Saab * handle it now. 58a5f0fb15SPaul Saab * This happens if the previous option was, for example, "-P" 59a5f0fb15SPaul Saab * without a following string. In that case, the current 60a5f0fb15SPaul Saab * option is simply the argument for the previous option. 61a5f0fb15SPaul Saab */ 62a5f0fb15SPaul Saab if (pendopt != NULL) 63a5f0fb15SPaul Saab { 64a5f0fb15SPaul Saab switch (pendopt->otype & OTYPE) 65a5f0fb15SPaul Saab { 66a5f0fb15SPaul Saab case STRING: 67a5f0fb15SPaul Saab (*pendopt->ofunc)(INIT, s); 68a5f0fb15SPaul Saab break; 69a5f0fb15SPaul Saab case NUMBER: 70a5f0fb15SPaul Saab printopt = propt(pendopt->oletter); 71a5f0fb15SPaul Saab *(pendopt->ovar) = getnum(&s, printopt, (int*)NULL); 72a5f0fb15SPaul Saab break; 73a5f0fb15SPaul Saab } 74a5f0fb15SPaul Saab pendopt = NULL; 75a5f0fb15SPaul Saab return; 76a5f0fb15SPaul Saab } 77a5f0fb15SPaul Saab 78a5f0fb15SPaul Saab set_default = FALSE; 79a5f0fb15SPaul Saab optname = NULL; 80a5f0fb15SPaul Saab 81a5f0fb15SPaul Saab while (*s != '\0') 82a5f0fb15SPaul Saab { 83a5f0fb15SPaul Saab /* 84a5f0fb15SPaul Saab * Check some special cases first. 85a5f0fb15SPaul Saab */ 86a5f0fb15SPaul Saab switch (optc = *s++) 87a5f0fb15SPaul Saab { 88a5f0fb15SPaul Saab case ' ': 89a5f0fb15SPaul Saab case '\t': 90a5f0fb15SPaul Saab case END_OPTION_STRING: 91a5f0fb15SPaul Saab continue; 92a5f0fb15SPaul Saab case '-': 93a5f0fb15SPaul Saab /* 94a5f0fb15SPaul Saab * "--" indicates an option name instead of a letter. 95a5f0fb15SPaul Saab */ 96a5f0fb15SPaul Saab if (*s == '-') 97a5f0fb15SPaul Saab { 98a5f0fb15SPaul Saab optname = ++s; 99a5f0fb15SPaul Saab break; 100a5f0fb15SPaul Saab } 101a5f0fb15SPaul Saab /* 102a5f0fb15SPaul Saab * "-+" means set these options back to their defaults. 103a5f0fb15SPaul Saab * (They may have been set otherwise by previous 104a5f0fb15SPaul Saab * options.) 105a5f0fb15SPaul Saab */ 106a5f0fb15SPaul Saab set_default = (*s == '+'); 107a5f0fb15SPaul Saab if (set_default) 108a5f0fb15SPaul Saab s++; 109a5f0fb15SPaul Saab continue; 110a5f0fb15SPaul Saab case '+': 111a5f0fb15SPaul Saab /* 112a5f0fb15SPaul Saab * An option prefixed by a "+" is ungotten, so 113a5f0fb15SPaul Saab * that it is interpreted as less commands 114a5f0fb15SPaul Saab * processed at the start of the first input file. 115a5f0fb15SPaul Saab * "++" means process the commands at the start of 116a5f0fb15SPaul Saab * EVERY input file. 117a5f0fb15SPaul Saab */ 118a5f0fb15SPaul Saab plusoption = TRUE; 119c9346414SPaul Saab str = s; 120c9346414SPaul Saab s = optstring(s, propt('+'), NULL); 121c9346414SPaul Saab if (*str == '+') 122c9346414SPaul Saab every_first_cmd = save(++str); 123a5f0fb15SPaul Saab else 124c9346414SPaul Saab ungetsc(str); 125a5f0fb15SPaul Saab continue; 126a5f0fb15SPaul Saab case '0': case '1': case '2': case '3': case '4': 127a5f0fb15SPaul Saab case '5': case '6': case '7': case '8': case '9': 128a5f0fb15SPaul Saab /* 129a5f0fb15SPaul Saab * Special "more" compatibility form "-<number>" 130a5f0fb15SPaul Saab * instead of -z<number> to set the scrolling 131a5f0fb15SPaul Saab * window size. 132a5f0fb15SPaul Saab */ 133a5f0fb15SPaul Saab s--; 134a5f0fb15SPaul Saab optc = 'z'; 135a5f0fb15SPaul Saab break; 136a5f0fb15SPaul Saab } 137a5f0fb15SPaul Saab 138a5f0fb15SPaul Saab /* 139a5f0fb15SPaul Saab * Not a special case. 140a5f0fb15SPaul Saab * Look up the option letter in the option table. 141a5f0fb15SPaul Saab */ 142a5f0fb15SPaul Saab err = 0; 143a5f0fb15SPaul Saab if (optname == NULL) 144a5f0fb15SPaul Saab { 145a5f0fb15SPaul Saab printopt = propt(optc); 146a5f0fb15SPaul Saab lc = SIMPLE_IS_LOWER(optc); 147a5f0fb15SPaul Saab o = findopt(optc); 148a5f0fb15SPaul Saab } else 149a5f0fb15SPaul Saab { 150a5f0fb15SPaul Saab printopt = optname; 151a5f0fb15SPaul Saab lc = SIMPLE_IS_LOWER(optname[0]); 152a5f0fb15SPaul Saab o = findopt_name(&optname, NULL, &err); 153a5f0fb15SPaul Saab s = optname; 154a5f0fb15SPaul Saab optname = NULL; 155a5f0fb15SPaul Saab if (*s == '\0' || *s == ' ') 156a5f0fb15SPaul Saab { 157a5f0fb15SPaul Saab /* 158a5f0fb15SPaul Saab * The option name matches exactly. 159a5f0fb15SPaul Saab */ 160a5f0fb15SPaul Saab ; 161a5f0fb15SPaul Saab } else if (*s == '=') 162a5f0fb15SPaul Saab { 163a5f0fb15SPaul Saab /* 164a5f0fb15SPaul Saab * The option name is followed by "=value". 165a5f0fb15SPaul Saab */ 166a5f0fb15SPaul Saab if (o != NULL && 167a5f0fb15SPaul Saab (o->otype & OTYPE) != STRING && 168a5f0fb15SPaul Saab (o->otype & OTYPE) != NUMBER) 169a5f0fb15SPaul Saab { 170a5f0fb15SPaul Saab parg.p_string = printopt; 171a5f0fb15SPaul Saab error("The %s option should not be followed by =", 172a5f0fb15SPaul Saab &parg); 173a5f0fb15SPaul Saab quit(QUIT_ERROR); 174a5f0fb15SPaul Saab } 175a5f0fb15SPaul Saab s++; 176a5f0fb15SPaul Saab } else 177a5f0fb15SPaul Saab { 178a5f0fb15SPaul Saab /* 179a5f0fb15SPaul Saab * The specified name is longer than the 180a5f0fb15SPaul Saab * real option name. 181a5f0fb15SPaul Saab */ 182a5f0fb15SPaul Saab o = NULL; 183a5f0fb15SPaul Saab } 184a5f0fb15SPaul Saab } 185a5f0fb15SPaul Saab if (o == NULL) 186a5f0fb15SPaul Saab { 187a5f0fb15SPaul Saab parg.p_string = printopt; 188a5f0fb15SPaul Saab if (err == OPT_AMBIG) 189a5f0fb15SPaul Saab error("%s is an ambiguous abbreviation (\"less --help\" for help)", 190a5f0fb15SPaul Saab &parg); 191a5f0fb15SPaul Saab else 192a5f0fb15SPaul Saab error("There is no %s option (\"less --help\" for help)", 193a5f0fb15SPaul Saab &parg); 194a5f0fb15SPaul Saab quit(QUIT_ERROR); 195a5f0fb15SPaul Saab } 196a5f0fb15SPaul Saab 197a5f0fb15SPaul Saab str = NULL; 198a5f0fb15SPaul Saab switch (o->otype & OTYPE) 199a5f0fb15SPaul Saab { 200a5f0fb15SPaul Saab case BOOL: 201a5f0fb15SPaul Saab if (set_default) 202a5f0fb15SPaul Saab *(o->ovar) = o->odefault; 203a5f0fb15SPaul Saab else 204a5f0fb15SPaul Saab *(o->ovar) = ! o->odefault; 205a5f0fb15SPaul Saab break; 206a5f0fb15SPaul Saab case TRIPLE: 207a5f0fb15SPaul Saab if (set_default) 208a5f0fb15SPaul Saab *(o->ovar) = o->odefault; 209a5f0fb15SPaul Saab else 210a5f0fb15SPaul Saab *(o->ovar) = flip_triple(o->odefault, lc); 211a5f0fb15SPaul Saab break; 212a5f0fb15SPaul Saab case STRING: 213a5f0fb15SPaul Saab if (*s == '\0') 214a5f0fb15SPaul Saab { 215a5f0fb15SPaul Saab /* 216a5f0fb15SPaul Saab * Set pendopt and return. 217a5f0fb15SPaul Saab * We will get the string next time 218a5f0fb15SPaul Saab * scan_option is called. 219a5f0fb15SPaul Saab */ 220a5f0fb15SPaul Saab pendopt = o; 221a5f0fb15SPaul Saab return; 222a5f0fb15SPaul Saab } 223a5f0fb15SPaul Saab /* 224a5f0fb15SPaul Saab * Don't do anything here. 225a5f0fb15SPaul Saab * All processing of STRING options is done by 226a5f0fb15SPaul Saab * the handling function. 227a5f0fb15SPaul Saab */ 228a5f0fb15SPaul Saab str = s; 229c9346414SPaul Saab s = optstring(s, printopt, o->odesc[1]); 230a5f0fb15SPaul Saab break; 231a5f0fb15SPaul Saab case NUMBER: 232a5f0fb15SPaul Saab if (*s == '\0') 233a5f0fb15SPaul Saab { 234a5f0fb15SPaul Saab pendopt = o; 235a5f0fb15SPaul Saab return; 236a5f0fb15SPaul Saab } 237a5f0fb15SPaul Saab *(o->ovar) = getnum(&s, printopt, (int*)NULL); 238a5f0fb15SPaul Saab break; 239a5f0fb15SPaul Saab } 240a5f0fb15SPaul Saab /* 241a5f0fb15SPaul Saab * If the option has a handling function, call it. 242a5f0fb15SPaul Saab */ 243a5f0fb15SPaul Saab if (o->ofunc != NULL) 244a5f0fb15SPaul Saab (*o->ofunc)(INIT, str); 245a5f0fb15SPaul Saab } 246a5f0fb15SPaul Saab } 247a5f0fb15SPaul Saab 248a5f0fb15SPaul Saab /* 249a5f0fb15SPaul Saab * Toggle command line flags from within the program. 250a5f0fb15SPaul Saab * Used by the "-" and "_" commands. 251a5f0fb15SPaul Saab * how_toggle may be: 252a5f0fb15SPaul Saab * OPT_NO_TOGGLE just report the current setting, without changing it. 253a5f0fb15SPaul Saab * OPT_TOGGLE invert the current setting 254a5f0fb15SPaul Saab * OPT_UNSET set to the default value 255a5f0fb15SPaul Saab * OPT_SET set to the inverse of the default value 256a5f0fb15SPaul Saab */ 257a5f0fb15SPaul Saab public void 258a5f0fb15SPaul Saab toggle_option(c, s, how_toggle) 259a5f0fb15SPaul Saab int c; 260a5f0fb15SPaul Saab char *s; 261a5f0fb15SPaul Saab int how_toggle; 262a5f0fb15SPaul Saab { 263a5f0fb15SPaul Saab register struct option *o; 264a5f0fb15SPaul Saab register int num; 265a5f0fb15SPaul Saab int no_prompt; 266a5f0fb15SPaul Saab int err; 267a5f0fb15SPaul Saab PARG parg; 268a5f0fb15SPaul Saab 269a5f0fb15SPaul Saab no_prompt = (how_toggle & OPT_NO_PROMPT); 270a5f0fb15SPaul Saab how_toggle &= ~OPT_NO_PROMPT; 271a5f0fb15SPaul Saab 272a5f0fb15SPaul Saab /* 273a5f0fb15SPaul Saab * Look up the option letter in the option table. 274a5f0fb15SPaul Saab */ 275a5f0fb15SPaul Saab o = findopt(c); 276a5f0fb15SPaul Saab if (o == NULL) 277a5f0fb15SPaul Saab { 278a5f0fb15SPaul Saab parg.p_string = propt(c); 279a5f0fb15SPaul Saab error("There is no %s option", &parg); 280a5f0fb15SPaul Saab return; 281a5f0fb15SPaul Saab } 282a5f0fb15SPaul Saab 283a5f0fb15SPaul Saab if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE)) 284a5f0fb15SPaul Saab { 285a5f0fb15SPaul Saab parg.p_string = propt(c); 286a5f0fb15SPaul Saab error("Cannot change the %s option", &parg); 287a5f0fb15SPaul Saab return; 288a5f0fb15SPaul Saab } 289a5f0fb15SPaul Saab 290a5f0fb15SPaul Saab if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY)) 291a5f0fb15SPaul Saab { 292a5f0fb15SPaul Saab parg.p_string = propt(c); 293a5f0fb15SPaul Saab error("Cannot query the %s option", &parg); 294a5f0fb15SPaul Saab return; 295a5f0fb15SPaul Saab } 296a5f0fb15SPaul Saab 297a5f0fb15SPaul Saab /* 298a5f0fb15SPaul Saab * Check for something which appears to be a do_toggle 299a5f0fb15SPaul Saab * (because the "-" command was used), but really is not. 300a5f0fb15SPaul Saab * This could be a string option with no string, or 301a5f0fb15SPaul Saab * a number option with no number. 302a5f0fb15SPaul Saab */ 303a5f0fb15SPaul Saab switch (o->otype & OTYPE) 304a5f0fb15SPaul Saab { 305a5f0fb15SPaul Saab case STRING: 306a5f0fb15SPaul Saab case NUMBER: 307a5f0fb15SPaul Saab if (how_toggle == OPT_TOGGLE && *s == '\0') 308a5f0fb15SPaul Saab how_toggle = OPT_NO_TOGGLE; 309a5f0fb15SPaul Saab break; 310a5f0fb15SPaul Saab } 311a5f0fb15SPaul Saab 312a5f0fb15SPaul Saab #if HILITE_SEARCH 313a5f0fb15SPaul Saab if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) 314a5f0fb15SPaul Saab repaint_hilite(0); 315a5f0fb15SPaul Saab #endif 316a5f0fb15SPaul Saab 317a5f0fb15SPaul Saab /* 318a5f0fb15SPaul Saab * Now actually toggle (change) the variable. 319a5f0fb15SPaul Saab */ 320a5f0fb15SPaul Saab if (how_toggle != OPT_NO_TOGGLE) 321a5f0fb15SPaul Saab { 322a5f0fb15SPaul Saab switch (o->otype & OTYPE) 323a5f0fb15SPaul Saab { 324a5f0fb15SPaul Saab case BOOL: 325a5f0fb15SPaul Saab /* 326a5f0fb15SPaul Saab * Boolean. 327a5f0fb15SPaul Saab */ 328a5f0fb15SPaul Saab switch (how_toggle) 329a5f0fb15SPaul Saab { 330a5f0fb15SPaul Saab case OPT_TOGGLE: 331a5f0fb15SPaul Saab *(o->ovar) = ! *(o->ovar); 332a5f0fb15SPaul Saab break; 333a5f0fb15SPaul Saab case OPT_UNSET: 334a5f0fb15SPaul Saab *(o->ovar) = o->odefault; 335a5f0fb15SPaul Saab break; 336a5f0fb15SPaul Saab case OPT_SET: 337a5f0fb15SPaul Saab *(o->ovar) = ! o->odefault; 338a5f0fb15SPaul Saab break; 339a5f0fb15SPaul Saab } 340a5f0fb15SPaul Saab break; 341a5f0fb15SPaul Saab case TRIPLE: 342a5f0fb15SPaul Saab /* 343a5f0fb15SPaul Saab * Triple: 344a5f0fb15SPaul Saab * If user gave the lower case letter, then switch 345a5f0fb15SPaul Saab * to 1 unless already 1, in which case make it 0. 346a5f0fb15SPaul Saab * If user gave the upper case letter, then switch 347a5f0fb15SPaul Saab * to 2 unless already 2, in which case make it 0. 348a5f0fb15SPaul Saab */ 349a5f0fb15SPaul Saab switch (how_toggle) 350a5f0fb15SPaul Saab { 351a5f0fb15SPaul Saab case OPT_TOGGLE: 352a5f0fb15SPaul Saab *(o->ovar) = flip_triple(*(o->ovar), 353a5f0fb15SPaul Saab islower(c)); 354a5f0fb15SPaul Saab break; 355a5f0fb15SPaul Saab case OPT_UNSET: 356a5f0fb15SPaul Saab *(o->ovar) = o->odefault; 357a5f0fb15SPaul Saab break; 358a5f0fb15SPaul Saab case OPT_SET: 359a5f0fb15SPaul Saab *(o->ovar) = flip_triple(o->odefault, 360a5f0fb15SPaul Saab islower(c)); 361a5f0fb15SPaul Saab break; 362a5f0fb15SPaul Saab } 363a5f0fb15SPaul Saab break; 364a5f0fb15SPaul Saab case STRING: 365a5f0fb15SPaul Saab /* 366a5f0fb15SPaul Saab * String: don't do anything here. 367a5f0fb15SPaul Saab * The handling function will do everything. 368a5f0fb15SPaul Saab */ 369a5f0fb15SPaul Saab switch (how_toggle) 370a5f0fb15SPaul Saab { 371a5f0fb15SPaul Saab case OPT_SET: 372a5f0fb15SPaul Saab case OPT_UNSET: 373a5f0fb15SPaul Saab error("Cannot use \"-+\" or \"--\" for a string option", 374a5f0fb15SPaul Saab NULL_PARG); 375a5f0fb15SPaul Saab return; 376a5f0fb15SPaul Saab } 377a5f0fb15SPaul Saab break; 378a5f0fb15SPaul Saab case NUMBER: 379a5f0fb15SPaul Saab /* 380a5f0fb15SPaul Saab * Number: set the variable to the given number. 381a5f0fb15SPaul Saab */ 382a5f0fb15SPaul Saab switch (how_toggle) 383a5f0fb15SPaul Saab { 384a5f0fb15SPaul Saab case OPT_TOGGLE: 385a5f0fb15SPaul Saab num = getnum(&s, '\0', &err); 386a5f0fb15SPaul Saab if (!err) 387a5f0fb15SPaul Saab *(o->ovar) = num; 388a5f0fb15SPaul Saab break; 389a5f0fb15SPaul Saab case OPT_UNSET: 390a5f0fb15SPaul Saab *(o->ovar) = o->odefault; 391a5f0fb15SPaul Saab break; 392a5f0fb15SPaul Saab case OPT_SET: 393a5f0fb15SPaul Saab error("Can't use \"-!\" for a numeric option", 394a5f0fb15SPaul Saab NULL_PARG); 395a5f0fb15SPaul Saab return; 396a5f0fb15SPaul Saab } 397a5f0fb15SPaul Saab break; 398a5f0fb15SPaul Saab } 399a5f0fb15SPaul Saab } 400a5f0fb15SPaul Saab 401a5f0fb15SPaul Saab /* 402a5f0fb15SPaul Saab * Call the handling function for any special action 403a5f0fb15SPaul Saab * specific to this option. 404a5f0fb15SPaul Saab */ 405a5f0fb15SPaul Saab if (o->ofunc != NULL) 406a5f0fb15SPaul Saab (*o->ofunc)((how_toggle==OPT_NO_TOGGLE) ? QUERY : TOGGLE, s); 407a5f0fb15SPaul Saab 408a5f0fb15SPaul Saab #if HILITE_SEARCH 409a5f0fb15SPaul Saab if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT)) 410a5f0fb15SPaul Saab chg_hilite(); 411a5f0fb15SPaul Saab #endif 412a5f0fb15SPaul Saab 413a5f0fb15SPaul Saab if (!no_prompt) 414a5f0fb15SPaul Saab { 415a5f0fb15SPaul Saab /* 416a5f0fb15SPaul Saab * Print a message describing the new setting. 417a5f0fb15SPaul Saab */ 418a5f0fb15SPaul Saab switch (o->otype & OTYPE) 419a5f0fb15SPaul Saab { 420a5f0fb15SPaul Saab case BOOL: 421a5f0fb15SPaul Saab case TRIPLE: 422a5f0fb15SPaul Saab /* 423a5f0fb15SPaul Saab * Print the odesc message. 424a5f0fb15SPaul Saab */ 425a5f0fb15SPaul Saab error(o->odesc[*(o->ovar)], NULL_PARG); 426a5f0fb15SPaul Saab break; 427a5f0fb15SPaul Saab case NUMBER: 428a5f0fb15SPaul Saab /* 429a5f0fb15SPaul Saab * The message is in odesc[1] and has a %d for 430a5f0fb15SPaul Saab * the value of the variable. 431a5f0fb15SPaul Saab */ 432a5f0fb15SPaul Saab parg.p_int = *(o->ovar); 433a5f0fb15SPaul Saab error(o->odesc[1], &parg); 434a5f0fb15SPaul Saab break; 435a5f0fb15SPaul Saab case STRING: 436a5f0fb15SPaul Saab /* 437a5f0fb15SPaul Saab * Message was already printed by the handling function. 438a5f0fb15SPaul Saab */ 439a5f0fb15SPaul Saab break; 440a5f0fb15SPaul Saab } 441a5f0fb15SPaul Saab } 442a5f0fb15SPaul Saab 443a5f0fb15SPaul Saab if (how_toggle != OPT_NO_TOGGLE && (o->otype & REPAINT)) 444a5f0fb15SPaul Saab screen_trashed = TRUE; 445a5f0fb15SPaul Saab } 446a5f0fb15SPaul Saab 447a5f0fb15SPaul Saab /* 448a5f0fb15SPaul Saab * "Toggle" a triple-valued option. 449a5f0fb15SPaul Saab */ 450a5f0fb15SPaul Saab static int 451a5f0fb15SPaul Saab flip_triple(val, lc) 452a5f0fb15SPaul Saab int val; 453a5f0fb15SPaul Saab int lc; 454a5f0fb15SPaul Saab { 455a5f0fb15SPaul Saab if (lc) 456a5f0fb15SPaul Saab return ((val == OPT_ON) ? OPT_OFF : OPT_ON); 457a5f0fb15SPaul Saab else 458a5f0fb15SPaul Saab return ((val == OPT_ONPLUS) ? OPT_OFF : OPT_ONPLUS); 459a5f0fb15SPaul Saab } 460a5f0fb15SPaul Saab 461a5f0fb15SPaul Saab /* 462a5f0fb15SPaul Saab * Return a string suitable for printing as the "name" of an option. 463a5f0fb15SPaul Saab * For example, if the option letter is 'x', just return "-x". 464a5f0fb15SPaul Saab */ 465a5f0fb15SPaul Saab static char * 466a5f0fb15SPaul Saab propt(c) 467a5f0fb15SPaul Saab int c; 468a5f0fb15SPaul Saab { 469a5f0fb15SPaul Saab static char buf[8]; 470a5f0fb15SPaul Saab 471a5f0fb15SPaul Saab sprintf(buf, "-%s", prchar(c)); 472a5f0fb15SPaul Saab return (buf); 473a5f0fb15SPaul Saab } 474a5f0fb15SPaul Saab 475a5f0fb15SPaul Saab /* 476a5f0fb15SPaul Saab * Determine if an option is a single character option (BOOL or TRIPLE), 477a5f0fb15SPaul Saab * or if it a multi-character option (NUMBER). 478a5f0fb15SPaul Saab */ 479a5f0fb15SPaul Saab public int 480a5f0fb15SPaul Saab single_char_option(c) 481a5f0fb15SPaul Saab int c; 482a5f0fb15SPaul Saab { 483a5f0fb15SPaul Saab register struct option *o; 484a5f0fb15SPaul Saab 485a5f0fb15SPaul Saab o = findopt(c); 486a5f0fb15SPaul Saab if (o == NULL) 487a5f0fb15SPaul Saab return (TRUE); 488a5f0fb15SPaul Saab return ((o->otype & (BOOL|TRIPLE|NOVAR|NO_TOGGLE)) != 0); 489a5f0fb15SPaul Saab } 490a5f0fb15SPaul Saab 491a5f0fb15SPaul Saab /* 492a5f0fb15SPaul Saab * Return the prompt to be used for a given option letter. 493a5f0fb15SPaul Saab * Only string and number valued options have prompts. 494a5f0fb15SPaul Saab */ 495a5f0fb15SPaul Saab public char * 496a5f0fb15SPaul Saab opt_prompt(c) 497a5f0fb15SPaul Saab int c; 498a5f0fb15SPaul Saab { 499a5f0fb15SPaul Saab register struct option *o; 500a5f0fb15SPaul Saab 501a5f0fb15SPaul Saab o = findopt(c); 502a5f0fb15SPaul Saab if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) 503a5f0fb15SPaul Saab return (NULL); 504a5f0fb15SPaul Saab return (o->odesc[0]); 505a5f0fb15SPaul Saab } 506a5f0fb15SPaul Saab 507a5f0fb15SPaul Saab /* 508a5f0fb15SPaul Saab * Return whether or not there is a string option pending; 509a5f0fb15SPaul Saab * that is, if the previous option was a string-valued option letter 510a5f0fb15SPaul Saab * (like -P) without a following string. 511a5f0fb15SPaul Saab * In that case, the current option is taken to be the string for 512a5f0fb15SPaul Saab * the previous option. 513a5f0fb15SPaul Saab */ 514a5f0fb15SPaul Saab public int 515a5f0fb15SPaul Saab isoptpending() 516a5f0fb15SPaul Saab { 517a5f0fb15SPaul Saab return (pendopt != NULL); 518a5f0fb15SPaul Saab } 519a5f0fb15SPaul Saab 520a5f0fb15SPaul Saab /* 521a5f0fb15SPaul Saab * Print error message about missing string. 522a5f0fb15SPaul Saab */ 523a5f0fb15SPaul Saab static void 524a5f0fb15SPaul Saab nostring(printopt) 525a5f0fb15SPaul Saab char *printopt; 526a5f0fb15SPaul Saab { 527a5f0fb15SPaul Saab PARG parg; 528a5f0fb15SPaul Saab parg.p_string = printopt; 529a5f0fb15SPaul Saab error("Value is required after %s", &parg); 530a5f0fb15SPaul Saab } 531a5f0fb15SPaul Saab 532a5f0fb15SPaul Saab /* 533a5f0fb15SPaul Saab * Print error message if a STRING type option is not followed by a string. 534a5f0fb15SPaul Saab */ 535a5f0fb15SPaul Saab public void 536a5f0fb15SPaul Saab nopendopt() 537a5f0fb15SPaul Saab { 538a5f0fb15SPaul Saab nostring(propt(pendopt->oletter)); 539a5f0fb15SPaul Saab } 540a5f0fb15SPaul Saab 541a5f0fb15SPaul Saab /* 542a5f0fb15SPaul Saab * Scan to end of string or to an END_OPTION_STRING character. 543a5f0fb15SPaul Saab * In the latter case, replace the char with a null char. 544a5f0fb15SPaul Saab * Return a pointer to the remainder of the string, if any. 545a5f0fb15SPaul Saab */ 546a5f0fb15SPaul Saab static char * 547c9346414SPaul Saab optstring(s, printopt, validchars) 548a5f0fb15SPaul Saab char *s; 549a5f0fb15SPaul Saab char *printopt; 550c9346414SPaul Saab char *validchars; 551a5f0fb15SPaul Saab { 552a5f0fb15SPaul Saab register char *p; 553c9346414SPaul Saab PARG parg; 554a5f0fb15SPaul Saab 555a5f0fb15SPaul Saab if (*s == '\0') 556a5f0fb15SPaul Saab { 557a5f0fb15SPaul Saab nostring(printopt); 558a5f0fb15SPaul Saab quit(QUIT_ERROR); 559a5f0fb15SPaul Saab } 560a5f0fb15SPaul Saab for (p = s; *p != '\0'; p++) 561c9346414SPaul Saab if (*p == END_OPTION_STRING || 562c9346414SPaul Saab (validchars != NULL && strchr(validchars, *p) == NULL)) 563a5f0fb15SPaul Saab { 564c9346414SPaul Saab switch (*p) 565c9346414SPaul Saab { 566c9346414SPaul Saab case END_OPTION_STRING: 567c9346414SPaul Saab case ' ': case '\t': case '-': 568c9346414SPaul Saab break; 569c9346414SPaul Saab default: 570c9346414SPaul Saab parg.p_string = p; 571c9346414SPaul Saab error("Option string needs delimiter before %s", &parg); 572c9346414SPaul Saab break; 573c9346414SPaul Saab } 574a5f0fb15SPaul Saab *p = '\0'; 575a5f0fb15SPaul Saab return (p+1); 576a5f0fb15SPaul Saab } 577a5f0fb15SPaul Saab return (p); 578a5f0fb15SPaul Saab } 579a5f0fb15SPaul Saab 580a5f0fb15SPaul Saab /* 581a5f0fb15SPaul Saab * Translate a string into a number. 582a5f0fb15SPaul Saab * Like atoi(), but takes a pointer to a char *, and updates 583a5f0fb15SPaul Saab * the char * to point after the translated number. 584a5f0fb15SPaul Saab */ 585a5f0fb15SPaul Saab public int 586a5f0fb15SPaul Saab getnum(sp, printopt, errp) 587a5f0fb15SPaul Saab char **sp; 588a5f0fb15SPaul Saab char *printopt; 589a5f0fb15SPaul Saab int *errp; 590a5f0fb15SPaul Saab { 591a5f0fb15SPaul Saab register char *s; 592a5f0fb15SPaul Saab register int n; 593a5f0fb15SPaul Saab register int neg; 594a5f0fb15SPaul Saab PARG parg; 595a5f0fb15SPaul Saab 596a5f0fb15SPaul Saab s = skipsp(*sp); 597a5f0fb15SPaul Saab neg = FALSE; 598a5f0fb15SPaul Saab if (*s == '-') 599a5f0fb15SPaul Saab { 600a5f0fb15SPaul Saab neg = TRUE; 601a5f0fb15SPaul Saab s++; 602a5f0fb15SPaul Saab } 603a5f0fb15SPaul Saab if (*s < '0' || *s > '9') 604a5f0fb15SPaul Saab { 605a5f0fb15SPaul Saab if (errp != NULL) 606a5f0fb15SPaul Saab { 607a5f0fb15SPaul Saab *errp = TRUE; 608a5f0fb15SPaul Saab return (-1); 609a5f0fb15SPaul Saab } 610a5f0fb15SPaul Saab parg.p_string = printopt; 611a5f0fb15SPaul Saab error("Number is required after %s", &parg); 612a5f0fb15SPaul Saab quit(QUIT_ERROR); 613a5f0fb15SPaul Saab } 614a5f0fb15SPaul Saab 615a5f0fb15SPaul Saab n = 0; 616a5f0fb15SPaul Saab while (*s >= '0' && *s <= '9') 617a5f0fb15SPaul Saab n = 10 * n + *s++ - '0'; 618a5f0fb15SPaul Saab *sp = s; 619a5f0fb15SPaul Saab if (errp != NULL) 620a5f0fb15SPaul Saab *errp = FALSE; 621a5f0fb15SPaul Saab if (neg) 622a5f0fb15SPaul Saab n = -n; 623a5f0fb15SPaul Saab return (n); 624a5f0fb15SPaul Saab } 625