X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=thirdparty%2Fless%2Fmain.c;fp=thirdparty%2Fless%2Fmain.c;h=0af176299f63891ba9e37bf54aecbcc797f0e64d;hb=70c3470408854526136adcf3705d1dc7e7189c0a;hp=0000000000000000000000000000000000000000;hpb=d3846c6fda2eb17ccd0402551be8b569ab2dbc5a;p=apitrace diff --git a/thirdparty/less/main.c b/thirdparty/less/main.c new file mode 100644 index 0000000..0af1762 --- /dev/null +++ b/thirdparty/less/main.c @@ -0,0 +1,414 @@ +/* + * 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. + */ + + +/* + * Entry point, initialization, miscellaneous routines. + */ + +#include "less.h" +#if MSDOS_COMPILER==WIN32C +#include +#endif + +public char * every_first_cmd = NULL; +public int new_file; +public int is_tty; +public IFILE curr_ifile = NULL_IFILE; +public IFILE old_ifile = NULL_IFILE; +public struct scrpos initial_scrpos; +public int any_display = FALSE; +public POSITION start_attnpos = NULL_POSITION; +public POSITION end_attnpos = NULL_POSITION; +public int wscroll; +public char * progname; +public int quitting; +public int secure; +public int dohelp; + +#if LOGFILE +public int logfile = -1; +public int force_logfile = FALSE; +public char * namelogfile = NULL; +#endif + +#if EDITOR +public char * editor; +public char * editproto; +#endif + +#if TAGS +extern char * tags; +extern char * tagoption; +extern int jump_sline; +#endif + +#ifdef WIN32 +static char consoleTitle[256]; +#endif + +extern int less_is_more; +extern int missing_cap; +extern int know_dumb; +extern int quit_if_one_screen; +extern int pr_type; + + +/* + * Entry point. + */ +int +main(argc, argv) + int argc; + char *argv[]; +{ + IFILE ifile; + char *s; + +#ifdef __EMX__ + _response(&argc, &argv); + _wildcard(&argc, &argv); +#endif + + 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. + * Command line arguments override environment arguments. + */ + is_tty = isatty(1); + get_term(); + init_cmds(); + init_charset(); + init_line(); + init_cmdhist(); + init_option(); + init_search(); + + /* + * If the name of the executable program is "more", + * act like LESS_IS_MORE is set. + */ + for (s = progname + strlen(progname); s > progname; s--) + { + if (s[-1] == PATHNAME_SEP[0]) + break; + } + if (strcmp(s, "more") == 0) + less_is_more = 1; + + init_prompt(); + + s = lgetenv(less_is_more ? "MORE" : "LESS"); + if (s != NULL) + scan_option(save(s)); + +#define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0') + while (argc > 0 && (isoptstring(*argv) || isoptpending())) + { + s = *argv++; + argc--; + if (strcmp(s, "--") == 0) + break; + scan_option(s); + } +#undef isoptstring + + if (isoptpending()) + { + /* + * Last command line option was a flag requiring a + * following string, but there was no following string. + */ + nopendopt(); + quit(QUIT_OK); + } + + if (less_is_more && get_quit_at_eof()) + quit_if_one_screen = TRUE; + +#if EDITOR + editor = lgetenv("VISUAL"); + if (editor == NULL || *editor == '\0') + { + editor = lgetenv("EDITOR"); + if (editor == NULL || *editor == '\0') + editor = EDIT_PGM; + } + editproto = lgetenv("LESSEDIT"); + if (editproto == NULL || *editproto == '\0') + editproto = "%E ?lm+%lm. %f"; +#endif + + /* + * Call get_ifile with all the command line filenames + * to "register" them with the ifile system. + */ + ifile = NULL_IFILE; + if (dohelp) + ifile = get_ifile(FAKE_HELPFILE, ifile); + while (argc-- > 0) + { + char *filename; +#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) + /* + * Because the "shell" doesn't expand filename patterns, + * treat each argument as a filename pattern rather than + * a single filename. + * Expand the pattern and iterate over the expanded list. + */ + struct textlist tlist; + char *gfilename; + + gfilename = lglob(*argv++); + init_textlist(&tlist, gfilename); + filename = NULL; + while ((filename = forw_textlist(&tlist, filename)) != NULL) + { + (void) get_ifile(filename, ifile); + ifile = prev_ifile(NULL_IFILE); + } + free(gfilename); +#else + filename = shell_quote(*argv); + if (filename == NULL) + filename = *argv; + argv++; + (void) get_ifile(filename, ifile); + ifile = prev_ifile(NULL_IFILE); +#endif + } + /* + * Set up terminal, etc. + */ + if (!is_tty) + { + /* + * Output is not a tty. + * Just copy the input file(s) to output. + */ + SET_BINARY(1); + if (nifile() == 0) + { + if (edit_stdin() == 0) + cat_file(); + } else if (edit_first() == 0) + { + do { + cat_file(); + } while (edit_next(1) == 0); + } + quit(QUIT_OK); + } + + if (missing_cap && !know_dumb) + error("WARNING: terminal is not fully functional", NULL_PARG); + init_mark(); + open_getchr(); + raw_mode(1); + init_signals(1); + + /* + * Select the first file to examine. + */ +#if TAGS + if (tagoption != NULL || strcmp(tags, "-") == 0) + { + /* + * A -t option was given. + * Verify that no filenames were also given. + * Edit the file selected by the "tags" search, + * and search for the proper line in the file. + */ + if (nifile() > 0) + { + error("No filenames allowed with -t option", NULL_PARG); + quit(QUIT_ERROR); + } + findtag(tagoption); + if (edit_tagfile()) /* Edit file which contains the tag */ + quit(QUIT_ERROR); + /* + * Search for the line which contains the tag. + * Set up initial_scrpos so we display that line. + */ + initial_scrpos.pos = tagsearch(); + if (initial_scrpos.pos == NULL_POSITION) + quit(QUIT_ERROR); + initial_scrpos.ln = jump_sline; + } else +#endif + if (nifile() == 0) + { + if (edit_stdin()) /* Edit standard input */ + quit(QUIT_ERROR); + } else + { + if (edit_first()) /* Edit first valid file in cmd line */ + quit(QUIT_ERROR); + } + + init(); + commands(); + quit(QUIT_OK); + /*NOTREACHED*/ + return (0); +} + +/* + * Copy a string to a "safe" place + * (that is, to a buffer allocated by calloc). + */ + public char * +save(s) + char *s; +{ + register char *p; + + p = (char *) ecalloc(strlen(s)+1, sizeof(char)); + strcpy(p, s); + return (p); +} + +/* + * Allocate memory. + * Like calloc(), but never returns an error (NULL). + */ + public VOID_POINTER +ecalloc(count, size) + int count; + unsigned int size; +{ + register VOID_POINTER p; + + p = (VOID_POINTER) calloc(count, size); + if (p != NULL) + return (p); + error("Cannot allocate memory", NULL_PARG); + quit(QUIT_ERROR); + /*NOTREACHED*/ + return (NULL); +} + +/* + * Skip leading spaces in a string. + */ + public char * +skipsp(s) + register char *s; +{ + while (*s == ' ' || *s == '\t') + s++; + return (s); +} + +/* + * 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 && ASCII_IS_LOWER(c)) + return (-1); + if (ASCII_IS_UPPER(c)) + c = ASCII_TO_LOWER(c); + } + sc = *s; + if (len > 0 && ASCII_IS_UPPER(sc)) + sc = ASCII_TO_LOWER(sc); + if (c != sc) + break; + len++; + } + return (len); +} + +/* + * Exit the program. + */ + public void +quit(status) + int status; +{ + static int save_status; + + /* + * Put cursor at bottom left corner, clear the line, + * reset the terminal modes, and exit. + */ + if (status < 0) + status = save_status; + else + save_status = status; + quitting = 1; + edit((char*)NULL); + save_cmdhist(); + if (any_display && is_tty) + clear_bot(); + deinit(); + flush(); + raw_mode(0); +#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC + /* + * If we don't close 2, we get some garbage from + * 2's buffer when it flushes automatically. + * I cannot track this one down RB + * The same bug shows up if we use ^C^C to abort. + */ + close(2); +#endif +#ifdef WIN32 + SetConsoleTitle(consoleTitle); +#endif + close_getchr(); + exit(status); +}