summaryrefslogtreecommitdiffstats
path: root/contrib/less/edit.c
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2009-05-08 23:34:35 +0000
committerdelphij <delphij@FreeBSD.org>2009-05-08 23:34:35 +0000
commitd069efd47cacc3156036ed37d5532d6a1d4f55c3 (patch)
tree2526f6b109843b646672c1537476dc51e56c0454 /contrib/less/edit.c
parent6aa3e25391d160482339ee072c010bcd22dfbbd1 (diff)
downloadFreeBSD-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.c818
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
OpenPOWER on IntegriCloud