1a5f0fb15SPaul Saab /* 2f6b74a7dSXin LI * Copyright (C) 1984-2017 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 * 796e55cc7SXin LI * For more information, see the README file. 8a5f0fb15SPaul Saab */ 9a5f0fb15SPaul Saab 10a5f0fb15SPaul Saab 11a5f0fb15SPaul Saab /* 12a5f0fb15SPaul Saab * Handling functions for command line options. 13a5f0fb15SPaul Saab * 14a5f0fb15SPaul Saab * Most options are handled by the generic code in option.c. 15a5f0fb15SPaul Saab * But all string options, and a few non-string options, require 16a5f0fb15SPaul Saab * special handling specific to the particular option. 17a5f0fb15SPaul Saab * This special processing is done by the "handling functions" in this file. 18a5f0fb15SPaul Saab * 19a5f0fb15SPaul Saab * Each handling function is passed a "type" and, if it is a string 20a5f0fb15SPaul Saab * option, the string which should be "assigned" to the option. 21a5f0fb15SPaul Saab * The type may be one of: 22a5f0fb15SPaul Saab * INIT The option is being initialized from the command line. 23a5f0fb15SPaul Saab * TOGGLE The option is being changed from within the program. 24a5f0fb15SPaul Saab * QUERY The setting of the option is merely being queried. 25a5f0fb15SPaul Saab */ 26a5f0fb15SPaul Saab 27a5f0fb15SPaul Saab #include "less.h" 28a5f0fb15SPaul Saab #include "option.h" 29a5f0fb15SPaul Saab 30a5f0fb15SPaul Saab extern int nbufs; 31000ba3e8STim J. Robbins extern int bufspace; 32a5f0fb15SPaul Saab extern int pr_type; 33a5f0fb15SPaul Saab extern int plusoption; 34a5f0fb15SPaul Saab extern int swindow; 35f0be0a1fSXin LI extern int sc_width; 36a5f0fb15SPaul Saab extern int sc_height; 37a5f0fb15SPaul Saab extern int secure; 38a5f0fb15SPaul Saab extern int dohelp; 39a5f0fb15SPaul Saab extern int any_display; 40a5f0fb15SPaul Saab extern char openquote; 41a5f0fb15SPaul Saab extern char closequote; 42a5f0fb15SPaul Saab extern char *prproto[]; 43a5f0fb15SPaul Saab extern char *eqproto; 44a5f0fb15SPaul Saab extern char *hproto; 45c9346414SPaul Saab extern char *wproto; 46a15691bfSXin LI extern char *every_first_cmd; 47a5f0fb15SPaul Saab extern IFILE curr_ifile; 48a5f0fb15SPaul Saab extern char version[]; 49efd72c2eSXin LI extern int jump_sline; 50f6b74a7dSXin LI extern long jump_sline_fraction; 51f0be0a1fSXin LI extern int shift_count; 52f6b74a7dSXin LI extern long shift_count_fraction; 53*b2ea2440SXin LI extern LWCHAR rscroll_char; 54*b2ea2440SXin LI extern int rscroll_attr; 55efd72c2eSXin LI extern int less_is_more; 56a5f0fb15SPaul Saab #if LOGFILE 57a5f0fb15SPaul Saab extern char *namelogfile; 58a5f0fb15SPaul Saab extern int force_logfile; 59a5f0fb15SPaul Saab extern int logfile; 60a5f0fb15SPaul Saab #endif 61a5f0fb15SPaul Saab #if TAGS 62a5f0fb15SPaul Saab public char *tagoption = NULL; 63a5f0fb15SPaul Saab extern char *tags; 64a15691bfSXin LI extern char ztags[]; 65a5f0fb15SPaul Saab #endif 66a5f0fb15SPaul Saab #if MSDOS_COMPILER 67a5f0fb15SPaul Saab extern int nm_fg_color, nm_bg_color; 68a5f0fb15SPaul Saab extern int bo_fg_color, bo_bg_color; 69a5f0fb15SPaul Saab extern int ul_fg_color, ul_bg_color; 70a5f0fb15SPaul Saab extern int so_fg_color, so_bg_color; 71a5f0fb15SPaul Saab extern int bl_fg_color, bl_bg_color; 72f6b74a7dSXin LI extern int sgr_mode; 73*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C 74*b2ea2440SXin LI #ifndef COMMON_LVB_UNDERSCORE 75*b2ea2440SXin LI #define COMMON_LVB_UNDERSCORE 0x8000 76*b2ea2440SXin LI #endif 77*b2ea2440SXin LI #endif 78a5f0fb15SPaul Saab #endif 79a5f0fb15SPaul Saab 80a5f0fb15SPaul Saab 81a5f0fb15SPaul Saab #if LOGFILE 82a5f0fb15SPaul Saab /* 83a5f0fb15SPaul Saab * Handler for -o option. 84a5f0fb15SPaul Saab */ 85a5f0fb15SPaul Saab public void 86f6b74a7dSXin LI opt_o(type, s) 87f6b74a7dSXin LI int type; 88f6b74a7dSXin LI char *s; 89a5f0fb15SPaul Saab { 90a5f0fb15SPaul Saab PARG parg; 91*b2ea2440SXin LI char *filename; 92a5f0fb15SPaul Saab 93a5f0fb15SPaul Saab if (secure) 94a5f0fb15SPaul Saab { 95a5f0fb15SPaul Saab error("log file support is not available", NULL_PARG); 96a5f0fb15SPaul Saab return; 97a5f0fb15SPaul Saab } 98a5f0fb15SPaul Saab switch (type) 99a5f0fb15SPaul Saab { 100a5f0fb15SPaul Saab case INIT: 101a15691bfSXin LI namelogfile = save(s); 102a5f0fb15SPaul Saab break; 103a5f0fb15SPaul Saab case TOGGLE: 104a5f0fb15SPaul Saab if (ch_getflags() & CH_CANSEEK) 105a5f0fb15SPaul Saab { 106a5f0fb15SPaul Saab error("Input is not a pipe", NULL_PARG); 107a5f0fb15SPaul Saab return; 108a5f0fb15SPaul Saab } 109a5f0fb15SPaul Saab if (logfile >= 0) 110a5f0fb15SPaul Saab { 111a5f0fb15SPaul Saab error("Log file is already in use", NULL_PARG); 112a5f0fb15SPaul Saab return; 113a5f0fb15SPaul Saab } 114a5f0fb15SPaul Saab s = skipsp(s); 115a15691bfSXin LI if (namelogfile != NULL) 116a15691bfSXin LI free(namelogfile); 117*b2ea2440SXin LI filename = lglob(s); 118*b2ea2440SXin LI namelogfile = shell_unquote(filename); 119*b2ea2440SXin LI free(filename); 120a5f0fb15SPaul Saab use_logfile(namelogfile); 121a5f0fb15SPaul Saab sync_logfile(); 122a5f0fb15SPaul Saab break; 123a5f0fb15SPaul Saab case QUERY: 124a5f0fb15SPaul Saab if (logfile < 0) 125a5f0fb15SPaul Saab error("No log file", NULL_PARG); 126a5f0fb15SPaul Saab else 127a5f0fb15SPaul Saab { 128000ba3e8STim J. Robbins parg.p_string = namelogfile; 129a5f0fb15SPaul Saab error("Log file \"%s\"", &parg); 130a5f0fb15SPaul Saab } 131a5f0fb15SPaul Saab break; 132a5f0fb15SPaul Saab } 133a5f0fb15SPaul Saab } 134a5f0fb15SPaul Saab 135a5f0fb15SPaul Saab /* 136a5f0fb15SPaul Saab * Handler for -O option. 137a5f0fb15SPaul Saab */ 138a5f0fb15SPaul Saab public void 139f6b74a7dSXin LI opt__O(type, s) 140f6b74a7dSXin LI int type; 141f6b74a7dSXin LI char *s; 142a5f0fb15SPaul Saab { 143a5f0fb15SPaul Saab force_logfile = TRUE; 144a5f0fb15SPaul Saab opt_o(type, s); 145a5f0fb15SPaul Saab } 146a5f0fb15SPaul Saab #endif 147a5f0fb15SPaul Saab 148a5f0fb15SPaul Saab /* 1497f074f9cSXin LI * Handlers for -j option. 1507f074f9cSXin LI */ 1517f074f9cSXin LI public void 152f6b74a7dSXin LI opt_j(type, s) 153f6b74a7dSXin LI int type; 154f6b74a7dSXin LI char *s; 1557f074f9cSXin LI { 1567f074f9cSXin LI PARG parg; 1577f074f9cSXin LI char buf[16]; 1587f074f9cSXin LI int len; 1597f074f9cSXin LI int err; 1607f074f9cSXin LI 1617f074f9cSXin LI switch (type) 1627f074f9cSXin LI { 1637f074f9cSXin LI case INIT: 1647f074f9cSXin LI case TOGGLE: 1657f074f9cSXin LI if (*s == '.') 1667f074f9cSXin LI { 1677f074f9cSXin LI s++; 1687f074f9cSXin LI jump_sline_fraction = getfraction(&s, "j", &err); 1697f074f9cSXin LI if (err) 1707f074f9cSXin LI error("Invalid line fraction", NULL_PARG); 1717f074f9cSXin LI else 1727f074f9cSXin LI calc_jump_sline(); 1737f074f9cSXin LI } else 1747f074f9cSXin LI { 1757f074f9cSXin LI int sline = getnum(&s, "j", &err); 1767f074f9cSXin LI if (err) 1777f074f9cSXin LI error("Invalid line number", NULL_PARG); 1787f074f9cSXin LI else 1797f074f9cSXin LI { 1807f074f9cSXin LI jump_sline = sline; 1817f074f9cSXin LI jump_sline_fraction = -1; 1827f074f9cSXin LI } 1837f074f9cSXin LI } 1847f074f9cSXin LI break; 1857f074f9cSXin LI case QUERY: 1867f074f9cSXin LI if (jump_sline_fraction < 0) 1877f074f9cSXin LI { 1887f074f9cSXin LI parg.p_int = jump_sline; 1897f074f9cSXin LI error("Position target at screen line %d", &parg); 1907f074f9cSXin LI } else 1917f074f9cSXin LI { 1927f074f9cSXin LI 193f6b74a7dSXin LI sprintf(buf, ".%06ld", jump_sline_fraction); 194a15691bfSXin LI len = (int) strlen(buf); 1957f074f9cSXin LI while (len > 2 && buf[len-1] == '0') 1967f074f9cSXin LI len--; 1977f074f9cSXin LI buf[len] = '\0'; 1987f074f9cSXin LI parg.p_string = buf; 1997f074f9cSXin LI error("Position target at screen position %s", &parg); 2007f074f9cSXin LI } 2017f074f9cSXin LI break; 2027f074f9cSXin LI } 2037f074f9cSXin LI } 2047f074f9cSXin LI 2057f074f9cSXin LI public void 206f6b74a7dSXin LI calc_jump_sline() 2077f074f9cSXin LI { 2087f074f9cSXin LI if (jump_sline_fraction < 0) 2097f074f9cSXin LI return; 2107f074f9cSXin LI jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM; 2117f074f9cSXin LI } 2127f074f9cSXin LI 213f0be0a1fSXin LI /* 214f0be0a1fSXin LI * Handlers for -# option. 215f0be0a1fSXin LI */ 216f0be0a1fSXin LI public void 217f6b74a7dSXin LI opt_shift(type, s) 218f6b74a7dSXin LI int type; 219f6b74a7dSXin LI char *s; 220f0be0a1fSXin LI { 221f0be0a1fSXin LI PARG parg; 222f0be0a1fSXin LI char buf[16]; 223f0be0a1fSXin LI int len; 224f0be0a1fSXin LI int err; 225f0be0a1fSXin LI 226f0be0a1fSXin LI switch (type) 227f0be0a1fSXin LI { 228f0be0a1fSXin LI case INIT: 229f0be0a1fSXin LI case TOGGLE: 230f0be0a1fSXin LI if (*s == '.') 231f0be0a1fSXin LI { 232f0be0a1fSXin LI s++; 233f0be0a1fSXin LI shift_count_fraction = getfraction(&s, "#", &err); 234f0be0a1fSXin LI if (err) 235f0be0a1fSXin LI error("Invalid column fraction", NULL_PARG); 236f0be0a1fSXin LI else 237f0be0a1fSXin LI calc_shift_count(); 238f0be0a1fSXin LI } else 239f0be0a1fSXin LI { 240f0be0a1fSXin LI int hs = getnum(&s, "#", &err); 241f0be0a1fSXin LI if (err) 242f0be0a1fSXin LI error("Invalid column number", NULL_PARG); 243f0be0a1fSXin LI else 244f0be0a1fSXin LI { 245f0be0a1fSXin LI shift_count = hs; 246f0be0a1fSXin LI shift_count_fraction = -1; 247f0be0a1fSXin LI } 248f0be0a1fSXin LI } 249f0be0a1fSXin LI break; 250f0be0a1fSXin LI case QUERY: 251f0be0a1fSXin LI if (shift_count_fraction < 0) 252f0be0a1fSXin LI { 253f0be0a1fSXin LI parg.p_int = shift_count; 254f0be0a1fSXin LI error("Horizontal shift %d columns", &parg); 255f0be0a1fSXin LI } else 256f0be0a1fSXin LI { 257f0be0a1fSXin LI 258f6b74a7dSXin LI sprintf(buf, ".%06ld", shift_count_fraction); 259a15691bfSXin LI len = (int) strlen(buf); 260f0be0a1fSXin LI while (len > 2 && buf[len-1] == '0') 261f0be0a1fSXin LI len--; 262f0be0a1fSXin LI buf[len] = '\0'; 263f0be0a1fSXin LI parg.p_string = buf; 264f0be0a1fSXin LI error("Horizontal shift %s of screen width", &parg); 265f0be0a1fSXin LI } 266f0be0a1fSXin LI break; 267f0be0a1fSXin LI } 268f0be0a1fSXin LI } 269f0be0a1fSXin LI public void 270f6b74a7dSXin LI calc_shift_count() 271f0be0a1fSXin LI { 272f0be0a1fSXin LI if (shift_count_fraction < 0) 273f0be0a1fSXin LI return; 274f0be0a1fSXin LI shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM; 275f0be0a1fSXin LI } 276f0be0a1fSXin LI 277a5f0fb15SPaul Saab #if USERFILE 278a5f0fb15SPaul Saab public void 279f6b74a7dSXin LI opt_k(type, s) 280f6b74a7dSXin LI int type; 281f6b74a7dSXin LI char *s; 282a5f0fb15SPaul Saab { 283a5f0fb15SPaul Saab PARG parg; 284a5f0fb15SPaul Saab 285a5f0fb15SPaul Saab switch (type) 286a5f0fb15SPaul Saab { 287a5f0fb15SPaul Saab case INIT: 288a5f0fb15SPaul Saab if (lesskey(s, 0)) 289a5f0fb15SPaul Saab { 290000ba3e8STim J. Robbins parg.p_string = s; 291a5f0fb15SPaul Saab error("Cannot use lesskey file \"%s\"", &parg); 292a5f0fb15SPaul Saab } 293a5f0fb15SPaul Saab break; 294a5f0fb15SPaul Saab } 295a5f0fb15SPaul Saab } 296a5f0fb15SPaul Saab #endif 297a5f0fb15SPaul Saab 298a5f0fb15SPaul Saab #if TAGS 299a5f0fb15SPaul Saab /* 300a5f0fb15SPaul Saab * Handler for -t option. 301a5f0fb15SPaul Saab */ 302a5f0fb15SPaul Saab public void 303f6b74a7dSXin LI opt_t(type, s) 304f6b74a7dSXin LI int type; 305f6b74a7dSXin LI char *s; 306a5f0fb15SPaul Saab { 307a5f0fb15SPaul Saab IFILE save_ifile; 308a5f0fb15SPaul Saab POSITION pos; 309a5f0fb15SPaul Saab 310a5f0fb15SPaul Saab switch (type) 311a5f0fb15SPaul Saab { 312a5f0fb15SPaul Saab case INIT: 313a15691bfSXin LI tagoption = save(s); 314a5f0fb15SPaul Saab /* Do the rest in main() */ 315a5f0fb15SPaul Saab break; 316a5f0fb15SPaul Saab case TOGGLE: 317a5f0fb15SPaul Saab if (secure) 318a5f0fb15SPaul Saab { 319a5f0fb15SPaul Saab error("tags support is not available", NULL_PARG); 320a5f0fb15SPaul Saab break; 321a5f0fb15SPaul Saab } 322a5f0fb15SPaul Saab findtag(skipsp(s)); 323a5f0fb15SPaul Saab save_ifile = save_curr_ifile(); 3246dcb072bSXin LI /* 3256dcb072bSXin LI * Try to open the file containing the tag 3266dcb072bSXin LI * and search for the tag in that file. 3276dcb072bSXin LI */ 3286dcb072bSXin LI if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION) 329a5f0fb15SPaul Saab { 3306dcb072bSXin LI /* Failed: reopen the old file. */ 331a5f0fb15SPaul Saab reedit_ifile(save_ifile); 332a5f0fb15SPaul Saab break; 333a5f0fb15SPaul Saab } 334a5f0fb15SPaul Saab unsave_ifile(save_ifile); 335a5f0fb15SPaul Saab jump_loc(pos, jump_sline); 336a5f0fb15SPaul Saab break; 337a5f0fb15SPaul Saab } 338a5f0fb15SPaul Saab } 339a5f0fb15SPaul Saab 340a5f0fb15SPaul Saab /* 341a5f0fb15SPaul Saab * Handler for -T option. 342a5f0fb15SPaul Saab */ 343a5f0fb15SPaul Saab public void 344f6b74a7dSXin LI opt__T(type, s) 345f6b74a7dSXin LI int type; 346f6b74a7dSXin LI char *s; 347a5f0fb15SPaul Saab { 348a5f0fb15SPaul Saab PARG parg; 349*b2ea2440SXin LI char *filename; 350a5f0fb15SPaul Saab 351a5f0fb15SPaul Saab switch (type) 352a5f0fb15SPaul Saab { 353a5f0fb15SPaul Saab case INIT: 354a15691bfSXin LI tags = save(s); 355a5f0fb15SPaul Saab break; 356a5f0fb15SPaul Saab case TOGGLE: 357a5f0fb15SPaul Saab s = skipsp(s); 358a15691bfSXin LI if (tags != NULL && tags != ztags) 359a15691bfSXin LI free(tags); 360*b2ea2440SXin LI filename = lglob(s); 361*b2ea2440SXin LI tags = shell_unquote(filename); 362*b2ea2440SXin LI free(filename); 363a5f0fb15SPaul Saab break; 364a5f0fb15SPaul Saab case QUERY: 365000ba3e8STim J. Robbins parg.p_string = tags; 366a5f0fb15SPaul Saab error("Tags file \"%s\"", &parg); 367a5f0fb15SPaul Saab break; 368a5f0fb15SPaul Saab } 369a5f0fb15SPaul Saab } 370a5f0fb15SPaul Saab #endif 371a5f0fb15SPaul Saab 372a5f0fb15SPaul Saab /* 373a5f0fb15SPaul Saab * Handler for -p option. 374a5f0fb15SPaul Saab */ 375a5f0fb15SPaul Saab public void 376f6b74a7dSXin LI opt_p(type, s) 377f6b74a7dSXin LI int type; 378f6b74a7dSXin LI char *s; 379a5f0fb15SPaul Saab { 380a5f0fb15SPaul Saab switch (type) 381a5f0fb15SPaul Saab { 382a5f0fb15SPaul Saab case INIT: 383a5f0fb15SPaul Saab /* 384a15691bfSXin LI * Unget a command for the specified string. 385a5f0fb15SPaul Saab */ 386a15691bfSXin LI if (less_is_more) 387a15691bfSXin LI { 3886dcb072bSXin LI /* 3896dcb072bSXin LI * In "more" mode, the -p argument is a command, 3906dcb072bSXin LI * not a search string, so we don't need a slash. 3916dcb072bSXin LI */ 392a15691bfSXin LI every_first_cmd = save(s); 393a15691bfSXin LI } else 394a15691bfSXin LI { 395a15691bfSXin LI plusoption = TRUE; 396a15691bfSXin LI ungetcc(CHAR_END_COMMAND); 397a15691bfSXin LI ungetsc(s); 398a15691bfSXin LI /* 399a15691bfSXin LI * {{ This won't work if the "/" command is 400a15691bfSXin LI * changed or invalidated by a .lesskey file. }} 401a15691bfSXin LI */ 402a5f0fb15SPaul Saab ungetsc("/"); 403a15691bfSXin LI } 404a5f0fb15SPaul Saab break; 405a5f0fb15SPaul Saab } 406a5f0fb15SPaul Saab } 407a5f0fb15SPaul Saab 408a5f0fb15SPaul Saab /* 409a5f0fb15SPaul Saab * Handler for -P option. 410a5f0fb15SPaul Saab */ 411a5f0fb15SPaul Saab public void 412f6b74a7dSXin LI opt__P(type, s) 413f6b74a7dSXin LI int type; 414f6b74a7dSXin LI char *s; 415a5f0fb15SPaul Saab { 4161ea31627SRobert Watson char **proto; 417a5f0fb15SPaul Saab PARG parg; 418a5f0fb15SPaul Saab 419a5f0fb15SPaul Saab switch (type) 420a5f0fb15SPaul Saab { 421a5f0fb15SPaul Saab case INIT: 422a5f0fb15SPaul Saab case TOGGLE: 423a5f0fb15SPaul Saab /* 424a5f0fb15SPaul Saab * Figure out which prototype string should be changed. 425a5f0fb15SPaul Saab */ 426a5f0fb15SPaul Saab switch (*s) 427a5f0fb15SPaul Saab { 428a5f0fb15SPaul Saab case 's': proto = &prproto[PR_SHORT]; s++; break; 429a5f0fb15SPaul Saab case 'm': proto = &prproto[PR_MEDIUM]; s++; break; 430a5f0fb15SPaul Saab case 'M': proto = &prproto[PR_LONG]; s++; break; 431a5f0fb15SPaul Saab case '=': proto = &eqproto; s++; break; 432a5f0fb15SPaul Saab case 'h': proto = &hproto; s++; break; 433c9346414SPaul Saab case 'w': proto = &wproto; s++; break; 434a5f0fb15SPaul Saab default: proto = &prproto[PR_SHORT]; break; 435a5f0fb15SPaul Saab } 436a5f0fb15SPaul Saab free(*proto); 437a5f0fb15SPaul Saab *proto = save(s); 438a5f0fb15SPaul Saab break; 439a5f0fb15SPaul Saab case QUERY: 440a5f0fb15SPaul Saab parg.p_string = prproto[pr_type]; 441a5f0fb15SPaul Saab error("%s", &parg); 442a5f0fb15SPaul Saab break; 443a5f0fb15SPaul Saab } 444a5f0fb15SPaul Saab } 445a5f0fb15SPaul Saab 446a5f0fb15SPaul Saab /* 447a5f0fb15SPaul Saab * Handler for the -b option. 448a5f0fb15SPaul Saab */ 449a5f0fb15SPaul Saab /*ARGSUSED*/ 450a5f0fb15SPaul Saab public void 451f6b74a7dSXin LI opt_b(type, s) 452f6b74a7dSXin LI int type; 453f6b74a7dSXin LI char *s; 454a5f0fb15SPaul Saab { 455a5f0fb15SPaul Saab switch (type) 456a5f0fb15SPaul Saab { 457a5f0fb15SPaul Saab case INIT: 458000ba3e8STim J. Robbins case TOGGLE: 459000ba3e8STim J. Robbins /* 460000ba3e8STim J. Robbins * Set the new number of buffers. 461000ba3e8STim J. Robbins */ 462000ba3e8STim J. Robbins ch_setbufspace(bufspace); 463000ba3e8STim J. Robbins break; 464000ba3e8STim J. Robbins case QUERY: 465a5f0fb15SPaul Saab break; 466a5f0fb15SPaul Saab } 467a5f0fb15SPaul Saab } 468a5f0fb15SPaul Saab 469a5f0fb15SPaul Saab /* 470a5f0fb15SPaul Saab * Handler for the -i option. 471a5f0fb15SPaul Saab */ 472a5f0fb15SPaul Saab /*ARGSUSED*/ 473a5f0fb15SPaul Saab public void 474f6b74a7dSXin LI opt_i(type, s) 475f6b74a7dSXin LI int type; 476f6b74a7dSXin LI char *s; 477a5f0fb15SPaul Saab { 478a5f0fb15SPaul Saab switch (type) 479a5f0fb15SPaul Saab { 480a5f0fb15SPaul Saab case TOGGLE: 481a5f0fb15SPaul Saab chg_caseless(); 482a5f0fb15SPaul Saab break; 483a5f0fb15SPaul Saab case QUERY: 484a5f0fb15SPaul Saab case INIT: 485a5f0fb15SPaul Saab break; 486a5f0fb15SPaul Saab } 487a5f0fb15SPaul Saab } 488a5f0fb15SPaul Saab 489a5f0fb15SPaul Saab /* 490a5f0fb15SPaul Saab * Handler for the -V option. 491a5f0fb15SPaul Saab */ 492a5f0fb15SPaul Saab /*ARGSUSED*/ 493a5f0fb15SPaul Saab public void 494f6b74a7dSXin LI opt__V(type, s) 495f6b74a7dSXin LI int type; 496f6b74a7dSXin LI char *s; 497a5f0fb15SPaul Saab { 498a5f0fb15SPaul Saab switch (type) 499a5f0fb15SPaul Saab { 500a5f0fb15SPaul Saab case TOGGLE: 501a5f0fb15SPaul Saab case QUERY: 502a5f0fb15SPaul Saab dispversion(); 503a5f0fb15SPaul Saab break; 504a5f0fb15SPaul Saab case INIT: 505a5f0fb15SPaul Saab /* 506a5f0fb15SPaul Saab * Force output to stdout per GNU standard for --version output. 507a5f0fb15SPaul Saab */ 508a5f0fb15SPaul Saab any_display = 1; 509a5f0fb15SPaul Saab putstr("less "); 510a5f0fb15SPaul Saab putstr(version); 51196e55cc7SXin LI putstr(" ("); 51296e55cc7SXin LI #if HAVE_GNU_REGEX 51396e55cc7SXin LI putstr("GNU "); 51496e55cc7SXin LI #endif 51596e55cc7SXin LI #if HAVE_POSIX_REGCOMP 51696e55cc7SXin LI putstr("POSIX "); 51796e55cc7SXin LI #endif 51896e55cc7SXin LI #if HAVE_PCRE 51996e55cc7SXin LI putstr("PCRE "); 52096e55cc7SXin LI #endif 52196e55cc7SXin LI #if HAVE_RE_COMP 52296e55cc7SXin LI putstr("BSD "); 52396e55cc7SXin LI #endif 52496e55cc7SXin LI #if HAVE_REGCMP 52596e55cc7SXin LI putstr("V8 "); 52696e55cc7SXin LI #endif 52796e55cc7SXin LI #if HAVE_V8_REGCOMP 52896e55cc7SXin LI putstr("Spencer V8 "); 52996e55cc7SXin LI #endif 53096e55cc7SXin LI #if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP 53196e55cc7SXin LI putstr("no "); 53296e55cc7SXin LI #endif 53396e55cc7SXin LI putstr("regular expressions)\n"); 534f6b74a7dSXin LI putstr("Copyright (C) 1984-2017 Mark Nudelman\n\n"); 535a5f0fb15SPaul Saab putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); 536a5f0fb15SPaul Saab putstr("For information about the terms of redistribution,\n"); 537a5f0fb15SPaul Saab putstr("see the file named README in the less distribution.\n"); 538c9346414SPaul Saab putstr("Homepage: http://www.greenwoodsoftware.com/less\n"); 539a5f0fb15SPaul Saab quit(QUIT_OK); 540a5f0fb15SPaul Saab break; 541a5f0fb15SPaul Saab } 542a5f0fb15SPaul Saab } 543a5f0fb15SPaul Saab 544a5f0fb15SPaul Saab #if MSDOS_COMPILER 545a5f0fb15SPaul Saab /* 546a5f0fb15SPaul Saab * Parse an MSDOS color descriptor. 547a5f0fb15SPaul Saab */ 548a5f0fb15SPaul Saab static void 549f6b74a7dSXin LI colordesc(s, fg_color, bg_color) 550f6b74a7dSXin LI char *s; 551f6b74a7dSXin LI int *fg_color; 552f6b74a7dSXin LI int *bg_color; 553a5f0fb15SPaul Saab { 554a5f0fb15SPaul Saab int fg, bg; 555a5f0fb15SPaul Saab int err; 556*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C 557*b2ea2440SXin LI int ul = 0; 558a5f0fb15SPaul Saab 559*b2ea2440SXin LI if (*s == 'u') 560*b2ea2440SXin LI { 561*b2ea2440SXin LI ul = COMMON_LVB_UNDERSCORE; 562*b2ea2440SXin LI ++s; 563*b2ea2440SXin LI } 564*b2ea2440SXin LI #endif 565000ba3e8STim J. Robbins fg = getnum(&s, "D", &err); 566a5f0fb15SPaul Saab if (err) 567a5f0fb15SPaul Saab { 568*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C 569*b2ea2440SXin LI if (ul) 570*b2ea2440SXin LI fg = nm_fg_color; 571*b2ea2440SXin LI else 572*b2ea2440SXin LI #endif 573*b2ea2440SXin LI { 574a5f0fb15SPaul Saab error("Missing fg color in -D", NULL_PARG); 575a5f0fb15SPaul Saab return; 576a5f0fb15SPaul Saab } 577*b2ea2440SXin LI } 578a5f0fb15SPaul Saab if (*s != '.') 5797374caaaSXin LI bg = nm_bg_color; 580a5f0fb15SPaul Saab else 581a5f0fb15SPaul Saab { 582a5f0fb15SPaul Saab s++; 583000ba3e8STim J. Robbins bg = getnum(&s, "D", &err); 584a5f0fb15SPaul Saab if (err) 585a5f0fb15SPaul Saab { 5867374caaaSXin LI error("Missing bg color in -D", NULL_PARG); 587a5f0fb15SPaul Saab return; 588a5f0fb15SPaul Saab } 589a5f0fb15SPaul Saab } 590*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C 591*b2ea2440SXin LI if (*s == 'u') 592*b2ea2440SXin LI { 593*b2ea2440SXin LI ul = COMMON_LVB_UNDERSCORE; 594*b2ea2440SXin LI ++s; 595*b2ea2440SXin LI } 596*b2ea2440SXin LI fg |= ul; 597*b2ea2440SXin LI #endif 598a5f0fb15SPaul Saab if (*s != '\0') 599a5f0fb15SPaul Saab error("Extra characters at end of -D option", NULL_PARG); 600a5f0fb15SPaul Saab *fg_color = fg; 601a5f0fb15SPaul Saab *bg_color = bg; 602a5f0fb15SPaul Saab } 603a5f0fb15SPaul Saab 604a5f0fb15SPaul Saab /* 605a5f0fb15SPaul Saab * Handler for the -D option. 606a5f0fb15SPaul Saab */ 607a5f0fb15SPaul Saab /*ARGSUSED*/ 608a5f0fb15SPaul Saab public void 609f6b74a7dSXin LI opt_D(type, s) 610f6b74a7dSXin LI int type; 611f6b74a7dSXin LI char *s; 612a5f0fb15SPaul Saab { 613f6b74a7dSXin LI PARG p; 614f6b74a7dSXin LI 615a5f0fb15SPaul Saab switch (type) 616a5f0fb15SPaul Saab { 617a5f0fb15SPaul Saab case INIT: 618a5f0fb15SPaul Saab case TOGGLE: 619a5f0fb15SPaul Saab switch (*s++) 620a5f0fb15SPaul Saab { 621a5f0fb15SPaul Saab case 'n': 622a5f0fb15SPaul Saab colordesc(s, &nm_fg_color, &nm_bg_color); 623a5f0fb15SPaul Saab break; 624a5f0fb15SPaul Saab case 'd': 625a5f0fb15SPaul Saab colordesc(s, &bo_fg_color, &bo_bg_color); 626a5f0fb15SPaul Saab break; 627a5f0fb15SPaul Saab case 'u': 628a5f0fb15SPaul Saab colordesc(s, &ul_fg_color, &ul_bg_color); 629a5f0fb15SPaul Saab break; 630a5f0fb15SPaul Saab case 'k': 631a5f0fb15SPaul Saab colordesc(s, &bl_fg_color, &bl_bg_color); 632a5f0fb15SPaul Saab break; 633a5f0fb15SPaul Saab case 's': 634a5f0fb15SPaul Saab colordesc(s, &so_fg_color, &so_bg_color); 635a5f0fb15SPaul Saab break; 636f6b74a7dSXin LI case 'a': 637f6b74a7dSXin LI sgr_mode = !sgr_mode; 638f6b74a7dSXin LI break; 639a5f0fb15SPaul Saab default: 640f6b74a7dSXin LI error("-D must be followed by n, d, u, k, s or a", NULL_PARG); 641a5f0fb15SPaul Saab break; 642a5f0fb15SPaul Saab } 643a5f0fb15SPaul Saab if (type == TOGGLE) 644a5f0fb15SPaul Saab { 6456dcb072bSXin LI at_enter(AT_STANDOUT); 6466dcb072bSXin LI at_exit(); 647a5f0fb15SPaul Saab } 648a5f0fb15SPaul Saab break; 649a5f0fb15SPaul Saab case QUERY: 650f6b74a7dSXin LI p.p_string = (sgr_mode) ? "on" : "off"; 651f6b74a7dSXin LI error("SGR mode is %s", &p); 652a5f0fb15SPaul Saab break; 653a5f0fb15SPaul Saab } 654a5f0fb15SPaul Saab } 655a5f0fb15SPaul Saab #endif 656a5f0fb15SPaul Saab 657a5f0fb15SPaul Saab /* 658c9346414SPaul Saab * Handler for the -x option. 659c9346414SPaul Saab */ 660c9346414SPaul Saab public void 661f6b74a7dSXin LI opt_x(type, s) 662f6b74a7dSXin LI int type; 663f6b74a7dSXin LI char *s; 664c9346414SPaul Saab { 665c9346414SPaul Saab extern int tabstops[]; 666c9346414SPaul Saab extern int ntabstops; 667c9346414SPaul Saab extern int tabdefault; 668c9346414SPaul Saab char msg[60+(4*TABSTOP_MAX)]; 669c9346414SPaul Saab int i; 670c9346414SPaul Saab PARG p; 671c9346414SPaul Saab 672c9346414SPaul Saab switch (type) 673c9346414SPaul Saab { 674c9346414SPaul Saab case INIT: 675c9346414SPaul Saab case TOGGLE: 676c9346414SPaul Saab /* Start at 1 because tabstops[0] is always zero. */ 677c9346414SPaul Saab for (i = 1; i < TABSTOP_MAX; ) 678c9346414SPaul Saab { 679c9346414SPaul Saab int n = 0; 680000ba3e8STim J. Robbins s = skipsp(s); 681c9346414SPaul Saab while (*s >= '0' && *s <= '9') 682c9346414SPaul Saab n = (10 * n) + (*s++ - '0'); 683c9346414SPaul Saab if (n > tabstops[i-1]) 684c9346414SPaul Saab tabstops[i++] = n; 685000ba3e8STim J. Robbins s = skipsp(s); 686c9346414SPaul Saab if (*s++ != ',') 687c9346414SPaul Saab break; 688c9346414SPaul Saab } 689c9346414SPaul Saab if (i < 2) 690c9346414SPaul Saab return; 691c9346414SPaul Saab ntabstops = i; 692c9346414SPaul Saab tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2]; 693c9346414SPaul Saab break; 694c9346414SPaul Saab case QUERY: 695c9346414SPaul Saab strcpy(msg, "Tab stops "); 696c9346414SPaul Saab if (ntabstops > 2) 697c9346414SPaul Saab { 698c9346414SPaul Saab for (i = 1; i < ntabstops; i++) 699c9346414SPaul Saab { 700c9346414SPaul Saab if (i > 1) 701c9346414SPaul Saab strcat(msg, ","); 702c9346414SPaul Saab sprintf(msg+strlen(msg), "%d", tabstops[i]); 703c9346414SPaul Saab } 704c9346414SPaul Saab sprintf(msg+strlen(msg), " and then "); 705c9346414SPaul Saab } 706c9346414SPaul Saab sprintf(msg+strlen(msg), "every %d spaces", 707c9346414SPaul Saab tabdefault); 708c9346414SPaul Saab p.p_string = msg; 709c9346414SPaul Saab error("%s", &p); 710c9346414SPaul Saab break; 711c9346414SPaul Saab } 712c9346414SPaul Saab } 713c9346414SPaul Saab 714c9346414SPaul Saab 715c9346414SPaul Saab /* 716a5f0fb15SPaul Saab * Handler for the -" option. 717a5f0fb15SPaul Saab */ 718a5f0fb15SPaul Saab public void 719f6b74a7dSXin LI opt_quote(type, s) 720f6b74a7dSXin LI int type; 721f6b74a7dSXin LI char *s; 722a5f0fb15SPaul Saab { 723a5f0fb15SPaul Saab char buf[3]; 724a5f0fb15SPaul Saab PARG parg; 725a5f0fb15SPaul Saab 726a5f0fb15SPaul Saab switch (type) 727a5f0fb15SPaul Saab { 728a5f0fb15SPaul Saab case INIT: 729a5f0fb15SPaul Saab case TOGGLE: 730000ba3e8STim J. Robbins if (s[0] == '\0') 731000ba3e8STim J. Robbins { 732000ba3e8STim J. Robbins openquote = closequote = '\0'; 733000ba3e8STim J. Robbins break; 734000ba3e8STim J. Robbins } 735a5f0fb15SPaul Saab if (s[1] != '\0' && s[2] != '\0') 736a5f0fb15SPaul Saab { 737a5f0fb15SPaul Saab error("-\" must be followed by 1 or 2 chars", NULL_PARG); 738a5f0fb15SPaul Saab return; 739a5f0fb15SPaul Saab } 740a5f0fb15SPaul Saab openquote = s[0]; 741a5f0fb15SPaul Saab if (s[1] == '\0') 742a5f0fb15SPaul Saab closequote = openquote; 743a5f0fb15SPaul Saab else 744a5f0fb15SPaul Saab closequote = s[1]; 745a5f0fb15SPaul Saab break; 746a5f0fb15SPaul Saab case QUERY: 747a5f0fb15SPaul Saab buf[0] = openquote; 748a5f0fb15SPaul Saab buf[1] = closequote; 749a5f0fb15SPaul Saab buf[2] = '\0'; 750a5f0fb15SPaul Saab parg.p_string = buf; 751a5f0fb15SPaul Saab error("quotes %s", &parg); 752a5f0fb15SPaul Saab break; 753a5f0fb15SPaul Saab } 754a5f0fb15SPaul Saab } 755a5f0fb15SPaul Saab 756a5f0fb15SPaul Saab /* 757*b2ea2440SXin LI * Handler for the --rscroll option. 758*b2ea2440SXin LI */ 759*b2ea2440SXin LI /*ARGSUSED*/ 760*b2ea2440SXin LI public void 761*b2ea2440SXin LI opt_rscroll(type, s) 762*b2ea2440SXin LI int type; 763*b2ea2440SXin LI char *s; 764*b2ea2440SXin LI { 765*b2ea2440SXin LI PARG p; 766*b2ea2440SXin LI 767*b2ea2440SXin LI switch (type) 768*b2ea2440SXin LI { 769*b2ea2440SXin LI case INIT: 770*b2ea2440SXin LI case TOGGLE: { 771*b2ea2440SXin LI char *fmt; 772*b2ea2440SXin LI int attr = AT_STANDOUT; 773*b2ea2440SXin LI setfmt(s, &fmt, &attr, "*s>"); 774*b2ea2440SXin LI if (strcmp(fmt, "-") == 0) 775*b2ea2440SXin LI { 776*b2ea2440SXin LI rscroll_char = 0; 777*b2ea2440SXin LI } else 778*b2ea2440SXin LI { 779*b2ea2440SXin LI rscroll_char = *fmt ? *fmt : '>'; 780*b2ea2440SXin LI rscroll_attr = attr; 781*b2ea2440SXin LI } 782*b2ea2440SXin LI break; } 783*b2ea2440SXin LI case QUERY: { 784*b2ea2440SXin LI p.p_string = rscroll_char ? prchar(rscroll_char) : "-"; 785*b2ea2440SXin LI error("rscroll char is %s", &p); 786*b2ea2440SXin LI break; } 787*b2ea2440SXin LI } 788*b2ea2440SXin LI } 789*b2ea2440SXin LI 790*b2ea2440SXin LI /* 791a5f0fb15SPaul Saab * "-?" means display a help message. 792a5f0fb15SPaul Saab * If from the command line, exit immediately. 793a5f0fb15SPaul Saab */ 794a5f0fb15SPaul Saab /*ARGSUSED*/ 795a5f0fb15SPaul Saab public void 796f6b74a7dSXin LI opt_query(type, s) 797f6b74a7dSXin LI int type; 798f6b74a7dSXin LI char *s; 799a5f0fb15SPaul Saab { 800a5f0fb15SPaul Saab switch (type) 801a5f0fb15SPaul Saab { 802a5f0fb15SPaul Saab case QUERY: 803a5f0fb15SPaul Saab case TOGGLE: 804a5f0fb15SPaul Saab error("Use \"h\" for help", NULL_PARG); 805a5f0fb15SPaul Saab break; 806a5f0fb15SPaul Saab case INIT: 807a5f0fb15SPaul Saab dohelp = 1; 808a5f0fb15SPaul Saab } 809a5f0fb15SPaul Saab } 810a5f0fb15SPaul Saab 811a5f0fb15SPaul Saab /* 812a5f0fb15SPaul Saab * Get the "screen window" size. 813a5f0fb15SPaul Saab */ 814a5f0fb15SPaul Saab public int 815f6b74a7dSXin LI get_swindow() 816a5f0fb15SPaul Saab { 817a5f0fb15SPaul Saab if (swindow > 0) 818a5f0fb15SPaul Saab return (swindow); 819a5f0fb15SPaul Saab return (sc_height + swindow); 820a5f0fb15SPaul Saab } 821a5f0fb15SPaul Saab 822