diff options
author | delphij <delphij@FreeBSD.org> | 2009-05-08 23:34:35 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2009-05-08 23:34:35 +0000 |
commit | d069efd47cacc3156036ed37d5532d6a1d4f55c3 (patch) | |
tree | 2526f6b109843b646672c1537476dc51e56c0454 /contrib/less/edit.c | |
parent | 6aa3e25391d160482339ee072c010bcd22dfbbd1 (diff) | |
download | FreeBSD-src-d069efd47cacc3156036ed37d5532d6a1d4f55c3.zip FreeBSD-src-d069efd47cacc3156036ed37d5532d6a1d4f55c3.tar.gz |
Flatten all tags of the dist tree of less.
Diffstat (limited to 'contrib/less/edit.c')
-rw-r--r-- | contrib/less/edit.c | 818 |
1 files changed, 0 insertions, 818 deletions
diff --git a/contrib/less/edit.c b/contrib/less/edit.c deleted file mode 100644 index e2e30f2..0000000 --- a/contrib/less/edit.c +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Copyright (C) 1984-2007 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. - */ - - -#include "less.h" -#if HAVE_STAT -#include <sys/stat.h> -#endif - -public int fd0 = 0; - -extern int new_file; -extern int errmsgs; -extern int cbufs; -extern char *every_first_cmd; -extern int any_display; -extern int force_open; -extern int is_tty; -extern int sigs; -extern IFILE curr_ifile; -extern IFILE old_ifile; -extern struct scrpos initial_scrpos; -extern void constant *ml_examine; -#if SPACES_IN_FILENAMES -extern char openquote; -extern char closequote; -#endif - -#if LOGFILE -extern int logfile; -extern int force_logfile; -extern char *namelogfile; -#endif - -#if HAVE_STAT_INO -public dev_t curr_dev; -public ino_t curr_ino; -#endif - -char *curr_altfilename = NULL; -static void *curr_altpipe; - - -/* - * Textlist functions deal with a list of words separated by spaces. - * init_textlist sets up a textlist structure. - * forw_textlist uses that structure to iterate thru the list of - * words, returning each one as a standard null-terminated string. - * back_textlist does the same, but runs thru the list backwards. - */ - public void -init_textlist(tlist, str) - struct textlist *tlist; - char *str; -{ - char *s; -#if SPACES_IN_FILENAMES - int meta_quoted = 0; - int delim_quoted = 0; - char *esc = get_meta_escape(); - int esclen = strlen(esc); -#endif - - tlist->string = skipsp(str); - tlist->endstring = tlist->string + strlen(tlist->string); - for (s = str; s < tlist->endstring; s++) - { -#if SPACES_IN_FILENAMES - if (meta_quoted) - { - meta_quoted = 0; - } else if (esclen > 0 && s + esclen < tlist->endstring && - strncmp(s, esc, esclen) == 0) - { - meta_quoted = 1; - s += esclen - 1; - } else if (delim_quoted) - { - if (*s == closequote) - delim_quoted = 0; - } else /* (!delim_quoted) */ - { - if (*s == openquote) - delim_quoted = 1; - else if (*s == ' ') - *s = '\0'; - } -#else - if (*s == ' ') - *s = '\0'; -#endif - } -} - - public char * -forw_textlist(tlist, prev) - struct textlist *tlist; - char *prev; -{ - char *s; - - /* - * prev == NULL means return the first word in the list. - * Otherwise, return the word after "prev". - */ - if (prev == NULL) - s = tlist->string; - else - s = prev + strlen(prev); - if (s >= tlist->endstring) - return (NULL); - while (*s == '\0') - s++; - if (s >= tlist->endstring) - return (NULL); - return (s); -} - - public char * -back_textlist(tlist, prev) - struct textlist *tlist; - char *prev; -{ - char *s; - - /* - * prev == NULL means return the last word in the list. - * Otherwise, return the word before "prev". - */ - if (prev == NULL) - s = tlist->endstring; - else if (prev <= tlist->string) - return (NULL); - else - s = prev - 1; - while (*s == '\0') - s--; - if (s <= tlist->string) - return (NULL); - while (s[-1] != '\0' && s > tlist->string) - s--; - return (s); -} - -/* - * Close the current input file. - */ - static void -close_file() -{ - struct scrpos scrpos; - - if (curr_ifile == NULL_IFILE) - return; - - /* - * Save the current position so that we can return to - * the same position if we edit this file again. - */ - get_scrpos(&scrpos); - if (scrpos.pos != NULL_POSITION) - { - store_pos(curr_ifile, &scrpos); - lastmark(); - } - /* - * Close the file descriptor, unless it is a pipe. - */ - ch_close(); - /* - * If we opened a file using an alternate name, - * do special stuff to close it. - */ - if (curr_altfilename != NULL) - { - close_altfile(curr_altfilename, get_filename(curr_ifile), - curr_altpipe); - free(curr_altfilename); - curr_altfilename = NULL; - } - curr_ifile = NULL_IFILE; -#if HAVE_STAT_INO - curr_ino = curr_dev = 0; -#endif -} - -/* - * Edit a new file (given its name). - * Filename == "-" means standard input. - * Filename == NULL means just close the current file. - */ - public int -edit(filename) - char *filename; -{ - if (filename == NULL) - return (edit_ifile(NULL_IFILE)); - return (edit_ifile(get_ifile(filename, curr_ifile))); -} - -/* - * Edit a new file (given its IFILE). - * ifile == NULL means just close the current file. - */ - public int -edit_ifile(ifile) - IFILE ifile; -{ - int f; - int answer; - int no_display; - int chflags; - char *filename; - char *open_filename; - char *qopen_filename; - char *alt_filename; - void *alt_pipe; - IFILE was_curr_ifile; - PARG parg; - - if (ifile == curr_ifile) - { - /* - * Already have the correct file open. - */ - return (0); - } - - /* - * We must close the currently open file now. - * This is necessary to make the open_altfile/close_altfile pairs - * nest properly (or rather to avoid nesting at all). - * {{ Some stupid implementations of popen() mess up if you do: - * fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }} - */ -#if LOGFILE - end_logfile(); -#endif - was_curr_ifile = save_curr_ifile(); - if (curr_ifile != NULL_IFILE) - { - chflags = ch_getflags(); - close_file(); - if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1) - { - /* - * Don't keep the help file in the ifile list. - */ - del_ifile(was_curr_ifile); - was_curr_ifile = old_ifile; - } - } - - if (ifile == NULL_IFILE) - { - /* - * No new file to open. - * (Don't set old_ifile, because if you call edit_ifile(NULL), - * you're supposed to have saved curr_ifile yourself, - * and you'll restore it if necessary.) - */ - unsave_ifile(was_curr_ifile); - return (0); - } - - filename = save(get_filename(ifile)); - /* - * See if LESSOPEN specifies an "alternate" file to open. - */ - alt_pipe = NULL; - alt_filename = open_altfile(filename, &f, &alt_pipe); - open_filename = (alt_filename != NULL) ? alt_filename : filename; - qopen_filename = shell_unquote(open_filename); - - chflags = 0; - if (alt_pipe != NULL) - { - /* - * The alternate "file" is actually a pipe. - * f has already been set to the file descriptor of the pipe - * in the call to open_altfile above. - * Keep the file descriptor open because it was opened - * via popen(), and pclose() wants to close it. - */ - chflags |= CH_POPENED; - } else if (strcmp(open_filename, "-") == 0) - { - /* - * Use standard input. - * Keep the file descriptor open because we can't reopen it. - */ - f = fd0; - chflags |= CH_KEEPOPEN; - /* - * Must switch stdin to BINARY mode. - */ - SET_BINARY(f); -#if MSDOS_COMPILER==DJGPPC - /* - * Setting stdin to binary by default causes - * Ctrl-C to not raise SIGINT. We must undo - * that side-effect. - */ - __djgpp_set_ctrl_c(1); -#endif - } else if (strcmp(open_filename, FAKE_HELPFILE) == 0) - { - f = -1; - chflags |= CH_HELPFILE; - } else if ((parg.p_string = bad_file(open_filename)) != NULL) - { - /* - * It looks like a bad file. Don't try to open it. - */ - error("%s", &parg); - free(parg.p_string); - err1: - if (alt_filename != NULL) - { - close_altfile(alt_filename, filename, alt_pipe); - free(alt_filename); - } - del_ifile(ifile); - free(qopen_filename); - free(filename); - /* - * Re-open the current file. - */ - if (was_curr_ifile == ifile) - { - /* - * Whoops. The "current" ifile is the one we just deleted. - * Just give up. - */ - quit(QUIT_ERROR); - } - reedit_ifile(was_curr_ifile); - return (1); - } else if ((f = open(qopen_filename, OPEN_READ)) < 0) - { - /* - * Got an error trying to open it. - */ - parg.p_string = errno_message(filename); - error("%s", &parg); - free(parg.p_string); - goto err1; - } else - { - chflags |= CH_CANSEEK; - if (!force_open && !opened(ifile) && bin_file(f)) - { - /* - * Looks like a binary file. - * Ask user if we should proceed. - */ - parg.p_string = filename; - answer = query("\"%s\" may be a binary file. See it anyway? ", - &parg); - if (answer != 'y' && answer != 'Y') - { - close(f); - goto err1; - } - } - } - - /* - * Get the new ifile. - * Get the saved position for the file. - */ - if (was_curr_ifile != NULL_IFILE) - { - old_ifile = was_curr_ifile; - unsave_ifile(was_curr_ifile); - } - curr_ifile = ifile; - curr_altfilename = alt_filename; - curr_altpipe = alt_pipe; - set_open(curr_ifile); /* File has been opened */ - get_pos(curr_ifile, &initial_scrpos); - new_file = TRUE; - ch_init(f, chflags); - - if (!(chflags & CH_HELPFILE)) - { -#if LOGFILE - if (namelogfile != NULL && is_tty) - use_logfile(namelogfile); -#endif -#if HAVE_STAT_INO - /* Remember the i-number and device of the opened file. */ - { - struct stat statbuf; - int r = stat(qopen_filename, &statbuf); - if (r == 0) - { - curr_ino = statbuf.st_ino; - curr_dev = statbuf.st_dev; - } - } -#endif - if (every_first_cmd != NULL) - ungetsc(every_first_cmd); - } - - free(qopen_filename); - no_display = !any_display; - flush(); - any_display = TRUE; - - if (is_tty) - { - /* - * Output is to a real tty. - */ - - /* - * Indicate there is nothing displayed yet. - */ - pos_clear(); - clr_linenum(); -#if HILITE_SEARCH - clr_hilite(); -#endif - cmd_addhist(ml_examine, filename); - if (no_display && errmsgs > 0) - { - /* - * We displayed some messages on error output - * (file descriptor 2; see error() function). - * Before erasing the screen contents, - * display the file name and wait for a keystroke. - */ - parg.p_string = filename; - error("%s", &parg); - } - } - free(filename); - return (0); -} - -/* - * Edit a space-separated list of files. - * For each filename in the list, enter it into the ifile list. - * Then edit the first one. - */ - public int -edit_list(filelist) - char *filelist; -{ - IFILE save_ifile; - char *good_filename; - char *filename; - char *gfilelist; - char *gfilename; - struct textlist tl_files; - struct textlist tl_gfiles; - - save_ifile = save_curr_ifile(); - good_filename = NULL; - - /* - * Run thru each filename in the list. - * Try to glob the filename. - * If it doesn't expand, just try to open the filename. - * If it does expand, try to open each name in that list. - */ - init_textlist(&tl_files, filelist); - filename = NULL; - while ((filename = forw_textlist(&tl_files, filename)) != NULL) - { - gfilelist = lglob(filename); - init_textlist(&tl_gfiles, gfilelist); - gfilename = NULL; - while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL) - { - if (edit(gfilename) == 0 && good_filename == NULL) - good_filename = get_filename(curr_ifile); - } - free(gfilelist); - } - /* - * Edit the first valid filename in the list. - */ - if (good_filename == NULL) - { - unsave_ifile(save_ifile); - return (1); - } - if (get_ifile(good_filename, curr_ifile) == curr_ifile) - { - /* - * Trying to edit the current file; don't reopen it. - */ - unsave_ifile(save_ifile); - return (0); - } - reedit_ifile(save_ifile); - return (edit(good_filename)); -} - -/* - * Edit the first file in the command line (ifile) list. - */ - public int -edit_first() -{ - curr_ifile = NULL_IFILE; - return (edit_next(1)); -} - -/* - * Edit the last file in the command line (ifile) list. - */ - public int -edit_last() -{ - curr_ifile = NULL_IFILE; - return (edit_prev(1)); -} - - -/* - * Edit the n-th next or previous file in the command line (ifile) list. - */ - static int -edit_istep(h, n, dir) - IFILE h; - int n; - int dir; -{ - IFILE next; - - /* - * Skip n filenames, then try to edit each filename. - */ - for (;;) - { - next = (dir > 0) ? next_ifile(h) : prev_ifile(h); - if (--n < 0) - { - if (edit_ifile(h) == 0) - break; - } - if (next == NULL_IFILE) - { - /* - * Reached end of the ifile list. - */ - return (1); - } - if (ABORT_SIGS()) - { - /* - * Interrupt breaks out, if we're in a long - * list of files that can't be opened. - */ - return (1); - } - h = next; - } - /* - * Found a file that we can edit. - */ - return (0); -} - - static int -edit_inext(h, n) - IFILE h; - int n; -{ - return (edit_istep(h, n, +1)); -} - - public int -edit_next(n) - int n; -{ - return edit_istep(curr_ifile, n, +1); -} - - static int -edit_iprev(h, n) - IFILE h; - int n; -{ - return (edit_istep(h, n, -1)); -} - - public int -edit_prev(n) - int n; -{ - return edit_istep(curr_ifile, n, -1); -} - -/* - * Edit a specific file in the command line (ifile) list. - */ - public int -edit_index(n) - int n; -{ - IFILE h; - - h = NULL_IFILE; - do - { - if ((h = next_ifile(h)) == NULL_IFILE) - { - /* - * Reached end of the list without finding it. - */ - return (1); - } - } while (get_index(h) != n); - - return (edit_ifile(h)); -} - - public IFILE -save_curr_ifile() -{ - if (curr_ifile != NULL_IFILE) - hold_ifile(curr_ifile, 1); - return (curr_ifile); -} - - public void -unsave_ifile(save_ifile) - IFILE save_ifile; -{ - if (save_ifile != NULL_IFILE) - hold_ifile(save_ifile, -1); -} - -/* - * Reedit the ifile which was previously open. - */ - public void -reedit_ifile(save_ifile) - IFILE save_ifile; -{ - IFILE next; - IFILE prev; - - /* - * Try to reopen the ifile. - * Note that opening it may fail (maybe the file was removed), - * in which case the ifile will be deleted from the list. - * So save the next and prev ifiles first. - */ - unsave_ifile(save_ifile); - next = next_ifile(save_ifile); - prev = prev_ifile(save_ifile); - if (edit_ifile(save_ifile) == 0) - return; - /* - * If can't reopen it, open the next input file in the list. - */ - if (next != NULL_IFILE && edit_inext(next, 0) == 0) - return; - /* - * If can't open THAT one, open the previous input file in the list. - */ - if (prev != NULL_IFILE && edit_iprev(prev, 0) == 0) - return; - /* - * If can't even open that, we're stuck. Just quit. - */ - quit(QUIT_ERROR); -} - - public void -reopen_curr_ifile() -{ - IFILE save_ifile = save_curr_ifile(); - close_file(); - reedit_ifile(save_ifile); -} - -/* - * Edit standard input. - */ - public int -edit_stdin() -{ - if (isatty(fd0)) - { - error("Missing filename (\"less --help\" for help)", NULL_PARG); - quit(QUIT_OK); - } - return (edit("-")); -} - -/* - * Copy a file directly to standard output. - * Used if standard output is not a tty. - */ - public void -cat_file() -{ - register int c; - - while ((c = ch_forw_get()) != EOI) - putchr(c); - flush(); -} - -#if LOGFILE - -/* - * If the user asked for a log file and our input file - * is standard input, create the log file. - * We take care not to blindly overwrite an existing file. - */ - public void -use_logfile(filename) - char *filename; -{ - register int exists; - register int answer; - PARG parg; - - if (ch_getflags() & CH_CANSEEK) - /* - * Can't currently use a log file on a file that can seek. - */ - return; - - /* - * {{ We could use access() here. }} - */ - filename = shell_unquote(filename); - exists = open(filename, OPEN_READ); - close(exists); - exists = (exists >= 0); - - /* - * Decide whether to overwrite the log file or append to it. - * If it doesn't exist we "overwrite" it. - */ - if (!exists || force_logfile) - { - /* - * Overwrite (or create) the log file. - */ - answer = 'O'; - } else - { - /* - * Ask user what to do. - */ - parg.p_string = filename; - answer = query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg); - } - -loop: - switch (answer) - { - case 'O': case 'o': - /* - * Overwrite: create the file. - */ - logfile = creat(filename, 0644); - break; - case 'A': case 'a': - /* - * Append: open the file and seek to the end. - */ - logfile = open(filename, OPEN_APPEND); - if (lseek(logfile, (off_t)0, SEEK_END) == BAD_LSEEK) - { - close(logfile); - logfile = -1; - } - break; - case 'D': case 'd': - /* - * Don't do anything. - */ - free(filename); - return; - case 'q': - quit(QUIT_OK); - /*NOTREACHED*/ - default: - /* - * Eh? - */ - answer = query("Overwrite, Append, or Don't log? (Type \"O\", \"A\", \"D\" or \"q\") ", NULL_PARG); - goto loop; - } - - if (logfile < 0) - { - /* - * Error in opening logfile. - */ - parg.p_string = filename; - error("Cannot write to \"%s\"", &parg); - free(filename); - return; - } - free(filename); - SET_BINARY(logfile); -} - -#endif |