version 1.9, 2014/04/25 13:38:21 |
version 1.10, 2015/11/05 22:08:44 |
|
|
* |
* |
* For more information, see the README file. |
* For more information, see the README file. |
*/ |
*/ |
|
/* |
|
* Modified for use with illumos. |
|
* Copyright 2014 Garrett D'Amore <garrett@damore.org> |
|
*/ |
|
|
|
|
/* |
/* |
* Handling functions for command line options. |
* Handling functions for command line options. |
* |
* |
|
|
#include "less.h" |
#include "less.h" |
#include "option.h" |
#include "option.h" |
|
|
extern int nbufs; |
|
extern int bufspace; |
extern int bufspace; |
extern int pr_type; |
extern int pr_type; |
extern int plusoption; |
extern int plusoption; |
|
|
extern char version[]; |
extern char version[]; |
extern int jump_sline; |
extern int jump_sline; |
extern int jump_sline_fraction; |
extern int jump_sline_fraction; |
extern int shift_count; |
|
extern int shift_count_fraction; |
|
extern int less_is_more; |
extern int less_is_more; |
#if LOGFILE |
|
extern char *namelogfile; |
extern char *namelogfile; |
extern int force_logfile; |
extern int force_logfile; |
extern int logfile; |
extern int logfile; |
#endif |
char *tagoption = NULL; |
#if TAGS |
|
public char *tagoption = NULL; |
|
extern char *tags; |
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 |
|
extern char *every_first_cmd; |
|
|
|
|
int shift_count; /* Number of positions to shift horizontally */ |
|
static int shift_count_fraction = -1; |
|
|
#if LOGFILE |
|
/* |
/* |
* Handler for -o option. |
* Handler for -o option. |
*/ |
*/ |
public void |
void |
opt_o(type, s) |
opt_o(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
PARG parg; |
PARG parg; |
|
|
if (secure) |
if (secure) { |
{ |
|
error("log file support is not available", NULL_PARG); |
error("log file support is not available", NULL_PARG); |
return; |
return; |
} |
} |
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
namelogfile = s; |
namelogfile = s; |
break; |
break; |
case TOGGLE: |
case TOGGLE: |
if (ch_getflags() & CH_CANSEEK) |
if (ch_getflags() & CH_CANSEEK) { |
{ |
|
error("Input is not a pipe", NULL_PARG); |
error("Input is not a pipe", NULL_PARG); |
return; |
return; |
} |
} |
if (logfile >= 0) |
if (logfile >= 0) { |
{ |
|
error("Log file is already in use", NULL_PARG); |
error("Log file is already in use", NULL_PARG); |
return; |
return; |
} |
} |
|
|
sync_logfile(); |
sync_logfile(); |
break; |
break; |
case QUERY: |
case QUERY: |
if (logfile < 0) |
if (logfile < 0) { |
error("No log file", NULL_PARG); |
error("No log file", NULL_PARG); |
else |
} else { |
{ |
|
parg.p_string = namelogfile; |
parg.p_string = namelogfile; |
error("Log file \"%s\"", &parg); |
error("Log file \"%s\"", &parg); |
} |
} |
|
|
/* |
/* |
* Handler for -O option. |
* Handler for -O option. |
*/ |
*/ |
public void |
void |
opt__O(type, s) |
opt__O(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
force_logfile = TRUE; |
force_logfile = TRUE; |
opt_o(type, s); |
opt_o(type, s); |
} |
} |
#endif |
|
|
|
/* |
/* |
* Handlers for -j option. |
* Handlers for -j option. |
*/ |
*/ |
public void |
void |
opt_j(type, s) |
opt_j(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
PARG parg; |
PARG parg; |
char buf[16]; |
char buf[16]; |
int len; |
int len; |
int err; |
int err; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
case TOGGLE: |
case TOGGLE: |
if (*s == '.') |
if (*s == '.') { |
{ |
|
s++; |
s++; |
jump_sline_fraction = getfraction(&s, "j", &err); |
jump_sline_fraction = getfraction(&s, "j", &err); |
if (err) |
if (err) |
error("Invalid line fraction", NULL_PARG); |
error("Invalid line fraction", NULL_PARG); |
else |
else |
calc_jump_sline(); |
calc_jump_sline(); |
} else |
} else { |
{ |
|
int sline = getnum(&s, "j", &err); |
int sline = getnum(&s, "j", &err); |
if (err) |
if (err) { |
error("Invalid line number", NULL_PARG); |
error("Invalid line number", NULL_PARG); |
else |
} else { |
{ |
|
jump_sline = sline; |
jump_sline = sline; |
jump_sline_fraction = -1; |
jump_sline_fraction = -1; |
} |
} |
} |
} |
break; |
break; |
case QUERY: |
case QUERY: |
if (jump_sline_fraction < 0) |
if (jump_sline_fraction < 0) { |
{ |
|
parg.p_int = jump_sline; |
parg.p_int = jump_sline; |
error("Position target at screen line %d", &parg); |
error("Position target at screen line %d", &parg); |
} else |
} else { |
{ |
(void) snprintf(buf, sizeof (buf), ".%06d", |
|
jump_sline_fraction); |
snprintf(buf, sizeof(buf), ".%06d", jump_sline_fraction); |
|
len = strlen(buf); |
len = strlen(buf); |
while (len > 2 && buf[len-1] == '0') |
while (len > 2 && buf[len-1] == '0') |
len--; |
len--; |
|
|
} |
} |
} |
} |
|
|
public void |
void |
calc_jump_sline() |
calc_jump_sline(void) |
{ |
{ |
if (jump_sline_fraction < 0) |
if (jump_sline_fraction < 0) |
return; |
return; |
|
|
/* |
/* |
* Handlers for -# option. |
* Handlers for -# option. |
*/ |
*/ |
public void |
void |
opt_shift(type, s) |
opt_shift(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
PARG parg; |
PARG parg; |
char buf[16]; |
char buf[16]; |
int len; |
int len; |
int err; |
int err; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
case TOGGLE: |
case TOGGLE: |
if (*s == '.') |
if (*s == '.') { |
{ |
|
s++; |
s++; |
shift_count_fraction = getfraction(&s, "#", &err); |
shift_count_fraction = getfraction(&s, "#", &err); |
if (err) |
if (err) |
error("Invalid column fraction", NULL_PARG); |
error("Invalid column fraction", NULL_PARG); |
else |
else |
calc_shift_count(); |
calc_shift_count(); |
} else |
} else { |
{ |
|
int hs = getnum(&s, "#", &err); |
int hs = getnum(&s, "#", &err); |
if (err) |
if (err) { |
error("Invalid column number", NULL_PARG); |
error("Invalid column number", NULL_PARG); |
else |
} else { |
{ |
|
shift_count = hs; |
shift_count = hs; |
shift_count_fraction = -1; |
shift_count_fraction = -1; |
} |
} |
} |
} |
break; |
break; |
case QUERY: |
case QUERY: |
if (shift_count_fraction < 0) |
if (shift_count_fraction < 0) { |
{ |
|
parg.p_int = shift_count; |
parg.p_int = shift_count; |
error("Horizontal shift %d columns", &parg); |
error("Horizontal shift %d columns", &parg); |
} else |
} else { |
{ |
|
|
|
snprintf(buf, sizeof(buf), ".%06d", shift_count_fraction); |
(void) snprintf(buf, sizeof (buf), ".%06d", |
|
shift_count_fraction); |
len = strlen(buf); |
len = strlen(buf); |
while (len > 2 && buf[len-1] == '0') |
while (len > 2 && buf[len-1] == '0') |
len--; |
len--; |
|
|
break; |
break; |
} |
} |
} |
} |
public void |
|
calc_shift_count() |
void |
|
calc_shift_count(void) |
{ |
{ |
if (shift_count_fraction < 0) |
if (shift_count_fraction < 0) |
return; |
return; |
shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM; |
shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM; |
} |
} |
|
|
#if USERFILE |
void |
public void |
opt_k(int type, char *s) |
opt_k(type, s) |
|
int type; |
|
char *s; |
|
{ |
{ |
PARG parg; |
PARG parg; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
if (lesskey(s, 0)) |
if (lesskey(s, 0)) { |
{ |
|
parg.p_string = s; |
parg.p_string = s; |
error("Cannot use lesskey file \"%s\"", &parg); |
error("Cannot use lesskey file \"%s\"", &parg); |
} |
} |
break; |
break; |
} |
} |
} |
} |
#endif |
|
|
|
#if TAGS |
|
/* |
/* |
* Handler for -t option. |
* Handler for -t option. |
*/ |
*/ |
public void |
void |
opt_t(type, s) |
opt_t(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
IFILE save_ifile; |
IFILE save_ifile; |
POSITION pos; |
off_t pos; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
tagoption = s; |
tagoption = s; |
/* Do the rest in main() */ |
/* Do the rest in main() */ |
break; |
break; |
case TOGGLE: |
case TOGGLE: |
if (secure) |
if (secure) { |
{ |
|
error("tags support is not available", NULL_PARG); |
error("tags support is not available", NULL_PARG); |
break; |
break; |
} |
} |
|
|
* Try to open the file containing the tag |
* Try to open the file containing the tag |
* and search for the tag in that file. |
* and search for the tag in that file. |
*/ |
*/ |
if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION) |
if (edit_tagfile() || (pos = tagsearch()) == -1) { |
{ |
|
/* Failed: reopen the old file. */ |
/* Failed: reopen the old file. */ |
reedit_ifile(save_ifile); |
reedit_ifile(save_ifile); |
break; |
break; |
|
|
/* |
/* |
* Handler for -T option. |
* Handler for -T option. |
*/ |
*/ |
public void |
void |
opt__T(type, s) |
opt__T(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
PARG parg; |
PARG parg; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
tags = s; |
tags = s; |
break; |
break; |
|
|
break; |
break; |
} |
} |
} |
} |
#endif |
|
|
|
/* |
/* |
* Handler for -p option. |
* Handler for -p option. |
*/ |
*/ |
public void |
void |
opt_p(type, s) |
opt_p(int type, char *s) |
int type; |
|
register char *s; |
|
{ |
{ |
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
/* |
/* |
* Unget a search command for the specified string. |
* Unget a search command for the specified string. |
* {{ This won't work if the "/" command is |
* {{ This won't work if the "/" command is |
* changed or invalidated by a .lesskey file. }} |
* changed or invalidated by a .lesskey file. }} |
*/ |
*/ |
if (less_is_more) { |
plusoption = TRUE; |
/* |
ungetsc(s); |
* In "more" mode, the -p argument is a command, |
/* |
* not a search string, run for each file. |
* In "more" mode, the -p argument is a command, |
*/ |
* not a search string, so we don't need a slash. |
every_first_cmd = save(s); |
*/ |
} else { |
if (!less_is_more) |
plusoption = TRUE; |
|
ungetsc(s); |
|
ungetsc("/"); |
ungetsc("/"); |
} |
|
break; |
break; |
} |
} |
} |
} |
|
|
/* |
/* |
* Handler for -P option. |
* Handler for -P option. |
*/ |
*/ |
public void |
void |
opt__P(type, s) |
opt__P(int type, char *s) |
int type; |
|
register char *s; |
|
{ |
{ |
register char **proto; |
char **proto; |
PARG parg; |
PARG parg; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
case TOGGLE: |
case TOGGLE: |
/* |
/* |
* Figure out which prototype string should be changed. |
* Figure out which prototype string should be changed. |
*/ |
*/ |
switch (*s) |
switch (*s) { |
{ |
|
case 's': proto = &prproto[PR_SHORT]; s++; break; |
case 's': proto = &prproto[PR_SHORT]; s++; break; |
case 'm': proto = &prproto[PR_MEDIUM]; s++; break; |
case 'm': proto = &prproto[PR_MEDIUM]; s++; break; |
case 'M': proto = &prproto[PR_LONG]; s++; break; |
case 'M': proto = &prproto[PR_LONG]; s++; break; |
|
|
/* |
/* |
* Handler for the -b option. |
* Handler for the -b option. |
*/ |
*/ |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
public void |
void |
opt_b(type, s) |
opt_b(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
case TOGGLE: |
case TOGGLE: |
/* |
/* |
|
|
/* |
/* |
* Handler for the -i option. |
* Handler for the -i option. |
*/ |
*/ |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
public void |
void |
opt_i(type, s) |
opt_i(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
switch (type) |
switch (type) { |
{ |
|
case TOGGLE: |
case TOGGLE: |
chg_caseless(); |
chg_caseless(); |
break; |
break; |
|
|
/* |
/* |
* Handler for the -V option. |
* Handler for the -V option. |
*/ |
*/ |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
public void |
void |
opt__V(type, s) |
opt__V(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
switch (type) |
switch (type) { |
{ |
|
case TOGGLE: |
case TOGGLE: |
case QUERY: |
case QUERY: |
dispversion(); |
dispversion(); |
|
|
putstr("less "); |
putstr("less "); |
putstr(version); |
putstr(version); |
putstr(" ("); |
putstr(" ("); |
#if HAVE_GNU_REGEX |
|
putstr("GNU "); |
|
#endif |
|
#if HAVE_POSIX_REGCOMP |
|
putstr("POSIX "); |
putstr("POSIX "); |
#endif |
|
#if HAVE_PCRE |
|
putstr("PCRE "); |
|
#endif |
|
#if HAVE_RE_COMP |
|
putstr("BSD "); |
|
#endif |
|
#if HAVE_REGCMP |
|
putstr("V8 "); |
|
#endif |
|
#if HAVE_V8_REGCOMP |
|
putstr("Spencer V8 "); |
|
#endif |
|
#if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP |
|
putstr("no "); |
|
#endif |
|
putstr("regular expressions)\n"); |
putstr("regular expressions)\n"); |
putstr("Copyright (C) 1984-2012 Mark Nudelman\n\n"); |
putstr("Copyright (C) 1984-2012 Mark Nudelman\n\n"); |
putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); |
putstr("less comes with NO WARRANTY, "); |
|
putstr("to the extent permitted by law.\n"); |
putstr("For information about the terms of redistribution,\n"); |
putstr("For information about the terms of redistribution,\n"); |
putstr("see the file named README in the less distribution.\n"); |
putstr("see the file named README in the less distribution.\n"); |
putstr("Homepage: http://www.greenwoodsoftware.com/less\n"); |
putstr("Homepage: http://www.greenwoodsoftware.com/less\n"); |
|
putstr("\n"); |
|
putstr("Modified for use with illumos.\n"); |
|
putstr("Copyright 2014 Garrett D'Amore\n"); |
quit(QUIT_OK); |
quit(QUIT_OK); |
break; |
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. |
* Handler for the -x option. |
*/ |
*/ |
public void |
void |
opt_x(type, s) |
opt_x(int type, char *s) |
int type; |
|
register char *s; |
|
{ |
{ |
extern int tabstops[]; |
extern int tabstops[]; |
extern int ntabstops; |
extern int ntabstops; |
|
|
int i; |
int i; |
PARG p; |
PARG p; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
case TOGGLE: |
case TOGGLE: |
/* Start at 1 because tabstops[0] is always zero. */ |
/* Start at 1 because tabstops[0] is always zero. */ |
for (i = 1; i < TABSTOP_MAX; ) |
for (i = 1; i < TABSTOP_MAX; ) { |
{ |
|
int n = 0; |
int n = 0; |
s = skipsp(s); |
s = skipsp(s); |
while (*s >= '0' && *s <= '9') |
while (*s >= '0' && *s <= '9') |
|
|
tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2]; |
tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2]; |
break; |
break; |
case QUERY: |
case QUERY: |
strlcpy(msg, "Tab stops ", sizeof(msg)); |
(void) strlcpy(msg, "Tab stops ", sizeof(msg)); |
if (ntabstops > 2) |
if (ntabstops > 2) { |
{ |
for (i = 1; i < ntabstops; i++) { |
for (i = 1; i < ntabstops; i++) |
|
{ |
|
if (i > 1) |
if (i > 1) |
strlcat(msg, ",", sizeof(msg)); |
strlcat(msg, ",", sizeof(msg)); |
snprintf(msg+strlen(msg), |
(void) snprintf(msg+strlen(msg), |
sizeof(msg)-strlen(msg), "%d", tabstops[i]); |
sizeof(msg)-strlen(msg), "%d", tabstops[i]); |
} |
} |
snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), |
(void) snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), |
" and then "); |
" and then "); |
} |
} |
snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), |
(void) snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), |
"every %d spaces", tabdefault); |
"every %d spaces", tabdefault); |
p.p_string = msg; |
p.p_string = msg; |
error("%s", &p); |
error("%s", &p); |
|
|
/* |
/* |
* Handler for the -" option. |
* Handler for the -" option. |
*/ |
*/ |
public void |
void |
opt_quote(type, s) |
opt_quote(int type, char *s) |
int type; |
|
register char *s; |
|
{ |
{ |
char buf[3]; |
char buf[3]; |
PARG parg; |
PARG parg; |
|
|
switch (type) |
switch (type) { |
{ |
|
case INIT: |
case INIT: |
case TOGGLE: |
case TOGGLE: |
if (s[0] == '\0') |
if (s[0] == '\0') { |
{ |
|
openquote = closequote = '\0'; |
openquote = closequote = '\0'; |
break; |
break; |
} |
} |
if (s[1] != '\0' && s[2] != '\0') |
if (s[1] != '\0' && s[2] != '\0') { |
{ |
error("-\" must be followed by 1 or 2 chars", |
error("-\" must be followed by 1 or 2 chars", NULL_PARG); |
NULL_PARG); |
return; |
return; |
} |
} |
openquote = s[0]; |
openquote = s[0]; |
|
|
* "-?" means display a help message. |
* "-?" means display a help message. |
* If from the command line, exit immediately. |
* If from the command line, exit immediately. |
*/ |
*/ |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
public void |
void |
opt_query(type, s) |
opt_query(int type, char *s) |
int type; |
|
char *s; |
|
{ |
{ |
switch (type) |
switch (type) { |
{ |
|
case QUERY: |
case QUERY: |
case TOGGLE: |
case TOGGLE: |
error("Use \"h\" for help", NULL_PARG); |
error("Use \"h\" for help", NULL_PARG); |
|
|
/* |
/* |
* Get the "screen window" size. |
* Get the "screen window" size. |
*/ |
*/ |
public int |
int |
get_swindow() |
get_swindow(void) |
{ |
{ |
if (swindow > 0) |
if (swindow > 0) |
return (swindow); |
return (swindow); |
return (sc_height + swindow); |
return (sc_height + swindow); |
} |
} |
|
|