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 * Handling functions for command line options. 1360786Sps * 1460786Sps * Most options are handled by the generic code in option.c. 1560786Sps * But all string options, and a few non-string options, require 1660786Sps * special handling specific to the particular option. 1760786Sps * This special processing is done by the "handling functions" in this file. 1860786Sps * 1960786Sps * Each handling function is passed a "type" and, if it is a string 2060786Sps * option, the string which should be "assigned" to the option. 2160786Sps * The type may be one of: 2260786Sps * INIT The option is being initialized from the command line. 2360786Sps * TOGGLE The option is being changed from within the program. 2460786Sps * QUERY The setting of the option is merely being queried. 2560786Sps */ 2660786Sps 2760786Sps#include "less.h" 2860786Sps#include "option.h" 2960786Sps 3060786Spsextern int nbufs; 31128345Stjrextern int bufspace; 3260786Spsextern int pr_type; 3360786Spsextern int plusoption; 3460786Spsextern int swindow; 35195941Sdelphijextern int sc_width; 3660786Spsextern int sc_height; 3760786Spsextern int secure; 3860786Spsextern int dohelp; 3960786Spsextern int any_display; 4060786Spsextern char openquote; 4160786Spsextern char closequote; 4260786Spsextern char *prproto[]; 4360786Spsextern char *eqproto; 4460786Spsextern char *hproto; 4589019Spsextern char *wproto; 46294286Sdelphijextern char *every_first_cmd; 4760786Spsextern IFILE curr_ifile; 4860786Spsextern char version[]; 49170964Sdelphijextern int jump_sline; 50330571Sdelphijextern long jump_sline_fraction; 51195941Sdelphijextern int shift_count; 52330571Sdelphijextern long shift_count_fraction; 53330571Sdelphijextern LWCHAR rscroll_char; 54330571Sdelphijextern int rscroll_attr; 55170964Sdelphijextern int less_is_more; 5660786Sps#if LOGFILE 5760786Spsextern char *namelogfile; 5860786Spsextern int force_logfile; 5960786Spsextern int logfile; 6060786Sps#endif 6160786Sps#if TAGS 6260786Spspublic char *tagoption = NULL; 6360786Spsextern char *tags; 64294286Sdelphijextern char ztags[]; 6560786Sps#endif 6660786Sps#if MSDOS_COMPILER 6760786Spsextern int nm_fg_color, nm_bg_color; 6860786Spsextern int bo_fg_color, bo_bg_color; 6960786Spsextern int ul_fg_color, ul_bg_color; 7060786Spsextern int so_fg_color, so_bg_color; 7160786Spsextern int bl_fg_color, bl_bg_color; 72330571Sdelphijextern int sgr_mode; 73330571Sdelphij#if MSDOS_COMPILER==WIN32C 74330571Sdelphij#ifndef COMMON_LVB_UNDERSCORE 75330571Sdelphij#define COMMON_LVB_UNDERSCORE 0x8000 7660786Sps#endif 77330571Sdelphij#endif 78330571Sdelphij#endif 7960786Sps 8060786Sps 8160786Sps#if LOGFILE 8260786Sps/* 8360786Sps * Handler for -o option. 8460786Sps */ 8560786Sps public void 8660786Spsopt_o(type, s) 8760786Sps int type; 8860786Sps char *s; 8960786Sps{ 9060786Sps PARG parg; 91330571Sdelphij char *filename; 9260786Sps 9360786Sps if (secure) 9460786Sps { 9560786Sps error("log file support is not available", NULL_PARG); 9660786Sps return; 9760786Sps } 9860786Sps switch (type) 9960786Sps { 10060786Sps case INIT: 101294286Sdelphij namelogfile = save(s); 10260786Sps break; 10360786Sps case TOGGLE: 10460786Sps if (ch_getflags() & CH_CANSEEK) 10560786Sps { 10660786Sps error("Input is not a pipe", NULL_PARG); 10760786Sps return; 10860786Sps } 10960786Sps if (logfile >= 0) 11060786Sps { 11160786Sps error("Log file is already in use", NULL_PARG); 11260786Sps return; 11360786Sps } 11460786Sps s = skipsp(s); 115294286Sdelphij if (namelogfile != NULL) 116294286Sdelphij free(namelogfile); 117330571Sdelphij filename = lglob(s); 118330571Sdelphij namelogfile = shell_unquote(filename); 119330571Sdelphij free(filename); 12060786Sps use_logfile(namelogfile); 12160786Sps sync_logfile(); 12260786Sps break; 12360786Sps case QUERY: 12460786Sps if (logfile < 0) 12560786Sps error("No log file", NULL_PARG); 12660786Sps else 12760786Sps { 128128345Stjr parg.p_string = namelogfile; 12960786Sps error("Log file \"%s\"", &parg); 13060786Sps } 13160786Sps break; 13260786Sps } 13360786Sps} 13460786Sps 13560786Sps/* 13660786Sps * Handler for -O option. 13760786Sps */ 13860786Sps public void 13960786Spsopt__O(type, s) 14060786Sps int type; 14160786Sps char *s; 14260786Sps{ 14360786Sps force_logfile = TRUE; 14460786Sps opt_o(type, s); 14560786Sps} 14660786Sps#endif 14760786Sps 14860786Sps/* 149170256Sdelphij * Handlers for -j option. 150170256Sdelphij */ 151170256Sdelphij public void 152170256Sdelphijopt_j(type, s) 153170256Sdelphij int type; 154170256Sdelphij char *s; 155170256Sdelphij{ 156170256Sdelphij PARG parg; 157170256Sdelphij char buf[16]; 158170256Sdelphij int len; 159170256Sdelphij int err; 160170256Sdelphij 161170256Sdelphij switch (type) 162170256Sdelphij { 163170256Sdelphij case INIT: 164170256Sdelphij case TOGGLE: 165170256Sdelphij if (*s == '.') 166170256Sdelphij { 167170256Sdelphij s++; 168170256Sdelphij jump_sline_fraction = getfraction(&s, "j", &err); 169170256Sdelphij if (err) 170170256Sdelphij error("Invalid line fraction", NULL_PARG); 171170256Sdelphij else 172170256Sdelphij calc_jump_sline(); 173170256Sdelphij } else 174170256Sdelphij { 175170256Sdelphij int sline = getnum(&s, "j", &err); 176170256Sdelphij if (err) 177170256Sdelphij error("Invalid line number", NULL_PARG); 178170256Sdelphij else 179170256Sdelphij { 180170256Sdelphij jump_sline = sline; 181170256Sdelphij jump_sline_fraction = -1; 182170256Sdelphij } 183170256Sdelphij } 184170256Sdelphij break; 185170256Sdelphij case QUERY: 186170256Sdelphij if (jump_sline_fraction < 0) 187170256Sdelphij { 188170256Sdelphij parg.p_int = jump_sline; 189170256Sdelphij error("Position target at screen line %d", &parg); 190170256Sdelphij } else 191170256Sdelphij { 192170256Sdelphij 193330571Sdelphij sprintf(buf, ".%06ld", jump_sline_fraction); 194294286Sdelphij len = (int) strlen(buf); 195170256Sdelphij while (len > 2 && buf[len-1] == '0') 196170256Sdelphij len--; 197170256Sdelphij buf[len] = '\0'; 198170256Sdelphij parg.p_string = buf; 199170256Sdelphij error("Position target at screen position %s", &parg); 200170256Sdelphij } 201170256Sdelphij break; 202170256Sdelphij } 203170256Sdelphij} 204170256Sdelphij 205170256Sdelphij public void 206170256Sdelphijcalc_jump_sline() 207170256Sdelphij{ 208170256Sdelphij if (jump_sline_fraction < 0) 209170256Sdelphij return; 210170256Sdelphij jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM; 211170256Sdelphij} 212170256Sdelphij 213195941Sdelphij/* 214195941Sdelphij * Handlers for -# option. 215195941Sdelphij */ 216195941Sdelphij public void 217195941Sdelphijopt_shift(type, s) 218195941Sdelphij int type; 219195941Sdelphij char *s; 220195941Sdelphij{ 221195941Sdelphij PARG parg; 222195941Sdelphij char buf[16]; 223195941Sdelphij int len; 224195941Sdelphij int err; 225195941Sdelphij 226195941Sdelphij switch (type) 227195941Sdelphij { 228195941Sdelphij case INIT: 229195941Sdelphij case TOGGLE: 230195941Sdelphij if (*s == '.') 231195941Sdelphij { 232195941Sdelphij s++; 233195941Sdelphij shift_count_fraction = getfraction(&s, "#", &err); 234195941Sdelphij if (err) 235195941Sdelphij error("Invalid column fraction", NULL_PARG); 236195941Sdelphij else 237195941Sdelphij calc_shift_count(); 238195941Sdelphij } else 239195941Sdelphij { 240195941Sdelphij int hs = getnum(&s, "#", &err); 241195941Sdelphij if (err) 242195941Sdelphij error("Invalid column number", NULL_PARG); 243195941Sdelphij else 244195941Sdelphij { 245195941Sdelphij shift_count = hs; 246195941Sdelphij shift_count_fraction = -1; 247195941Sdelphij } 248195941Sdelphij } 249195941Sdelphij break; 250195941Sdelphij case QUERY: 251195941Sdelphij if (shift_count_fraction < 0) 252195941Sdelphij { 253195941Sdelphij parg.p_int = shift_count; 254195941Sdelphij error("Horizontal shift %d columns", &parg); 255195941Sdelphij } else 256195941Sdelphij { 257195941Sdelphij 258330571Sdelphij sprintf(buf, ".%06ld", shift_count_fraction); 259294286Sdelphij len = (int) strlen(buf); 260195941Sdelphij while (len > 2 && buf[len-1] == '0') 261195941Sdelphij len--; 262195941Sdelphij buf[len] = '\0'; 263195941Sdelphij parg.p_string = buf; 264195941Sdelphij error("Horizontal shift %s of screen width", &parg); 265195941Sdelphij } 266195941Sdelphij break; 267195941Sdelphij } 268195941Sdelphij} 269195941Sdelphij public void 270195941Sdelphijcalc_shift_count() 271195941Sdelphij{ 272195941Sdelphij if (shift_count_fraction < 0) 273195941Sdelphij return; 274195941Sdelphij shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM; 275195941Sdelphij} 276195941Sdelphij 27760786Sps#if USERFILE 27860786Sps public void 27960786Spsopt_k(type, s) 28060786Sps int type; 28160786Sps char *s; 28260786Sps{ 28360786Sps PARG parg; 28460786Sps 28560786Sps switch (type) 28660786Sps { 28760786Sps case INIT: 28860786Sps if (lesskey(s, 0)) 28960786Sps { 290128345Stjr parg.p_string = s; 29160786Sps error("Cannot use lesskey file \"%s\"", &parg); 29260786Sps } 29360786Sps break; 29460786Sps } 29560786Sps} 29660786Sps#endif 29760786Sps 29860786Sps#if TAGS 29960786Sps/* 30060786Sps * Handler for -t option. 30160786Sps */ 30260786Sps public void 30360786Spsopt_t(type, s) 30460786Sps int type; 30560786Sps char *s; 30660786Sps{ 30760786Sps IFILE save_ifile; 30860786Sps POSITION pos; 30960786Sps 31060786Sps switch (type) 31160786Sps { 31260786Sps case INIT: 313294286Sdelphij tagoption = save(s); 31460786Sps /* Do the rest in main() */ 31560786Sps break; 31660786Sps case TOGGLE: 31760786Sps if (secure) 31860786Sps { 31960786Sps error("tags support is not available", NULL_PARG); 32060786Sps break; 32160786Sps } 32260786Sps findtag(skipsp(s)); 32360786Sps save_ifile = save_curr_ifile(); 324161475Sdelphij /* 325161475Sdelphij * Try to open the file containing the tag 326161475Sdelphij * and search for the tag in that file. 327161475Sdelphij */ 328161475Sdelphij if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION) 32960786Sps { 330161475Sdelphij /* Failed: reopen the old file. */ 33160786Sps reedit_ifile(save_ifile); 33260786Sps break; 33360786Sps } 33460786Sps unsave_ifile(save_ifile); 33560786Sps jump_loc(pos, jump_sline); 33660786Sps break; 33760786Sps } 33860786Sps} 33960786Sps 34060786Sps/* 34160786Sps * Handler for -T option. 34260786Sps */ 34360786Sps public void 34460786Spsopt__T(type, s) 34560786Sps int type; 34660786Sps char *s; 34760786Sps{ 34860786Sps PARG parg; 349330571Sdelphij char *filename; 35060786Sps 35160786Sps switch (type) 35260786Sps { 35360786Sps case INIT: 354294286Sdelphij tags = save(s); 35560786Sps break; 35660786Sps case TOGGLE: 35760786Sps s = skipsp(s); 358294286Sdelphij if (tags != NULL && tags != ztags) 359294286Sdelphij free(tags); 360330571Sdelphij filename = lglob(s); 361330571Sdelphij tags = shell_unquote(filename); 362330571Sdelphij free(filename); 36360786Sps break; 36460786Sps case QUERY: 365128345Stjr parg.p_string = tags; 36660786Sps error("Tags file \"%s\"", &parg); 36760786Sps break; 36860786Sps } 36960786Sps} 37060786Sps#endif 37160786Sps 37260786Sps/* 37360786Sps * Handler for -p option. 37460786Sps */ 37560786Sps public void 37660786Spsopt_p(type, s) 37760786Sps int type; 378330571Sdelphij char *s; 37960786Sps{ 38060786Sps switch (type) 38160786Sps { 38260786Sps case INIT: 38360786Sps /* 384294286Sdelphij * Unget a command for the specified string. 38560786Sps */ 386294286Sdelphij if (less_is_more) 387294286Sdelphij { 388294286Sdelphij /* 389294286Sdelphij * In "more" mode, the -p argument is a command, 390294286Sdelphij * not a search string, so we don't need a slash. 391294286Sdelphij */ 392294286Sdelphij every_first_cmd = save(s); 393294286Sdelphij } else 394294286Sdelphij { 395294286Sdelphij plusoption = TRUE; 396294286Sdelphij ungetcc(CHAR_END_COMMAND); 397294286Sdelphij ungetsc(s); 398294286Sdelphij /* 399294286Sdelphij * {{ This won't work if the "/" command is 400294286Sdelphij * changed or invalidated by a .lesskey file. }} 401294286Sdelphij */ 402161475Sdelphij ungetsc("/"); 403294286Sdelphij } 40460786Sps break; 40560786Sps } 40660786Sps} 40760786Sps 40860786Sps/* 40960786Sps * Handler for -P option. 41060786Sps */ 41160786Sps public void 41260786Spsopt__P(type, s) 41360786Sps int type; 414330571Sdelphij char *s; 41560786Sps{ 416330571Sdelphij char **proto; 41760786Sps PARG parg; 41860786Sps 41960786Sps switch (type) 42060786Sps { 42160786Sps case INIT: 42260786Sps case TOGGLE: 42360786Sps /* 42460786Sps * Figure out which prototype string should be changed. 42560786Sps */ 42660786Sps switch (*s) 42760786Sps { 42860786Sps case 's': proto = &prproto[PR_SHORT]; s++; break; 42960786Sps case 'm': proto = &prproto[PR_MEDIUM]; s++; break; 43060786Sps case 'M': proto = &prproto[PR_LONG]; s++; break; 43160786Sps case '=': proto = &eqproto; s++; break; 43260786Sps case 'h': proto = &hproto; s++; break; 43389019Sps case 'w': proto = &wproto; s++; break; 43460786Sps default: proto = &prproto[PR_SHORT]; break; 43560786Sps } 43660786Sps free(*proto); 43760786Sps *proto = save(s); 43860786Sps break; 43960786Sps case QUERY: 44060786Sps parg.p_string = prproto[pr_type]; 44160786Sps error("%s", &parg); 44260786Sps break; 44360786Sps } 44460786Sps} 44560786Sps 44660786Sps/* 44760786Sps * Handler for the -b option. 44860786Sps */ 44960786Sps /*ARGSUSED*/ 45060786Sps public void 45160786Spsopt_b(type, s) 45260786Sps int type; 45360786Sps char *s; 45460786Sps{ 45560786Sps switch (type) 45660786Sps { 457128345Stjr case INIT: 45860786Sps case TOGGLE: 45960786Sps /* 460128345Stjr * Set the new number of buffers. 46160786Sps */ 462128345Stjr ch_setbufspace(bufspace); 46360786Sps break; 464128345Stjr case QUERY: 46560786Sps break; 46660786Sps } 46760786Sps} 46860786Sps 46960786Sps/* 47060786Sps * Handler for the -i option. 47160786Sps */ 47260786Sps /*ARGSUSED*/ 47360786Sps public void 47460786Spsopt_i(type, s) 47560786Sps int type; 47660786Sps char *s; 47760786Sps{ 47860786Sps switch (type) 47960786Sps { 48060786Sps case TOGGLE: 48160786Sps chg_caseless(); 48260786Sps break; 48360786Sps case QUERY: 48460786Sps case INIT: 48560786Sps break; 48660786Sps } 48760786Sps} 48860786Sps 48960786Sps/* 49060786Sps * Handler for the -V option. 49160786Sps */ 49260786Sps /*ARGSUSED*/ 49360786Sps public void 49460786Spsopt__V(type, s) 49560786Sps int type; 49660786Sps char *s; 49760786Sps{ 49860786Sps switch (type) 49960786Sps { 50060786Sps case TOGGLE: 50160786Sps case QUERY: 50260786Sps dispversion(); 50360786Sps break; 50460786Sps case INIT: 50560786Sps /* 50660786Sps * Force output to stdout per GNU standard for --version output. 50760786Sps */ 50860786Sps any_display = 1; 50960786Sps putstr("less "); 51060786Sps putstr(version); 511237613Sdelphij putstr(" ("); 512237613Sdelphij#if HAVE_GNU_REGEX 513237613Sdelphij putstr("GNU "); 514237613Sdelphij#endif 515237613Sdelphij#if HAVE_POSIX_REGCOMP 516237613Sdelphij putstr("POSIX "); 517237613Sdelphij#endif 518237613Sdelphij#if HAVE_PCRE 519237613Sdelphij putstr("PCRE "); 520237613Sdelphij#endif 521237613Sdelphij#if HAVE_RE_COMP 522237613Sdelphij putstr("BSD "); 523237613Sdelphij#endif 524237613Sdelphij#if HAVE_REGCMP 525237613Sdelphij putstr("V8 "); 526237613Sdelphij#endif 527237613Sdelphij#if HAVE_V8_REGCOMP 528237613Sdelphij putstr("Spencer V8 "); 529237613Sdelphij#endif 530237613Sdelphij#if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP 531237613Sdelphij putstr("no "); 532237613Sdelphij#endif 533237613Sdelphij putstr("regular expressions)\n"); 534330571Sdelphij putstr("Copyright (C) 1984-2017 Mark Nudelman\n\n"); 53560786Sps putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); 53660786Sps putstr("For information about the terms of redistribution,\n"); 53760786Sps putstr("see the file named README in the less distribution.\n"); 53889019Sps putstr("Homepage: http://www.greenwoodsoftware.com/less\n"); 53960786Sps quit(QUIT_OK); 54060786Sps break; 54160786Sps } 54260786Sps} 54360786Sps 54460786Sps#if MSDOS_COMPILER 54560786Sps/* 54660786Sps * Parse an MSDOS color descriptor. 54760786Sps */ 54860786Sps static void 54960786Spscolordesc(s, fg_color, bg_color) 55060786Sps char *s; 55160786Sps int *fg_color; 55260786Sps int *bg_color; 55360786Sps{ 55460786Sps int fg, bg; 55560786Sps int err; 556330571Sdelphij#if MSDOS_COMPILER==WIN32C 557330571Sdelphij int ul = 0; 558330571Sdelphij 559330571Sdelphij if (*s == 'u') 560330571Sdelphij { 561330571Sdelphij ul = COMMON_LVB_UNDERSCORE; 562330571Sdelphij ++s; 563330571Sdelphij } 564330571Sdelphij#endif 565128345Stjr fg = getnum(&s, "D", &err); 56660786Sps if (err) 56760786Sps { 568330571Sdelphij#if MSDOS_COMPILER==WIN32C 569330571Sdelphij if (ul) 570330571Sdelphij fg = nm_fg_color; 571330571Sdelphij else 572330571Sdelphij#endif 573330571Sdelphij { 574330571Sdelphij error("Missing fg color in -D", NULL_PARG); 575330571Sdelphij return; 576330571Sdelphij } 57760786Sps } 57860786Sps if (*s != '.') 579191930Sdelphij bg = nm_bg_color; 58060786Sps else 58160786Sps { 58260786Sps s++; 583128345Stjr bg = getnum(&s, "D", &err); 58460786Sps if (err) 58560786Sps { 586191930Sdelphij error("Missing bg color in -D", NULL_PARG); 58760786Sps return; 58860786Sps } 58960786Sps } 590330571Sdelphij#if MSDOS_COMPILER==WIN32C 591330571Sdelphij if (*s == 'u') 592330571Sdelphij { 593330571Sdelphij ul = COMMON_LVB_UNDERSCORE; 594330571Sdelphij ++s; 595330571Sdelphij } 596330571Sdelphij fg |= ul; 597330571Sdelphij#endif 59860786Sps if (*s != '\0') 59960786Sps error("Extra characters at end of -D option", NULL_PARG); 60060786Sps *fg_color = fg; 60160786Sps *bg_color = bg; 60260786Sps} 60360786Sps 60460786Sps/* 60560786Sps * Handler for the -D option. 60660786Sps */ 60760786Sps /*ARGSUSED*/ 60860786Sps public void 60960786Spsopt_D(type, s) 61060786Sps int type; 61160786Sps char *s; 61260786Sps{ 613330571Sdelphij PARG p; 614330571Sdelphij 61560786Sps switch (type) 61660786Sps { 61760786Sps case INIT: 61860786Sps case TOGGLE: 61960786Sps switch (*s++) 62060786Sps { 62160786Sps case 'n': 62260786Sps colordesc(s, &nm_fg_color, &nm_bg_color); 62360786Sps break; 62460786Sps case 'd': 62560786Sps colordesc(s, &bo_fg_color, &bo_bg_color); 62660786Sps break; 62760786Sps case 'u': 62860786Sps colordesc(s, &ul_fg_color, &ul_bg_color); 62960786Sps break; 63060786Sps case 'k': 63160786Sps colordesc(s, &bl_fg_color, &bl_bg_color); 63260786Sps break; 63360786Sps case 's': 63460786Sps colordesc(s, &so_fg_color, &so_bg_color); 63560786Sps break; 636330571Sdelphij case 'a': 637330571Sdelphij sgr_mode = !sgr_mode; 638330571Sdelphij break; 63960786Sps default: 640330571Sdelphij error("-D must be followed by n, d, u, k, s or a", NULL_PARG); 64160786Sps break; 64260786Sps } 64360786Sps if (type == TOGGLE) 64460786Sps { 645161475Sdelphij at_enter(AT_STANDOUT); 646161475Sdelphij at_exit(); 64760786Sps } 64860786Sps break; 64960786Sps case QUERY: 650330571Sdelphij p.p_string = (sgr_mode) ? "on" : "off"; 651330571Sdelphij error("SGR mode is %s", &p); 65260786Sps break; 65360786Sps } 65460786Sps} 65560786Sps#endif 65660786Sps 65760786Sps/* 65889019Sps * Handler for the -x option. 65989019Sps */ 66089019Sps public void 66189019Spsopt_x(type, s) 66289019Sps int type; 663330571Sdelphij char *s; 66489019Sps{ 66589019Sps extern int tabstops[]; 66689019Sps extern int ntabstops; 66789019Sps extern int tabdefault; 66889019Sps char msg[60+(4*TABSTOP_MAX)]; 66989019Sps int i; 67089019Sps PARG p; 67189019Sps 67289019Sps switch (type) 67389019Sps { 67489019Sps case INIT: 67589019Sps case TOGGLE: 67689019Sps /* Start at 1 because tabstops[0] is always zero. */ 67789019Sps for (i = 1; i < TABSTOP_MAX; ) 67889019Sps { 67989019Sps int n = 0; 680128345Stjr s = skipsp(s); 68189019Sps while (*s >= '0' && *s <= '9') 68289019Sps n = (10 * n) + (*s++ - '0'); 68389019Sps if (n > tabstops[i-1]) 68489019Sps tabstops[i++] = n; 685128345Stjr s = skipsp(s); 68689019Sps if (*s++ != ',') 68789019Sps break; 68889019Sps } 68989019Sps if (i < 2) 69089019Sps return; 69189019Sps ntabstops = i; 69289019Sps tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2]; 69389019Sps break; 69489019Sps case QUERY: 69589019Sps strcpy(msg, "Tab stops "); 69689019Sps if (ntabstops > 2) 69789019Sps { 69889019Sps for (i = 1; i < ntabstops; i++) 69989019Sps { 70089019Sps if (i > 1) 70189019Sps strcat(msg, ","); 70289019Sps sprintf(msg+strlen(msg), "%d", tabstops[i]); 70389019Sps } 70489019Sps sprintf(msg+strlen(msg), " and then "); 70589019Sps } 70689019Sps sprintf(msg+strlen(msg), "every %d spaces", 70789019Sps tabdefault); 70889019Sps p.p_string = msg; 70989019Sps error("%s", &p); 71089019Sps break; 71189019Sps } 71289019Sps} 71389019Sps 71489019Sps 71589019Sps/* 71660786Sps * Handler for the -" option. 71760786Sps */ 71860786Sps public void 71960786Spsopt_quote(type, s) 72060786Sps int type; 721330571Sdelphij char *s; 72260786Sps{ 72360786Sps char buf[3]; 72460786Sps PARG parg; 72560786Sps 72660786Sps switch (type) 72760786Sps { 72860786Sps case INIT: 72960786Sps case TOGGLE: 730128345Stjr if (s[0] == '\0') 731128345Stjr { 732128345Stjr openquote = closequote = '\0'; 733128345Stjr break; 734128345Stjr } 73560786Sps if (s[1] != '\0' && s[2] != '\0') 73660786Sps { 73760786Sps error("-\" must be followed by 1 or 2 chars", NULL_PARG); 73860786Sps return; 73960786Sps } 74060786Sps openquote = s[0]; 74160786Sps if (s[1] == '\0') 74260786Sps closequote = openquote; 74360786Sps else 74460786Sps closequote = s[1]; 74560786Sps break; 74660786Sps case QUERY: 74760786Sps buf[0] = openquote; 74860786Sps buf[1] = closequote; 74960786Sps buf[2] = '\0'; 75060786Sps parg.p_string = buf; 75160786Sps error("quotes %s", &parg); 75260786Sps break; 75360786Sps } 75460786Sps} 75560786Sps 75660786Sps/* 757330571Sdelphij * Handler for the --rscroll option. 758330571Sdelphij */ 759330571Sdelphij /*ARGSUSED*/ 760330571Sdelphij public void 761330571Sdelphijopt_rscroll(type, s) 762330571Sdelphij int type; 763330571Sdelphij char *s; 764330571Sdelphij{ 765330571Sdelphij PARG p; 766330571Sdelphij 767330571Sdelphij switch (type) 768330571Sdelphij { 769330571Sdelphij case INIT: 770330571Sdelphij case TOGGLE: { 771330571Sdelphij char *fmt; 772330571Sdelphij int attr = AT_STANDOUT; 773330571Sdelphij setfmt(s, &fmt, &attr, "*s>"); 774330571Sdelphij if (strcmp(fmt, "-") == 0) 775330571Sdelphij { 776330571Sdelphij rscroll_char = 0; 777330571Sdelphij } else 778330571Sdelphij { 779330571Sdelphij rscroll_char = *fmt ? *fmt : '>'; 780330571Sdelphij rscroll_attr = attr; 781330571Sdelphij } 782330571Sdelphij break; } 783330571Sdelphij case QUERY: { 784330571Sdelphij p.p_string = rscroll_char ? prchar(rscroll_char) : "-"; 785330571Sdelphij error("rscroll char is %s", &p); 786330571Sdelphij break; } 787330571Sdelphij } 788330571Sdelphij} 789330571Sdelphij 790330571Sdelphij/* 79160786Sps * "-?" means display a help message. 79260786Sps * If from the command line, exit immediately. 79360786Sps */ 79460786Sps /*ARGSUSED*/ 79560786Sps public void 79660786Spsopt_query(type, s) 79760786Sps int type; 79860786Sps char *s; 79960786Sps{ 80060786Sps switch (type) 80160786Sps { 80260786Sps case QUERY: 80360786Sps case TOGGLE: 80460786Sps error("Use \"h\" for help", NULL_PARG); 80560786Sps break; 80660786Sps case INIT: 80760786Sps dohelp = 1; 80860786Sps } 80960786Sps} 81060786Sps 81160786Sps/* 81260786Sps * Get the "screen window" size. 81360786Sps */ 81460786Sps public int 81560786Spsget_swindow() 81660786Sps{ 81760786Sps if (swindow > 0) 81860786Sps return (swindow); 81960786Sps return (sc_height + swindow); 82060786Sps} 82160786Sps 822