X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=thirdparty%2Fless%2Foptfunc.c;fp=thirdparty%2Fless%2Foptfunc.c;h=a0aa10a81cd3ea105bffa0aeabbe3c9e8684dd22;hb=70c3470408854526136adcf3705d1dc7e7189c0a;hp=0000000000000000000000000000000000000000;hpb=d3846c6fda2eb17ccd0402551be8b569ab2dbc5a;p=apitrace diff --git a/thirdparty/less/optfunc.c b/thirdparty/less/optfunc.c new file mode 100644 index 0000000..a0aa10a --- /dev/null +++ b/thirdparty/less/optfunc.c @@ -0,0 +1,707 @@ +/* + * Copyright (C) 1984-2011 Mark Nudelman + * + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. + * + * For more information about less, or for information on how to + * contact the author, see the README file. + */ + + +/* + * Handling functions for command line options. + * + * Most options are handled by the generic code in option.c. + * But all string options, and a few non-string options, require + * special handling specific to the particular option. + * This special processing is done by the "handling functions" in this file. + * + * Each handling function is passed a "type" and, if it is a string + * option, the string which should be "assigned" to the option. + * The type may be one of: + * INIT The option is being initialized from the command line. + * TOGGLE The option is being changed from within the program. + * QUERY The setting of the option is merely being queried. + */ + +#include "less.h" +#include "option.h" + +extern int nbufs; +extern int bufspace; +extern int pr_type; +extern int plusoption; +extern int swindow; +extern int sc_width; +extern int sc_height; +extern int secure; +extern int dohelp; +extern int any_display; +extern char openquote; +extern char closequote; +extern char *prproto[]; +extern char *eqproto; +extern char *hproto; +extern char *wproto; +extern IFILE curr_ifile; +extern char version[]; +extern int jump_sline; +extern int jump_sline_fraction; +extern int shift_count; +extern int shift_count_fraction; +extern int less_is_more; +#if LOGFILE +extern char *namelogfile; +extern int force_logfile; +extern int logfile; +#endif +#if TAGS +public char *tagoption = NULL; +extern char *tags; +#endif +#if MSDOS_COMPILER +extern int nm_fg_color, nm_bg_color; +extern int bo_fg_color, bo_bg_color; +extern int ul_fg_color, ul_bg_color; +extern int so_fg_color, so_bg_color; +extern int bl_fg_color, bl_bg_color; +#endif + + +#if LOGFILE +/* + * Handler for -o option. + */ + public void +opt_o(type, s) + int type; + char *s; +{ + PARG parg; + + if (secure) + { + error("log file support is not available", NULL_PARG); + return; + } + switch (type) + { + case INIT: + namelogfile = s; + break; + case TOGGLE: + if (ch_getflags() & CH_CANSEEK) + { + error("Input is not a pipe", NULL_PARG); + return; + } + if (logfile >= 0) + { + error("Log file is already in use", NULL_PARG); + return; + } + s = skipsp(s); + namelogfile = lglob(s); + use_logfile(namelogfile); + sync_logfile(); + break; + case QUERY: + if (logfile < 0) + error("No log file", NULL_PARG); + else + { + parg.p_string = namelogfile; + error("Log file \"%s\"", &parg); + } + break; + } +} + +/* + * Handler for -O option. + */ + public void +opt__O(type, s) + int type; + char *s; +{ + force_logfile = TRUE; + opt_o(type, s); +} +#endif + +/* + * Handlers for -j option. + */ + public void +opt_j(type, s) + int type; + char *s; +{ + PARG parg; + char buf[16]; + int len; + int err; + + switch (type) + { + case INIT: + case TOGGLE: + if (*s == '.') + { + s++; + jump_sline_fraction = getfraction(&s, "j", &err); + if (err) + error("Invalid line fraction", NULL_PARG); + else + calc_jump_sline(); + } else + { + int sline = getnum(&s, "j", &err); + if (err) + error("Invalid line number", NULL_PARG); + else + { + jump_sline = sline; + jump_sline_fraction = -1; + } + } + break; + case QUERY: + if (jump_sline_fraction < 0) + { + parg.p_int = jump_sline; + error("Position target at screen line %d", &parg); + } else + { + + sprintf(buf, ".%06d", jump_sline_fraction); + len = strlen(buf); + while (len > 2 && buf[len-1] == '0') + len--; + buf[len] = '\0'; + parg.p_string = buf; + error("Position target at screen position %s", &parg); + } + break; + } +} + + public void +calc_jump_sline() +{ + if (jump_sline_fraction < 0) + return; + jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM; +} + +/* + * Handlers for -# option. + */ + public void +opt_shift(type, s) + int type; + char *s; +{ + PARG parg; + char buf[16]; + int len; + int err; + + switch (type) + { + case INIT: + case TOGGLE: + if (*s == '.') + { + s++; + shift_count_fraction = getfraction(&s, "#", &err); + if (err) + error("Invalid column fraction", NULL_PARG); + else + calc_shift_count(); + } else + { + int hs = getnum(&s, "#", &err); + if (err) + error("Invalid column number", NULL_PARG); + else + { + shift_count = hs; + shift_count_fraction = -1; + } + } + break; + case QUERY: + if (shift_count_fraction < 0) + { + parg.p_int = shift_count; + error("Horizontal shift %d columns", &parg); + } else + { + + sprintf(buf, ".%06d", shift_count_fraction); + len = strlen(buf); + while (len > 2 && buf[len-1] == '0') + len--; + buf[len] = '\0'; + parg.p_string = buf; + error("Horizontal shift %s of screen width", &parg); + } + break; + } +} + public void +calc_shift_count() +{ + if (shift_count_fraction < 0) + return; + shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM; +} + +#if USERFILE + public void +opt_k(type, s) + int type; + char *s; +{ + PARG parg; + + switch (type) + { + case INIT: + if (lesskey(s, 0)) + { + parg.p_string = s; + error("Cannot use lesskey file \"%s\"", &parg); + } + break; + } +} +#endif + +#if TAGS +/* + * Handler for -t option. + */ + public void +opt_t(type, s) + int type; + char *s; +{ + IFILE save_ifile; + POSITION pos; + + switch (type) + { + case INIT: + tagoption = s; + /* Do the rest in main() */ + break; + case TOGGLE: + if (secure) + { + error("tags support is not available", NULL_PARG); + break; + } + findtag(skipsp(s)); + save_ifile = save_curr_ifile(); + /* + * Try to open the file containing the tag + * and search for the tag in that file. + */ + if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION) + { + /* Failed: reopen the old file. */ + reedit_ifile(save_ifile); + break; + } + unsave_ifile(save_ifile); + jump_loc(pos, jump_sline); + break; + } +} + +/* + * Handler for -T option. + */ + public void +opt__T(type, s) + int type; + char *s; +{ + PARG parg; + + switch (type) + { + case INIT: + tags = s; + break; + case TOGGLE: + s = skipsp(s); + tags = lglob(s); + break; + case QUERY: + parg.p_string = tags; + error("Tags file \"%s\"", &parg); + break; + } +} +#endif + +/* + * Handler for -p option. + */ + public void +opt_p(type, s) + int type; + register char *s; +{ + switch (type) + { + case INIT: + /* + * Unget a search command for the specified string. + * {{ This won't work if the "/" command is + * changed or invalidated by a .lesskey file. }} + */ + plusoption = TRUE; + ungetsc(s); + /* + * In "more" mode, the -p argument is a command, + * not a search string, so we don't need a slash. + */ + if (!less_is_more) + ungetsc("/"); + break; + } +} + +/* + * Handler for -P option. + */ + public void +opt__P(type, s) + int type; + register char *s; +{ + register char **proto; + PARG parg; + + switch (type) + { + case INIT: + case TOGGLE: + /* + * Figure out which prototype string should be changed. + */ + switch (*s) + { + case 's': proto = &prproto[PR_SHORT]; s++; break; + case 'm': proto = &prproto[PR_MEDIUM]; s++; break; + case 'M': proto = &prproto[PR_LONG]; s++; break; + case '=': proto = &eqproto; s++; break; + case 'h': proto = &hproto; s++; break; + case 'w': proto = &wproto; s++; break; + default: proto = &prproto[PR_SHORT]; break; + } + free(*proto); + *proto = save(s); + break; + case QUERY: + parg.p_string = prproto[pr_type]; + error("%s", &parg); + break; + } +} + +/* + * Handler for the -b option. + */ + /*ARGSUSED*/ + public void +opt_b(type, s) + int type; + char *s; +{ + switch (type) + { + case INIT: + case TOGGLE: + /* + * Set the new number of buffers. + */ + ch_setbufspace(bufspace); + break; + case QUERY: + break; + } +} + +/* + * Handler for the -i option. + */ + /*ARGSUSED*/ + public void +opt_i(type, s) + int type; + char *s; +{ + switch (type) + { + case TOGGLE: + chg_caseless(); + break; + case QUERY: + case INIT: + break; + } +} + +/* + * Handler for the -V option. + */ + /*ARGSUSED*/ + public void +opt__V(type, s) + int type; + char *s; +{ + switch (type) + { + case TOGGLE: + case QUERY: + dispversion(); + break; + case INIT: + /* + * Force output to stdout per GNU standard for --version output. + */ + any_display = 1; + putstr("less "); + putstr(version); + putstr("\nCopyright (C) 1984-2009 Mark Nudelman\n\n"); + putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); + putstr("For information about the terms of redistribution,\n"); + putstr("see the file named README in the less distribution.\n"); + putstr("Homepage: http://www.greenwoodsoftware.com/less\n"); + quit(QUIT_OK); + break; + } +} + +#if MSDOS_COMPILER +/* + * Parse an MSDOS color descriptor. + */ + static void +colordesc(s, fg_color, bg_color) + char *s; + int *fg_color; + int *bg_color; +{ + int fg, bg; + int err; + + fg = getnum(&s, "D", &err); + if (err) + { + error("Missing fg color in -D", NULL_PARG); + return; + } + if (*s != '.') + bg = nm_bg_color; + else + { + s++; + bg = getnum(&s, "D", &err); + if (err) + { + error("Missing bg color in -D", NULL_PARG); + return; + } + } + if (*s != '\0') + error("Extra characters at end of -D option", NULL_PARG); + *fg_color = fg; + *bg_color = bg; +} + +/* + * Handler for the -D option. + */ + /*ARGSUSED*/ + public void +opt_D(type, s) + int type; + char *s; +{ + switch (type) + { + case INIT: + case TOGGLE: + switch (*s++) + { + case 'n': + colordesc(s, &nm_fg_color, &nm_bg_color); + break; + case 'd': + colordesc(s, &bo_fg_color, &bo_bg_color); + break; + case 'u': + colordesc(s, &ul_fg_color, &ul_bg_color); + break; + case 'k': + colordesc(s, &bl_fg_color, &bl_bg_color); + break; + case 's': + colordesc(s, &so_fg_color, &so_bg_color); + break; + default: + error("-D must be followed by n, d, u, k or s", NULL_PARG); + break; + } + if (type == TOGGLE) + { + at_enter(AT_STANDOUT); + at_exit(); + } + break; + case QUERY: + break; + } +} +#endif + +/* + * Handler for the -x option. + */ + public void +opt_x(type, s) + int type; + register char *s; +{ + extern int tabstops[]; + extern int ntabstops; + extern int tabdefault; + char msg[60+(4*TABSTOP_MAX)]; + int i; + PARG p; + + switch (type) + { + case INIT: + case TOGGLE: + /* Start at 1 because tabstops[0] is always zero. */ + for (i = 1; i < TABSTOP_MAX; ) + { + int n = 0; + s = skipsp(s); + while (*s >= '0' && *s <= '9') + n = (10 * n) + (*s++ - '0'); + if (n > tabstops[i-1]) + tabstops[i++] = n; + s = skipsp(s); + if (*s++ != ',') + break; + } + if (i < 2) + return; + ntabstops = i; + tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2]; + break; + case QUERY: + strcpy(msg, "Tab stops "); + if (ntabstops > 2) + { + for (i = 1; i < ntabstops; i++) + { + if (i > 1) + strcat(msg, ","); + sprintf(msg+strlen(msg), "%d", tabstops[i]); + } + sprintf(msg+strlen(msg), " and then "); + } + sprintf(msg+strlen(msg), "every %d spaces", + tabdefault); + p.p_string = msg; + error("%s", &p); + break; + } +} + + +/* + * Handler for the -" option. + */ + public void +opt_quote(type, s) + int type; + register char *s; +{ + char buf[3]; + PARG parg; + + switch (type) + { + case INIT: + case TOGGLE: + if (s[0] == '\0') + { + openquote = closequote = '\0'; + break; + } + if (s[1] != '\0' && s[2] != '\0') + { + error("-\" must be followed by 1 or 2 chars", NULL_PARG); + return; + } + openquote = s[0]; + if (s[1] == '\0') + closequote = openquote; + else + closequote = s[1]; + break; + case QUERY: + buf[0] = openquote; + buf[1] = closequote; + buf[2] = '\0'; + parg.p_string = buf; + error("quotes %s", &parg); + break; + } +} + +/* + * "-?" means display a help message. + * If from the command line, exit immediately. + */ + /*ARGSUSED*/ + public void +opt_query(type, s) + int type; + char *s; +{ + switch (type) + { + case QUERY: + case TOGGLE: + error("Use \"h\" for help", NULL_PARG); + break; + case INIT: + dohelp = 1; + } +} + +/* + * Get the "screen window" size. + */ + public int +get_swindow() +{ + if (swindow > 0) + return (swindow); + return (sc_height + swindow); +} +