version 1.1.1.1, 1996/09/21 05:39:41 |
version 1.1.1.2, 2003/04/13 18:21:21 |
|
|
/* |
/* |
* Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman |
* Copyright (C) 1984-2002 Mark Nudelman |
* All rights reserved. |
|
* |
* |
* Redistribution and use in source and binary forms, with or without |
* You may distribute under the terms of either the GNU General Public |
* modification, are permitted provided that the following conditions |
* License or the Less License, as specified in the README file. |
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice in the documentation and/or other materials provided with |
|
* the distribution. |
|
* |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY |
* For more information about less, or for information on how to |
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* contact the author, see the README file. |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
*/ |
|
|
|
|
|
|
*/ |
*/ |
|
|
#include "less.h" |
#include "less.h" |
#include "position.h" |
#if MSDOS_COMPILER==WIN32C |
|
#include <windows.h> |
|
#endif |
|
|
public char * every_first_cmd = NULL; |
public char * every_first_cmd = NULL; |
public int new_file; |
public int new_file; |
|
|
public IFILE old_ifile = NULL_IFILE; |
public IFILE old_ifile = NULL_IFILE; |
public struct scrpos initial_scrpos; |
public struct scrpos initial_scrpos; |
public int any_display = FALSE; |
public int any_display = FALSE; |
|
public POSITION start_attnpos = NULL_POSITION; |
|
public POSITION end_attnpos = NULL_POSITION; |
public int wscroll; |
public int wscroll; |
public char * progname; |
public char * progname; |
public int quitting; |
public int quitting; |
|
public int secure; |
|
public int dohelp; |
|
|
extern int quit_at_eof; |
|
extern int cbufs; |
|
extern int errmsgs; |
|
extern int screen_trashed; |
|
extern int force_open; |
|
|
|
#if LOGFILE |
#if LOGFILE |
public int logfile = -1; |
public int logfile = -1; |
public int force_logfile = FALSE; |
public int force_logfile = FALSE; |
|
|
#endif |
#endif |
|
|
#if TAGS |
#if TAGS |
extern char * tagfile; |
extern char * tags; |
extern char * tagoption; |
extern char * tagoption; |
extern int jump_sline; |
extern int jump_sline; |
#endif |
#endif |
|
|
|
#ifdef WIN32 |
|
static char consoleTitle[256]; |
|
#endif |
|
|
|
extern int missing_cap; |
|
extern int know_dumb; |
|
|
|
|
/* |
/* |
* Entry point. |
* Entry point. |
*/ |
*/ |
|
|
char *argv[]; |
char *argv[]; |
{ |
{ |
IFILE ifile; |
IFILE ifile; |
|
char *s; |
|
|
#ifdef __EMX__ |
#ifdef __EMX__ |
_response(&argc, &argv); |
_response(&argc, &argv); |
|
|
#endif |
#endif |
|
|
progname = *argv++; |
progname = *argv++; |
|
argc--; |
|
|
|
secure = 0; |
|
s = lgetenv("LESSSECURE"); |
|
if (s != NULL && *s != '\0') |
|
secure = 1; |
|
|
|
#ifdef WIN32 |
|
if (getenv("HOME") == NULL) |
|
{ |
|
/* |
|
* If there is no HOME environment variable, |
|
* try the concatenation of HOMEDRIVE + HOMEPATH. |
|
*/ |
|
char *drive = getenv("HOMEDRIVE"); |
|
char *path = getenv("HOMEPATH"); |
|
if (drive != NULL && path != NULL) |
|
{ |
|
char *env = (char *) ecalloc(strlen(drive) + |
|
strlen(path) + 6, sizeof(char)); |
|
strcpy(env, "HOME="); |
|
strcat(env, drive); |
|
strcat(env, path); |
|
putenv(env); |
|
} |
|
} |
|
GetConsoleTitle(consoleTitle, sizeof(consoleTitle)/sizeof(char)); |
|
#endif /* WIN32 */ |
|
|
/* |
/* |
* Process command line arguments and LESS environment arguments. |
* Process command line arguments and LESS environment arguments. |
* Command line arguments override environment arguments. |
* Command line arguments override environment arguments. |
*/ |
*/ |
|
is_tty = isatty(1); |
get_term(); |
get_term(); |
init_cmds(); |
init_cmds(); |
init_prompt(); |
init_prompt(); |
init_charset(); |
init_charset(); |
|
init_line(); |
init_option(); |
init_option(); |
scan_option(getenv("LESS")); |
s = lgetenv("LESS"); |
|
if (s != NULL) |
|
scan_option(save(s)); |
|
|
#if GNU_OPTIONS |
#define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0') |
/* |
while (argc > 0 && (isoptstring(*argv) || isoptpending())) |
* Special case for "less --help" and "less --version". |
|
*/ |
|
if (argc == 2) |
|
{ |
{ |
if (strcmp(argv[0], "--help") == 0) |
s = *argv++; |
scan_option("-?"); |
argc--; |
if (strcmp(argv[0], "--version") == 0) |
if (strcmp(s, "--") == 0) |
scan_option("-V"); |
break; |
|
scan_option(s); |
} |
} |
#endif |
|
#define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0') |
|
while (--argc > 0 && (isoptstring(argv[0]) || isoptpending())) |
|
scan_option(*argv++); |
|
#undef isoptstring |
#undef isoptstring |
|
|
if (isoptpending()) |
if (isoptpending()) |
|
|
} |
} |
|
|
#if EDITOR |
#if EDITOR |
editor = getenv("VISUAL"); |
editor = lgetenv("VISUAL"); |
if (editor == NULL || *editor == '\0') |
if (editor == NULL || *editor == '\0') |
{ |
{ |
editor = getenv("EDITOR"); |
editor = lgetenv("EDITOR"); |
if (editor == NULL || *editor == '\0') |
if (editor == NULL || *editor == '\0') |
editor = EDIT_PGM; |
editor = EDIT_PGM; |
} |
} |
editproto = getenv("LESSEDIT"); |
editproto = lgetenv("LESSEDIT"); |
if (editproto == NULL || *editproto == '\0') |
if (editproto == NULL || *editproto == '\0') |
editproto = "%E ?lm+%lm. %f"; |
editproto = "%E ?lm+%lm. %f"; |
#endif |
#endif |
|
|
* to "register" them with the ifile system. |
* to "register" them with the ifile system. |
*/ |
*/ |
ifile = NULL_IFILE; |
ifile = NULL_IFILE; |
while (--argc >= 0) |
if (dohelp) |
|
ifile = get_ifile(FAKE_HELPFILE, ifile); |
|
while (argc-- > 0) |
{ |
{ |
#if MSOFTC || OS2 |
char *filename; |
|
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) |
/* |
/* |
* Because the "shell" doesn't expand filename patterns, |
* Because the "shell" doesn't expand filename patterns, |
* treat each argument as a filename pattern rather than |
* treat each argument as a filename pattern rather than |
|
|
*/ |
*/ |
struct textlist tlist; |
struct textlist tlist; |
char *gfilename; |
char *gfilename; |
char *filename; |
|
|
|
gfilename = glob(*argv++); |
gfilename = lglob(*argv++); |
init_textlist(&tlist, gfilename); |
init_textlist(&tlist, gfilename); |
filename = NULL; |
filename = NULL; |
while ((filename = forw_textlist(&tlist, filename)) != NULL) |
while ((filename = forw_textlist(&tlist, filename)) != NULL) |
ifile = get_ifile(filename, ifile); |
{ |
|
(void) get_ifile(filename, ifile); |
|
ifile = prev_ifile(NULL_IFILE); |
|
} |
free(gfilename); |
free(gfilename); |
#else |
#else |
ifile = get_ifile(*argv++, ifile); |
filename = shell_quote(*argv); |
|
if (filename == NULL) |
|
filename = *argv; |
|
argv++; |
|
(void) get_ifile(filename, ifile); |
|
ifile = prev_ifile(NULL_IFILE); |
#endif |
#endif |
} |
} |
/* |
/* |
* Set up terminal, etc. |
* Set up terminal, etc. |
*/ |
*/ |
is_tty = isatty(1); |
|
if (!is_tty) |
if (!is_tty) |
{ |
{ |
/* |
/* |
* Output is not a tty. |
* Output is not a tty. |
* Just copy the input file(s) to output. |
* Just copy the input file(s) to output. |
*/ |
*/ |
|
SET_BINARY(1); |
if (nifile() == 0) |
if (nifile() == 0) |
{ |
{ |
if (edit_stdin() == 0) |
if (edit_stdin() == 0) |
|
|
quit(QUIT_OK); |
quit(QUIT_OK); |
} |
} |
|
|
|
if (missing_cap && !know_dumb) |
|
error("WARNING: terminal is not fully functional", NULL_PARG); |
init_mark(); |
init_mark(); |
raw_mode(1); |
|
open_getchr(); |
open_getchr(); |
|
raw_mode(1); |
init_signals(1); |
init_signals(1); |
|
|
/* |
/* |
* Select the first file to examine. |
* Select the first file to examine. |
*/ |
*/ |
#if TAGS |
#if TAGS |
if (tagoption != NULL) |
if (tagoption != NULL || strcmp(tags, "-") == 0) |
{ |
{ |
/* |
/* |
* A -t option was given. |
* A -t option was given. |
|
|
quit(QUIT_ERROR); |
quit(QUIT_ERROR); |
} |
} |
findtag(tagoption); |
findtag(tagoption); |
if (tagfile == NULL) |
if (edit_tagfile()) /* Edit file which contains the tag */ |
quit(QUIT_ERROR); |
quit(QUIT_ERROR); |
if (edit(tagfile)) /* Edit file which contains the tag */ |
|
quit(QUIT_ERROR); |
|
/* |
/* |
* Search for the line which contains the tag. |
* Search for the line which contains the tag. |
* Set up initial_scrpos so we display that line. |
* Set up initial_scrpos so we display that line. |
|
|
commands(); |
commands(); |
quit(QUIT_OK); |
quit(QUIT_OK); |
/*NOTREACHED*/ |
/*NOTREACHED*/ |
|
return (0); |
} |
} |
|
|
/* |
/* |
* Copy a string, truncating to the specified length if necessary. |
|
* Unlike strncpy(), the resulting string is guaranteed to be null-terminated. |
|
*/ |
|
public void |
|
strtcpy(to, from, len) |
|
char *to; |
|
char *from; |
|
unsigned int len; |
|
{ |
|
strncpy(to, from, len); |
|
to[len-1] = '\0'; |
|
} |
|
|
|
/* |
|
* Copy a string to a "safe" place |
* Copy a string to a "safe" place |
* (that is, to a buffer allocated by calloc). |
* (that is, to a buffer allocated by calloc). |
*/ |
*/ |
|
|
error("Cannot allocate memory", NULL_PARG); |
error("Cannot allocate memory", NULL_PARG); |
quit(QUIT_ERROR); |
quit(QUIT_ERROR); |
/*NOTREACHED*/ |
/*NOTREACHED*/ |
|
return (NULL); |
} |
} |
|
|
/* |
/* |
|
|
} |
} |
|
|
/* |
/* |
|
* See how many characters of two strings are identical. |
|
* If uppercase is true, the first string must begin with an uppercase |
|
* character; the remainder of the first string may be either case. |
|
*/ |
|
public int |
|
sprefix(ps, s, uppercase) |
|
char *ps; |
|
char *s; |
|
int uppercase; |
|
{ |
|
register int c; |
|
register int sc; |
|
register int len = 0; |
|
|
|
for ( ; *s != '\0'; s++, ps++) |
|
{ |
|
c = *ps; |
|
if (uppercase) |
|
{ |
|
if (len == 0 && SIMPLE_IS_LOWER(c)) |
|
return (-1); |
|
if (SIMPLE_IS_UPPER(c)) |
|
c = SIMPLE_TO_LOWER(c); |
|
} |
|
sc = *s; |
|
if (len > 0 && SIMPLE_IS_UPPER(sc)) |
|
sc = SIMPLE_TO_LOWER(sc); |
|
if (c != sc) |
|
break; |
|
len++; |
|
} |
|
return (len); |
|
} |
|
|
|
/* |
* Exit the program. |
* Exit the program. |
*/ |
*/ |
public void |
public void |
|
|
save_status = status; |
save_status = status; |
quitting = 1; |
quitting = 1; |
edit((char*)NULL); |
edit((char*)NULL); |
if (any_display) |
if (any_display && is_tty) |
clear_bot(); |
clear_bot(); |
deinit(); |
deinit(); |
flush(); |
flush(); |
raw_mode(0); |
raw_mode(0); |
#if MSOFTC |
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC |
/* |
/* |
* If we don't close 2, we get some garbage from |
* If we don't close 2, we get some garbage from |
* 2's buffer when it flushes automatically. |
* 2's buffer when it flushes automatically. |
|
|
*/ |
*/ |
close(2); |
close(2); |
#endif |
#endif |
|
#if WIN32 |
|
SetConsoleTitle(consoleTitle); |
|
#endif |
|
close_getchr(); |
exit(status); |
exit(status); |
} |
} |