Commit 02517e0a authored by David Lawrence Ramsey's avatar David Lawrence Ramsey
Browse files

add DB's overhaul of the file loading code to increase efficiency,

remove ugly workarounds for most cases of edittop's or current's being
NULL (as those cases no longer occur due to the overhaul), and remove
detection of binary files (since it wasn't always accurate and will only
cause problems when UTF-8 support is added); also add a few minor fixes
of mine


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1928 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
parent 8bf08097
Showing with 431 additions and 431 deletions
+431 -431
...@@ -15,6 +15,29 @@ CVS code - ...@@ -15,6 +15,29 @@ CVS code -
- Remove reference to @includedir@ in src/Makefile.am, as it's - Remove reference to @includedir@ in src/Makefile.am, as it's
unneeded and can break cross-compilation. (DLR, found by Mike unneeded and can break cross-compilation. (DLR, found by Mike
Frysinger) Frysinger)
- Overhaul the file opening, reading, and loading operations to
increase efficiency, avoid problems on invalid filenames
specified on the command line, and eliminate corner cases that
erroneously leave edittop or current NULL when they shouldn't
be. Also split out the code to execute a command into a
separate function, eliminate a workaround for one of the
aforementioned corner cases, handle files with a mix of DOS
and Mac format lines, and remove the code to turn on the
NO_CONVERT flag when opening a binary file, as it's not always
reliable and will cause problems with UTF-8 text files. New
functions open_file(), execute_command(), and mallocstrassn();
changes to read_line(), load_file(), read_file(), open_file(),
get_next_filename(), do_insertfile(), do_insertfile_void(),
do_alt_speller(), and edit_refresh(). (David Benbennick) DLR:
Add a few minor fixes to make sure that current is set
properly in all cases, indicate on the statusbar when the file
has a mix of DOS and Mac format lines, move the test for DOS
line endings from read_line() to read_file() to avoid
inaccurate statusbar messages and to reduce fileformat to a
local variable in read_file(), eliminate another workaround in
edit_update(), rename open_the_file() to open_file() since the
latter has been removed, and rename load_a_file() to
load_buffer().
- files.c: - files.c:
do_insertfile() do_insertfile()
- Readd the NANO_SMALL #ifdef around the start_again: label to - Readd the NANO_SMALL #ifdef around the start_again: label to
...@@ -23,14 +46,23 @@ CVS code - ...@@ -23,14 +46,23 @@ CVS code -
shortcut_init() shortcut_init()
- Remove redundant NANO_SMALL #ifdef. (DLR) - Remove redundant NANO_SMALL #ifdef. (DLR)
- nano.c: - nano.c:
die_save_file()
- Clarify the error message when there are too many backup files
and the current one can't be written. (DLR)
do_para_begin(), do_para_end() do_para_begin(), do_para_end()
- Maintain current_y's value when moving up or down lines so - Maintain current_y's value when moving up or down lines so
that smooth scrolling works correctly. (DLR) that smooth scrolling works correctly. (DLR)
- nano.h:
- Add WIDTH_OF_TAB #define, containing the default width of a
tab. (DLR)
- rcfile.c: - rcfile.c:
parse_rcfile() parse_rcfile()
- Add missing brackets around an if statement block so that - Add missing brackets around an if statement block so that
parsing the numeric argument after "tabsize" works properly parsing the numeric argument after "tabsize" works properly
again. (DLR, found by Mike Frysinger) again. (DLR, found by Mike Frysinger)
- Since flag values are longs, use "%ld" instead of "%d" in the
debugging messages indicating when a flag is set or unset.
(DLR)
- search.c: - search.c:
findnextstr() findnextstr()
- Take the no_sameline parameter after can_display_wrap and - Take the no_sameline parameter after can_display_wrap and
...@@ -56,6 +88,10 @@ CVS code - ...@@ -56,6 +88,10 @@ CVS code -
- If there are more than MAIN_VISIBLE shortcuts available, only - If there are more than MAIN_VISIBLE shortcuts available, only
register clicks on the first MAIN_VISIBLE shortcuts, since register clicks on the first MAIN_VISIBLE shortcuts, since
bottombars() only shows that many shortcuts. (DLR) bottombars() only shows that many shortcuts. (DLR)
reset_cursor()
- If this is called before any files have been opened, as it can
be by statusbar(), put the cursor at the top left corner of
the edit window before getting out. (DLR)
edit_refresh() edit_refresh()
- Call edit_update() with NONE instead of CENTER when smooth - Call edit_update() with NONE instead of CENTER when smooth
scrolling is on, for consistency with the movement routines. scrolling is on, for consistency with the movement routines.
......
...@@ -37,35 +37,12 @@ ...@@ -37,35 +37,12 @@
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
/* Set a default value for PATH_MAX, so we can use it below in lines like /* Set a default value for PATH_MAX, so we can use it below in lines
path = getcwd(NULL, PATH_MAX + 1); */ * like "path = getcwd(NULL, PATH_MAX + 1);". */
#ifndef PATH_MAX #ifndef PATH_MAX
#define PATH_MAX -1 #define PATH_MAX -1
#endif #endif
#ifndef NANO_SMALL
static int fileformat = 0; /* 0 = *nix, 1 = DOS, 2 = Mac */
#endif
/* Load file into edit buffer -- takes data from file struct. */
void load_file(int update)
{
current = fileage;
#ifdef ENABLE_MULTIBUFFER
/* if update is zero, add a new entry to the open_files structure;
otherwise, update the current entry (the latter is needed in the
case of the alternate spell checker) */
add_open_file(update);
#endif
#ifdef ENABLE_COLOR
update_color();
if (ISSET(COLOR_SYNTAX))
edit_refresh();
#endif
}
/* What happens when there is no file to open? aiee! */ /* What happens when there is no file to open? aiee! */
void new_file(void) void new_file(void)
{ {
...@@ -79,24 +56,6 @@ void new_file(void) ...@@ -79,24 +56,6 @@ void new_file(void)
totlines = 1; totlines = 1;
totsize = 0; totsize = 0;
#ifdef ENABLE_MULTIBUFFER
/* if there aren't any entries in open_files, create the entry for
this new file; without this, if nano is started without a filename
on the command line, a new file will be created, but it will be
given no open_files entry */
if (open_files == NULL) {
add_open_file(FALSE);
/* turn off view mode in this case; this is for consistency
whether multibuffers are compiled in or not */
UNSET(VIEW_MODE);
}
#else
/* if multibuffers haven't been compiled in, turn off view mode
unconditionally; otherwise, don't turn them off (except in the
above case), so that we can view multiple files properly */
UNSET(VIEW_MODE);
#endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
update_color(); update_color();
if (ISSET(COLOR_SYNTAX)) if (ISSET(COLOR_SYNTAX))
...@@ -104,12 +63,17 @@ void new_file(void) ...@@ -104,12 +63,17 @@ void new_file(void)
#endif #endif
} }
filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t /* We make a new line of text from buf. buf is length len. If
len) * first_line_ins is TRUE, then we put the new line at the top of the
* file. Otherwise, we assume prev is the last line of the file, and
* put our line after prev. */
filestruct *read_line(char *buf, filestruct *prev, bool *first_line_ins,
size_t len)
{ {
filestruct *fileptr = (filestruct *)nmalloc(sizeof(filestruct)); filestruct *fileptr = (filestruct *)nmalloc(sizeof(filestruct));
/* nulls to newlines; len is the string's real length here */ /* Convert nulls to newlines. len is the string's real length
* here. */
unsunder(buf, len); unsunder(buf, len);
assert(strlen(buf) == len); assert(strlen(buf) == len);
...@@ -117,27 +81,25 @@ filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t ...@@ -117,27 +81,25 @@ filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t
fileptr->data = mallocstrcpy(NULL, buf); fileptr->data = mallocstrcpy(NULL, buf);
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* If it's a DOS file (CRLF), and file conversion isn't disabled, /* If it's a DOS file (CR LF), and file conversion isn't disabled,
strip out the CR part */ * strip out the CR part. */
if (!ISSET(NO_CONVERT) && len > 0 && buf[len - 1] == '\r') { if (!ISSET(NO_CONVERT) && len > 0 && buf[len - 1] == '\r') {
fileptr->data[len - 1] = '\0'; fileptr->data[len - 1] = '\0';
totsize--; totsize--;
if (fileformat == 0)
fileformat = 1;
} }
#endif #endif
if (*line1ins != 0 || fileage == NULL) { if (*first_line_ins || fileage == NULL) {
/* Special case, insert with cursor on 1st line. */ /* Special case: we're inserting with the cursor on the first
* line. */
fileptr->prev = NULL; fileptr->prev = NULL;
fileptr->next = fileage; fileptr->next = fileage;
fileptr->lineno = 1; fileptr->lineno = 1;
if (*line1ins != 0) { if (*first_line_ins) {
*line1ins = 0; *first_line_ins = FALSE;
/* If we're inserting into the first line of the file, then /* If we're inserting into the first line of the file, then
we want to make sure that our edit buffer stays on the * we want to make sure that our edit buffer stays on the
first line (and that fileage stays up to date!) */ * first line and that fileage stays up to date. */
edittop = fileptr; edittop = fileptr;
} else } else
filebot = fileptr; filebot = fileptr;
...@@ -153,70 +115,105 @@ filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t ...@@ -153,70 +115,105 @@ filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t
return fileptr; return fileptr;
} }
void read_file(FILE *f, const char *filename, int quiet) /* Load a file into the edit buffer. This takes data from the file
* struct. */
void load_file(void)
{
current = fileage;
#ifdef ENABLE_MULTIBUFFER
/* Add a new entry to the open_files structure. */
add_open_file(FALSE);
/* Reinitialize the shortcut list. */
shortcut_init(FALSE);
#endif
}
void read_file(FILE *f, const char *filename)
{ {
int num_lines = 0, len = 0; size_t num_lines = 0;
char input = '\0'; /* current input character */ /* The number of lines in the file. */
size_t len = 0;
/* The length of the current line of the file. */
size_t i = 0;
/* The position in the current line of the file. */
size_t bufx = 128;
/* The size of each chunk of the file that we read. */
char input = '\0';
/* The current input character. */
char *buf; char *buf;
long i = 0, bufx = 128; /* The buffer where we store chunks of the file. */
filestruct *fileptr = current, *tmp = NULL; filestruct *fileptr = current;
/* The current line of the file. */
bool first_line_ins = FALSE;
/* Whether we're inserting with the cursor on the first line. */
int input_int;
/* The current value we read from the file, whether an input
* character or EOF. */
#ifndef NANO_SMALL #ifndef NANO_SMALL
int old_no_convert = ISSET(NO_CONVERT); int fileformat = 0;
/* 0 = *nix, 1 = DOS, 2 = Mac, 3 = both DOS and Mac. */
#endif #endif
int line1ins = 0;
int input_int;
buf = charalloc(bufx); buf = charalloc(bufx);
buf[0] = '\0'; buf[0] = '\0';
if (current != NULL) { if (current != NULL) {
if (current == fileage) if (current == fileage)
line1ins = 1; first_line_ins = TRUE;
else else
fileptr = current->prev; fileptr = current->prev;
tmp = fileptr;
} }
/* For the assertion in read_line(), it must be true that if current is /* For the assertion in read_line(), it must be true that if current
* NULL then so is fileage. */ * is NULL, then so is fileage. */
assert(current != NULL || fileage == NULL); assert(current != NULL || fileage == NULL);
/* Read the entire file into file struct. */ /* Read the entire file into the file struct. */
while ((input_int = getc(f)) != EOF) { while ((input_int = getc(f)) != EOF) {
input = (char)input_int; input = (char)input_int;
#ifndef NANO_SMALL
/* If the file has binary chars in it, don't stupidly
assume it's a DOS or Mac formatted file if it hasn't been
detected as one already! */
if (fileformat == 0 && !ISSET(NO_CONVERT)
&& is_cntrl_char(input) && input != '\t'
&& input != '\r' && input != '\n')
SET(NO_CONVERT);
#endif
/* If it's a *nix file (LF) or a DOS file (CR LF), and file
* conversion isn't disabled, handle it! */
if (input == '\n') { if (input == '\n') {
/* read in the line properly */ #ifndef NANO_SMALL
fileptr = read_line(buf, fileptr, &line1ins, len); /* If there's a CR before the LF, set fileformat to DOS if
* we currently think this is a *nix file, or to both if we
* currently think it's a Mac file. */
if (!ISSET(NO_CONVERT) && i > 0 && buf[i - 1] == '\r' &&
(fileformat == 0 || fileformat == 2))
fileformat++;
#endif
/* Read in the line properly. */
fileptr = read_line(buf, fileptr, &first_line_ins, len);
/* reset the line length, in preparation for the next line */ /* Reset the line length in preparation for the next
* line. */
len = 0; len = 0;
num_lines++; num_lines++;
buf[0] = '\0'; buf[0] = '\0';
i = 0; i = 0;
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* If it's a Mac file (no LF just a CR), and file conversion /* If it's a Mac file (CR without an LF), and file conversion
isn't disabled, handle it! */ * isn't disabled, handle it! */
} else if (!ISSET(NO_CONVERT) && i > 0 && buf[i - 1] == '\r') { } else if (!ISSET(NO_CONVERT) && i > 0 && buf[i - 1] == '\r') {
fileformat = 2;
/* read in the line properly */ /* If we currently think the file is a *nix file, set
fileptr = read_line(buf, fileptr, &line1ins, len); * fileformat to Mac. If we currently think the file is a
* DOS file, set fileformat to both DOS and Mac. */
if (fileformat == 0 || fileformat == 1)
fileformat += 2;
/* reset the line length, in preparation for the next line; /* Read in the line properly. */
since we've already read in the next character, reset it fileptr = read_line(buf, fileptr, &first_line_ins, len);
to 1 instead of 0 */
/* Reset the line length in preparation for the next line.
* Since we've already read in the next character, reset it
* to 1 instead of 0. */
len = 1; len = 1;
num_lines++; num_lines++;
...@@ -226,15 +223,14 @@ void read_file(FILE *f, const char *filename, int quiet) ...@@ -226,15 +223,14 @@ void read_file(FILE *f, const char *filename, int quiet)
i = 1; i = 1;
#endif #endif
} else { } else {
/* Calculate the total length of the line. It might have
/* Calculate the total length of the line; it might have * nulls in it, so we can't just use strlen() here. */
nulls in it, so we can't just use strlen(). */
len++; len++;
/* Now we allocate a bigger buffer 128 characters at a time. /* Now we allocate a bigger buffer 128 characters at a time.
If we allocate a lot of space for one line, we may indeed * If we allocate a lot of space for one line, we may indeed
have to use a buffer this big later on, so we don't * have to use a buffer this big later on, so we don't
decrease it at all. We do free it at the end, though. */ * decrease it at all. We do free it at the end, though. */
if (i >= bufx - 1) { if (i >= bufx - 1) {
bufx += 128; bufx += 128;
buf = charealloc(buf, bufx); buf = charealloc(buf, bufx);
...@@ -246,54 +242,43 @@ void read_file(FILE *f, const char *filename, int quiet) ...@@ -246,54 +242,43 @@ void read_file(FILE *f, const char *filename, int quiet)
totsize++; totsize++;
} }
/* This conditional duplicates previous read_byte() behavior; /* This conditional duplicates previous read_byte() behavior.
perhaps this could use some better handling. */ * Perhaps this could use some better handling. */
if (ferror(f)) if (ferror(f))
nperror(filename); nperror(filename);
fclose(f); fclose(f);
/* Did we not get a newline but still have stuff to do? */
if (len > 0) {
#ifndef NANO_SMALL
/* If file conversion isn't disabled, the last character in
this file is a CR and fileformat isn't set yet, make sure
it's set to Mac format */
if (!ISSET(NO_CONVERT) && buf[len - 1] == '\r' && fileformat == 0)
fileformat = 2;
#endif
/* read in the LAST line properly */
fileptr = read_line(buf, fileptr, &line1ins, len);
num_lines++;
totsize++;
buf[0] = '\0';
}
#ifndef NANO_SMALL #ifndef NANO_SMALL
else if (!ISSET(NO_CONVERT) && input == '\r') { /* If file conversion isn't disabled and the last character in this
/* If file conversion isn't disabled and the last character in * file is a CR, read it in properly as a Mac format line. */
this file is a CR, read it in properly as a (Mac format) if (len == 0 && !ISSET(NO_CONVERT) && input == '\r') {
line */
buf[0] = input; buf[0] = input;
buf[1] = '\0'; buf[1] = '\0';
len = 1; len = 1;
fileptr = read_line(buf, fileptr, &line1ins, len);
num_lines++;
totsize++;
buf[0] = '\0';
} }
#endif #endif
free(buf); /* Did we not get a newline and still have stuff to do? */
if (len > 0) {
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* If NO_CONVERT wasn't set before we read the file, but it is now, /* If file conversion isn't disabled and the last character in
unset it again. */ * this file is a CR, set fileformat to Mac if we currently
if (!old_no_convert && ISSET(NO_CONVERT)) * think the file is a *nix file, or to both DOS and Mac if we
UNSET(NO_CONVERT); * currently think the file is a DOS file. */
if (!ISSET(NO_CONVERT) && buf[len - 1] == '\r' &&
(fileformat == 0 || fileformat == 1))
fileformat += 2;
#endif #endif
/* Did we even GET a file if we don't already have one? */ /* Read in the last line properly. */
fileptr = read_line(buf, fileptr, &first_line_ins, len);
num_lines++;
totsize++;
}
free(buf);
/* If we didn't get a file and we don't already have one, make a new
* file. */
if (totsize == 0 || fileptr == NULL) if (totsize == 0 || fileptr == NULL)
new_file(); new_file();
...@@ -309,93 +294,77 @@ void read_file(FILE *f, const char *filename, int quiet) ...@@ -309,93 +294,77 @@ void read_file(FILE *f, const char *filename, int quiet)
filebot = fileptr; filebot = fileptr;
new_magicline(); new_magicline();
totsize--; totsize--;
load_file(quiet);
} }
} }
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (fileformat == 2) if (fileformat == 3)
statusbar(P_("Read %d line (Converted from Mac format)", statusbar(
"Read %d lines (Converted from Mac format)", P_("Read %lu line (Converted from DOS and Mac format)",
num_lines), num_lines); "Read %lu lines (Converted from DOS and Mac format)",
(unsigned long)num_lines), (unsigned long)num_lines);
else if (fileformat == 2)
statusbar(P_("Read %lu line (Converted from Mac format)",
"Read %lu lines (Converted from Mac format)",
(unsigned long)num_lines), (unsigned long)num_lines);
else if (fileformat == 1) else if (fileformat == 1)
statusbar(P_("Read %d line (Converted from DOS format)", statusbar(P_("Read %lu line (Converted from DOS format)",
"Read %d lines (Converted from DOS format)", "Read %lu lines (Converted from DOS format)",
num_lines), num_lines); (unsigned long)num_lines), (unsigned long)num_lines);
else else
#endif #endif
statusbar(P_("Read %d line", "Read %d lines", num_lines), statusbar(P_("Read %lu line", "Read %lu lines",
num_lines); (unsigned long) num_lines),(unsigned long)num_lines);
#ifndef NANO_SMALL
/* Set fileformat back to 0, now that we've read the file in and
possibly converted it from DOS/Mac format. */
fileformat = 0;
#endif
totlines += num_lines; totlines += num_lines;
return;
} }
/* Open the file (and decide if it exists). Return TRUE on success, /* Open the file (and decide if it exists). If newfie is TRUE, display
* FALSE on failure. */ * "New File" if the file is missing. Otherwise, say "[filename] not
bool open_file(const char *filename, int insert, int quiet) * found".
*
* Return -2 if we say "New File". Otherwise, -1 if the file isn't
* opened, 0 otherwise. The file might still have an error while
* reading with a 0 return value. *f is set to the opened file. */
int open_file(const char *filename, bool newfie, FILE **f)
{ {
int fd; int fd;
FILE *f;
struct stat fileinfo; struct stat fileinfo;
if (filename[0] == '\0' || stat(filename, &fileinfo) == -1) { assert(f != NULL);
if (insert && !quiet) { if (filename == NULL || filename[0] == '\0' ||
statusbar(_("\"%s\" not found"), filename); stat(filename, &fileinfo) == -1) {
return FALSE; if (newfie) {
} else {
/* We have a new file */
statusbar(_("New File")); statusbar(_("New File"));
new_file(); return -2;
} }
statusbar(_("\"%s\" not found"), filename);
return -1;
} else if (S_ISDIR(fileinfo.st_mode) || S_ISCHR(fileinfo.st_mode) || } else if (S_ISDIR(fileinfo.st_mode) || S_ISCHR(fileinfo.st_mode) ||
S_ISBLK(fileinfo.st_mode)) { S_ISBLK(fileinfo.st_mode)) {
/* Don't open character or block files. Sorry, /dev/sndstat! */ /* Don't open character or block files. Sorry, /dev/sndstat! */
statusbar(S_ISDIR(fileinfo.st_mode) ? _("\"%s\" is a directory") : statusbar(S_ISDIR(fileinfo.st_mode) ? _("\"%s\" is a directory") :
_("File \"%s\" is a device file"), filename); _("File \"%s\" is a device file"), filename);
if (!insert) return -1;
new_file();
return FALSE;
} else if ((fd = open(filename, O_RDONLY)) == -1) { } else if ((fd = open(filename, O_RDONLY)) == -1) {
/* If we're in multibuffer mode, don't be quiet when an error statusbar(_("Error reading %s: %s"), filename, strerror(errno));
occurs while opening a file */ return -1;
if (!quiet } else {
#ifdef ENABLE_MULTIBUFFER /* File is A-OK. */
|| ISSET(MULTIBUFFER) *f = fdopen(fd, "rb"); /* Binary for our own line-end munging */
#endif
) if (*f == NULL) {
statusbar("Error reading %s: %s", filename, strerror(errno)); statusbar(_("Error reading %s: %s"), filename, strerror(errno));
if (!insert)
new_file();
return FALSE;
} else { /* File is A-OK */
if (!quiet)
statusbar(_("Reading File"));
f = fdopen(fd, "rb"); /* Binary for our own line-end munging */
if (f == NULL) {
nperror("fdopen");
close(fd); close(fd);
return FALSE; } else
} statusbar(_("Reading File"));
read_file(f, filename, quiet);
#ifndef NANO_SMALL
stat(filename, &originalfilestat);
#endif
} }
return 0;
return TRUE;
} }
/* This function will return the name of the first available extension /* This function will return the name of the first available extension
* of a filename (starting with the filename.save, then filename.save.1, * of a filename (starting with filename.save, then filename.save.1,
* etc). Memory is allocated for the return value. If no writable * etc.). Memory is allocated for the return value. If no writable
* extension exists, we return "". */ * extension exists, we return "". */
char *get_next_filename(const char *name) char *get_next_filename(const char *name)
{ {
...@@ -421,77 +390,125 @@ char *get_next_filename(const char *name) ...@@ -421,77 +390,125 @@ char *get_next_filename(const char *name)
} }
/* We get here only if there is no possible save file. */ /* We get here only if there is no possible save file. */
buf[0] = '\0'; null_at(&buf, 0);
return buf; return buf;
} }
void do_insertfile(int loading_file) #ifndef NANO_SMALL
void execute_command(const char *command)
{ {
int i, old_current_x = current_x; #ifdef ENABLE_MULTIBUFFER
bool opened; if (ISSET(MULTIBUFFER)) {
/* TRUE if the file opened successfully. */ /* Update the current entry in the open_files structure. */
char *realname = NULL; add_open_file(TRUE);
static char *inspath = NULL; new_file();
UNSET(MODIFIED);
if (inspath == NULL) { UNSET(MARK_ISSET);
inspath = charalloc(1);
inspath[0] = '\0';
} }
#endif /* ENABLE_MULTIBUFFER */
open_pipe(command);
#ifdef ENABLE_MULTIBUFFER
/* Add this new entry to the open_files structure. */
if (ISSET(MULTIBUFFER))
load_file();
#endif /* ENABLE_MULTIBUFFER */
}
#endif /* !NANO_SMALL */
#ifndef DISABLE_WRAPPING /* name is a file name to open. We make a new buffer if necessary, then
wrap_reset(); * open and read the file. */
void load_buffer(const char *name)
{
bool new_buffer = fileage == NULL
#ifdef ENABLE_MULTIBUFFER
|| ISSET(MULTIBUFFER)
#endif #endif
;
/* new_buffer says whether we load to this buffer or a new one.
* If new_buffer is TRUE, we display "New File" if the file is
* not found, and if it is found we set filename and add a new
* open_files entry. */
FILE *f;
int rc;
/* rc == -2 means that the statusbar displayed "New File". -1
* means that the open failed. 0 means success. */
#ifndef NANO_SMALL #ifndef DISABLE_OPERATINGDIR
start_again: if (check_operating_dir(name, FALSE)) {
statusbar(_("Can't insert file from outside of %s"), operating_dir);
return;
}
#endif #endif
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE) #ifdef ENABLE_MULTIBUFFER
currshortcut = insertfile_list; /* Update the current entry in the open_files structure. */
add_open_file(TRUE);
#endif #endif
#ifndef DISABLE_OPERATINGDIR rc = open_file(name, new_buffer, &f);
if (operating_dir != NULL && strcmp(operating_dir, ".") != 0)
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (ISSET(MULTIBUFFER)) if (rc != -1 && ISSET(MULTIBUFFER)) {
i = statusq(TRUE, insertfile_list, inspath, UNSET(MODIFIED);
#ifndef NANO_SMALL #ifndef NANO_SMALL
NULL, UNSET(MARK_ISSET);
#endif #endif
_("File to insert into new buffer [from %s] "), }
operating_dir);
else
#endif #endif
i = statusq(TRUE, insertfile_list, inspath,
if (rc != -1 && new_buffer) {
filename = mallocstrcpy(filename, name);
new_file();
}
if (rc == 0) {
read_file(f, filename);
#ifndef NANO_SMALL #ifndef NANO_SMALL
NULL, stat(filename, &originalfilestat);
#endif #endif
_("File to insert [from %s] "), }
operating_dir);
/* Add this new entry to the open_files structure if we have
* multibuffer support, or to the main filestruct if we don't. */
if (rc != -1 && new_buffer)
load_file();
}
void do_insertfile(void)
{
int i;
const char *msg;
char *inspath = mallocstrcpy(NULL, "");
/* The last answer the user typed on the statusbar. Saved for if
* they do M-F or cancel the file browser. */
wrap_reset();
#if !defined(DISABLE_BROWSER) || (!defined(NANO_SMALL) && defined(ENABLE_MULTIBUFFER))
start_again: /* Go here when the user cancels the file browser. */
#endif
#ifdef ENABLE_MULTIBUFFER
if (ISSET(MULTIBUFFER))
msg = N_("File to insert into new buffer [from %s] ");
else else
#endif #endif
#ifdef ENABLE_MULTIBUFFER msg = N_("File to insert [from %s] ");
if (ISSET(MULTIBUFFER)) i = statusq(TRUE, insertfile_list, inspath,
i = statusq(TRUE, insertfile_list, inspath,
#ifndef NANO_SMALL #ifndef NANO_SMALL
NULL, NULL,
#endif #endif
_("File to insert into new buffer [from ./] ")); _(msg),
else #ifndef DISABLE_OPERATINGDIR
#endif /* ENABLE_MULTIBUFFER */ operating_dir != NULL && strcmp(operating_dir, ".") != 0 ?
i = statusq(TRUE, insertfile_list, inspath, operating_dir :
#ifndef NANO_SMALL
NULL,
#endif #endif
_("File to insert [from ./] ")); "./");
if (i != -1) { if (i != -1) {
int old_current_x = current_x;
inspath = mallocstrcpy(inspath, answer); inspath = mallocstrcpy(inspath, answer);
#ifdef DEBUG
fprintf(stderr, "filename is %s\n", answer);
#endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
...@@ -499,11 +516,9 @@ void do_insertfile(int loading_file) ...@@ -499,11 +516,9 @@ void do_insertfile(int loading_file)
/* Don't allow toggling if we're in view mode. */ /* Don't allow toggling if we're in view mode. */
if (!ISSET(VIEW_MODE)) if (!ISSET(VIEW_MODE))
TOGGLE(MULTIBUFFER); TOGGLE(MULTIBUFFER);
loading_file = ISSET(MULTIBUFFER);
goto start_again; goto start_again;
} }
#endif /* ENABLE_MULTIBUFFER */ #endif /* ENABLE_MULTIBUFFER */
if (i == NANO_EXTCMD_KEY) { if (i == NANO_EXTCMD_KEY) {
char *ans = mallocstrcpy(NULL, answer); char *ans = mallocstrcpy(NULL, answer);
int ts = statusq(TRUE, extcmd_list, ans, NULL, int ts = statusq(TRUE, extcmd_list, ans, NULL,
...@@ -511,137 +526,67 @@ void do_insertfile(int loading_file) ...@@ -511,137 +526,67 @@ void do_insertfile(int loading_file)
free(ans); free(ans);
if (ts == -1 || answer == NULL || answer[0] == '\0') { if (ts == -1 || answer == NULL || answer[0] == '\0')
statusbar(_("Cancelled")); goto start_again;
display_main_list();
return;
}
} }
#endif /* !NANO_SMALL */ #endif /* !NANO_SMALL */
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
if (i == NANO_TOFILES_KEY) { if (i == NANO_TOFILES_KEY) {
char *tmp = do_browse_from(answer); char *tmp = do_browse_from(answer);
if (tmp != NULL) { if (tmp == NULL)
free(answer);
answer = tmp;
resetstatuspos = 1;
} else
goto start_again; goto start_again;
} resetstatuspos = TRUE;
#endif free(answer);
answer = tmp;
#ifndef DISABLE_OPERATINGDIR
if (
#ifndef NANO_SMALL
i != NANO_EXTCMD_KEY &&
#endif
check_operating_dir(answer, FALSE) != 0) {
statusbar(_("Can't insert file from outside of %s"),
operating_dir);
return;
}
#endif
#ifdef ENABLE_MULTIBUFFER
if (loading_file) {
/* update the current entry in the open_files structure */
add_open_file(TRUE);
new_file();
UNSET(MODIFIED);
#ifndef NANO_SMALL
UNSET(MARK_ISSET);
#endif
} }
#endif #endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (i == NANO_EXTCMD_KEY) { if (i == NANO_EXTCMD_KEY)
realname = mallocstrcpy(realname, ""); execute_command(answer);
opened = open_pipe(answer); else {
} else {
#endif #endif
realname = real_dir_from_tilde(answer); answer = mallocstrassn(answer, real_dir_from_tilde(answer));
opened = open_file(realname, TRUE, loading_file); load_buffer(answer);
#ifndef NANO_SMALL #ifndef NANO_SMALL
} }
#endif #endif
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (loading_file) { if (ISSET(MULTIBUFFER)) {
/* if there was an error opening the file, free() realname, /* Update the titlebar. */
free() fileage (which now points to the new buffer we titlebar(NULL);
created to hold the file), reload the buffer we had open
before, and skip the insertion; otherwise, save realname
in filename and continue the insertion */
if (!opened) {
free(realname);
free(fileage);
load_open_file();
goto skip_insert;
} else
filename = mallocstrcpy(filename, realname);
}
#endif
free(realname);
#ifdef DEBUG
dump_buffer(fileage);
#endif
#ifdef ENABLE_MULTIBUFFER /* Reinitialize the shortcut list. */
if (loading_file) shortcut_init(FALSE);
load_file(FALSE); } else {
else
#endif #endif
/* Mark the file as modified. */
set_modified(); set_modified();
/* Restore the old x-coordinate position. */
current_x = old_current_x;
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
/* If we've loaded another file, update the titlebar's contents */ }
if (loading_file) {
clearok(topwin, FALSE);
titlebar(NULL);
/* And re-init the shortcut list */
shortcut_init(FALSE);
} else
#endif #endif
/* Restore the old x-coordinate position */
current_x = old_current_x;
/* If we've gone off the bottom, recenter; otherwise, just redraw */ /* If we've gone off the bottom, recenter; otherwise, just redraw */
edit_refresh(); edit_refresh();
} else
} else {
statusbar(_("Cancelled")); statusbar(_("Cancelled"));
i = 0;
}
#ifdef ENABLE_MULTIBUFFER
skip_insert:
#endif
free(inspath); free(inspath);
inspath = NULL;
display_main_list();
} }
void do_insertfile_void(void) void do_insertfile_void(void)
{ {
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (ISSET(VIEW_MODE)) { if (ISSET(VIEW_MODE) && !ISSET(MULTIBUFFER))
if (ISSET(MULTIBUFFER)) statusbar(_("Key illegal in non-multibuffer mode"));
do_insertfile(TRUE);
else
statusbar(_("Key illegal in non-multibuffer mode"));
}
else else
do_insertfile(ISSET(MULTIBUFFER));
#else
do_insertfile(FALSE);
#endif #endif
do_insertfile();
display_main_list(); display_main_list();
} }
...@@ -1008,7 +953,7 @@ int close_open_file(void) ...@@ -1008,7 +953,7 @@ int close_open_file(void)
display_main_list(); display_main_list();
return 0; return 0;
} }
#endif /* MULTIBUFFER */ #endif /* ENABLE_MULTIBUFFER */
#if !defined(DISABLE_SPELLER) || !defined(DISABLE_OPERATINGDIR) || !defined(NANO_SMALL) #if !defined(DISABLE_SPELLER) || !defined(DISABLE_OPERATINGDIR) || !defined(NANO_SMALL)
/* /*
......
...@@ -367,7 +367,8 @@ void shortcut_init(int unjustify) ...@@ -367,7 +367,8 @@ void shortcut_init(int unjustify)
); );
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (open_files != NULL && (open_files->prev != NULL || open_files->next != NULL)) if (open_files != NULL && (open_files->prev != NULL ||
open_files->next != NULL))
/* Translators: try to keep this string under 10 characters long */ /* Translators: try to keep this string under 10 characters long */
sc_init_one(&main_list, NANO_EXIT_KEY, N_("Close"), sc_init_one(&main_list, NANO_EXIT_KEY, N_("Close"),
IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY, IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY,
......
...@@ -179,7 +179,7 @@ void die_save_file(const char *die_filename) ...@@ -179,7 +179,7 @@ void die_save_file(const char *die_filename)
if (!failed) if (!failed)
fprintf(stderr, _("\nBuffer written to %s\n"), ret); fprintf(stderr, _("\nBuffer written to %s\n"), ret);
else else
fprintf(stderr, _("\nNo %s written (too many backup files?)\n"), ret); fprintf(stderr, _("\nBuffer not written to %s (too many backup files?)\n"), ret);
free(ret); free(ret);
} }
...@@ -856,7 +856,7 @@ bool open_pipe(const char *command) ...@@ -856,7 +856,7 @@ bool open_pipe(const char *command)
if (f == NULL) if (f == NULL)
nperror("fdopen"); nperror("fdopen");
read_file(f, "stdin", FALSE); read_file(f, "stdin");
/* If multibuffer mode is on, we could be here in view mode. If so, /* If multibuffer mode is on, we could be here in view mode. If so,
* don't set the modification flag. */ * don't set the modification flag. */
if (!ISSET(VIEW_MODE)) if (!ISSET(VIEW_MODE))
...@@ -1406,7 +1406,7 @@ bool do_int_spell_fix(const char *word) ...@@ -1406,7 +1406,7 @@ bool do_int_spell_fix(const char *word)
bool reverse_search_set = ISSET(REVERSE_SEARCH); bool reverse_search_set = ISSET(REVERSE_SEARCH);
#ifndef NANO_SMALL #ifndef NANO_SMALL
bool case_sens_set = ISSET(CASE_SENSITIVE); bool case_sens_set = ISSET(CASE_SENSITIVE);
bool mark_set = ISSET(MARK_ISSET); bool old_mark_set = ISSET(MARK_ISSET);
SET(CASE_SENSITIVE); SET(CASE_SENSITIVE);
/* Make sure the marking highlight is off during spell-check. */ /* Make sure the marking highlight is off during spell-check. */
...@@ -1475,7 +1475,7 @@ bool do_int_spell_fix(const char *word) ...@@ -1475,7 +1475,7 @@ bool do_int_spell_fix(const char *word)
UNSET(CASE_SENSITIVE); UNSET(CASE_SENSITIVE);
/* Restore marking highlight. */ /* Restore marking highlight. */
if (mark_set) if (old_mark_set)
SET(MARK_ISSET); SET(MARK_ISSET);
#endif #endif
...@@ -1678,16 +1678,17 @@ const char *do_alt_speller(char *tempfile_name) ...@@ -1678,16 +1678,17 @@ const char *do_alt_speller(char *tempfile_name)
pid_t pid_spell; pid_t pid_spell;
char *ptr; char *ptr;
static int arglen = 3; static int arglen = 3;
static char **spellargs = (char **)NULL; static char **spellargs = NULL;
FILE *f;
#ifndef NANO_SMALL #ifndef NANO_SMALL
bool mark_set = ISSET(MARK_ISSET); bool old_mark_set = ISSET(MARK_ISSET);
int mbb_lineno_cur = 0; int mbb_lineno_cur = 0;
/* We're going to close the current file, and open the output of /* We're going to close the current file, and open the output of
* the alternate spell command. The line that mark_beginbuf * the alternate spell command. The line that mark_beginbuf
* points to will be freed, so we save the line number and * points to will be freed, so we save the line number and
* restore afterwards. */ * restore afterwards. */
if (mark_set) { if (old_mark_set) {
mbb_lineno_cur = mark_beginbuf->lineno; mbb_lineno_cur = mark_beginbuf->lineno;
UNSET(MARK_ISSET); UNSET(MARK_ISSET);
} }
...@@ -1738,7 +1739,7 @@ const char *do_alt_speller(char *tempfile_name) ...@@ -1738,7 +1739,7 @@ const char *do_alt_speller(char *tempfile_name)
refresh(); refresh();
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (mark_set) { if (old_mark_set) {
do_gotopos(mbb_lineno_cur, mark_beginx, y_cur, 0); do_gotopos(mbb_lineno_cur, mark_beginx, y_cur, 0);
mark_beginbuf = current; mark_beginbuf = current;
/* In case the line got shorter, assign mark_beginx. */ /* In case the line got shorter, assign mark_beginx. */
...@@ -1750,7 +1751,13 @@ const char *do_alt_speller(char *tempfile_name) ...@@ -1750,7 +1751,13 @@ const char *do_alt_speller(char *tempfile_name)
free_filestruct(fileage); free_filestruct(fileage);
terminal_init(); terminal_init();
global_init(TRUE); global_init(TRUE);
open_file(tempfile_name, FALSE, TRUE);
/* Do what load_buffer() would do, except for making a new
* buffer for the temp file if multibuffer support is
* available. */
open_file(tempfile_name, FALSE, &f);
read_file(f, tempfile_name);
current = fileage;
#ifndef NANO_SMALL #ifndef NANO_SMALL
} }
#endif #endif
...@@ -2564,6 +2571,7 @@ void do_justify(bool full_justify) ...@@ -2564,6 +2571,7 @@ void do_justify(bool full_justify)
edit_refresh(); edit_refresh();
statusbar(_("Can now UnJustify!")); statusbar(_("Can now UnJustify!"));
/* Display the shortcut list with UnJustify. */ /* Display the shortcut list with UnJustify. */
shortcut_init(TRUE); shortcut_init(TRUE);
display_main_list(); display_main_list();
...@@ -2618,6 +2626,7 @@ void do_justify(bool full_justify) ...@@ -2618,6 +2626,7 @@ void do_justify(bool full_justify)
cutbuffer = cutbuffer_save; cutbuffer = cutbuffer_save;
/* Note that now cutbottom is invalid, but that's okay. */ /* Note that now cutbottom is invalid, but that's okay. */
blank_statusbar(); blank_statusbar();
/* Display the shortcut list with UnCut. */ /* Display the shortcut list with UnCut. */
shortcut_init(FALSE); shortcut_init(FALSE);
display_main_list(); display_main_list();
...@@ -2940,11 +2949,19 @@ void terminal_init(void) ...@@ -2940,11 +2949,19 @@ void terminal_init(void)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int optchr; int optchr;
int startline = 0; /* Line to try and start at */ int startline = 0;
/* Line to try and start at. */
#ifndef DISABLE_WRAPJUSTIFY #ifndef DISABLE_WRAPJUSTIFY
bool fill_flag_used = FALSE; /* Was the fill option used? */ bool fill_flag_used = FALSE;
/* Was the fill option used? */
#endif #endif
int kbinput; /* Input from keyboard */ #ifdef ENABLE_MULTIBUFFER
bool old_multibuffer;
/* The old value of the multibuffer option, restored after we
* load all files on the command line. */
#endif
int kbinput;
/* Input from keyboard. */
bool meta_key; bool meta_key;
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
const struct option long_options[] = { const struct option long_options[] = {
...@@ -3015,8 +3032,8 @@ int main(int argc, char **argv) ...@@ -3015,8 +3032,8 @@ int main(int argc, char **argv)
#endif #endif
#if !defined(ENABLE_NANORC) && defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING) #if !defined(ENABLE_NANORC) && defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING)
/* if we don't have rcfile support, we're root, and /* If we don't have rcfile support, we're root, and
--disable-wrapping-as-root is used, turn wrapping off */ * --disable-wrapping-as-root is used, turn wrapping off. */
if (geteuid() == NANO_ROOT_UID) if (geteuid() == NANO_ROOT_UID)
SET(NO_WRAP); SET(NO_WRAP);
#endif #endif
...@@ -3190,8 +3207,8 @@ int main(int argc, char **argv) ...@@ -3190,8 +3207,8 @@ int main(int argc, char **argv)
} }
/* We've read through the command line options. Now back up the flags /* We've read through the command line options. Now back up the flags
and values that are set, and read the rcfile(s). If the values * and values that are set, and read the rcfile(s). If the values
haven't changed afterward, restore the backed-up values. */ * haven't changed afterward, restore the backed-up values. */
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
if (!ISSET(NO_RCFILE)) { if (!ISSET(NO_RCFILE)) {
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
...@@ -3336,43 +3353,26 @@ int main(int argc, char **argv) ...@@ -3336,43 +3353,26 @@ int main(int argc, char **argv)
#endif #endif
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC) #if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
/* If whitespace wasn't specified, set its default value. */
if (whitespace == NULL) if (whitespace == NULL)
whitespace = mallocstrcpy(NULL, " "); whitespace = mallocstrcpy(NULL, " ");
#endif #endif
/* If tabsize wasn't specified, set its default value. */
if (tabsize == -1) if (tabsize == -1)
tabsize = 8; tabsize = WIDTH_OF_TAB;
/* Clear the filename we'll be using */
filename = charalloc(1);
filename[0] = '\0';
/* If there's a +LINE flag, it is the first non-option argument. */ /* If there's a +LINE flag, it is the first non-option argument. */
if (0 < optind && optind < argc && argv[optind][0] == '+') { if (0 < optind && optind < argc && argv[optind][0] == '+') {
startline = atoi(&argv[optind][1]); startline = atoi(&argv[optind][1]);
optind++; optind++;
} }
if (0 < optind && optind < argc)
filename = mallocstrcpy(filename, argv[optind]);
/* See if there's a non-option in argv (first non-option is the
filename, if +LINE is not given) */
if (argc > 1 && argc > optind) {
/* Look for the +line flag... */
if (argv[optind][0] == '+') {
startline = atoi(&argv[optind][1]);
optind++;
if (argc > optind)
filename = mallocstrcpy(filename, argv[optind]);
} else
filename = mallocstrcpy(filename, argv[optind]);
}
/* Back up the old terminal settings so that they can be restored. */ /* Back up the old terminal settings so that they can be restored. */
tcgetattr(0, &oldterm); tcgetattr(0, &oldterm);
/* Curses initialization stuff: Start curses and set up the /* Curses initialization stuff: Start curses and set up the
* terminal state. */ * terminal state. */
initscr(); initscr();
terminal_init(); terminal_init();
...@@ -3392,44 +3392,55 @@ int main(int argc, char **argv) ...@@ -3392,44 +3392,55 @@ int main(int argc, char **argv)
mouse_init(); mouse_init();
#endif #endif
#ifdef DEBUG
fprintf(stderr, "Main: top and bottom win\n");
#endif
titlebar(NULL);
display_main_list();
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Main: open file\n"); fprintf(stderr, "Main: open file\n");
#endif #endif
open_file(filename, FALSE, FALSE);
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
/* If we're using multibuffers and more than one file is specified old_multibuffer = ISSET(MULTIBUFFER);
on the command line, load them all and switch to the first one SET(MULTIBUFFER);
afterward. */
if (optind + 1 < argc) { /* Read all the files after the first one on the command line into
bool old_multibuffer = ISSET(MULTIBUFFER), list = FALSE; * new buffers. */
SET(MULTIBUFFER); {
for (optind++; optind < argc; optind++) { int i;
add_open_file(TRUE); for (i = optind + 1; i < argc; i++)
new_file(); load_buffer(argv[i]);
filename = mallocstrcpy(filename, argv[optind]); }
titlebar(NULL); #endif
open_file(filename, FALSE, FALSE);
load_file(FALSE); /* Read the first file on the command line into either the current
/* Display the main list with "Close" if we haven't * buffer or a new buffer, depending on whether multibuffer mode is
* already. */ * enabled. */
if (!list) { if (optind < argc)
shortcut_init(FALSE); load_buffer(argv[optind]);
list = TRUE;
display_main_list(); /* We didn't open any files if all the command line arguments were
} * invalid files like directories or if there were no command line
} * arguments given. In this case, we have to load a blank buffer.
open_nextfile_void(); * Also, we unset view mode to allow editing. */
if (!old_multibuffer) if (filename == NULL) {
UNSET(MULTIBUFFER); filename = mallocstrcpy(NULL, "");
new_file();
UNSET(VIEW_MODE);
/* Add this new entry to the open_files structure if we have
* multibuffer support, or to the main filestruct if we don't. */
load_file();
} }
#ifdef ENABLE_MULTIBUFFER
if (!old_multibuffer)
UNSET(MULTIBUFFER);
#endif #endif
#ifdef DEBUG
fprintf(stderr, "Main: top and bottom win\n");
#endif
titlebar(NULL);
display_main_list();
if (startline > 0) if (startline > 0)
do_gotoline(startline, FALSE); do_gotoline(startline, FALSE);
......
...@@ -491,6 +491,9 @@ typedef enum { ...@@ -491,6 +491,9 @@ typedef enum {
* occurs. */ * occurs. */
#define CHARS_FROM_EOL 8 #define CHARS_FROM_EOL 8
/* Default width of a tab. */
#define WIDTH_OF_TAB 8
/* Maximum number of search history strings saved, same value used for /* Maximum number of search history strings saved, same value used for
* replace history. */ * replace history. */
#define MAX_SEARCH_HISTORY 100 #define MAX_SEARCH_HISTORY 100
......
...@@ -164,14 +164,18 @@ void do_cut_text(void); ...@@ -164,14 +164,18 @@ void do_cut_text(void);
void do_uncut_text(void); void do_uncut_text(void);
/* Public functions in files.c */ /* Public functions in files.c */
void load_file(int update);
void new_file(void); void new_file(void);
filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t filestruct *read_line(char *buf, filestruct *prev, bool *first_line_ins,
len); size_t len);
void read_file(FILE *f, const char *filename, int quiet); void load_file(void);
bool open_file(const char *filename, int insert, int quiet); void read_file(FILE *f, const char *filename);
int open_file(const char *filename, bool newfie, FILE **f);
char *get_next_filename(const char *name); char *get_next_filename(const char *name);
void do_insertfile(int loading_file); #ifndef NANO_SMALL
void execute_command(const char *command);
#endif
void load_buffer(const char *name);
void do_insertfile(void);
void do_insertfile_void(void); void do_insertfile_void(void);
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
openfilestruct *make_new_opennode(openfilestruct *prevnode); openfilestruct *make_new_opennode(openfilestruct *prevnode);
...@@ -411,7 +415,7 @@ int do_replace_loop(const char *needle, const filestruct *real_current, ...@@ -411,7 +415,7 @@ int do_replace_loop(const char *needle, const filestruct *real_current,
void do_replace(void); void do_replace(void);
void do_gotoline(int line, bool save_pos); void do_gotoline(int line, bool save_pos);
void do_gotoline_void(void); void do_gotoline_void(void);
#if defined (ENABLE_MULTIBUFFER) || !defined (DISABLE_SPELLER) #if defined(ENABLE_MULTIBUFFER) || !defined(DISABLE_SPELLER)
void do_gotopos(int line, int pos_x, int pos_y, size_t pos_pww); void do_gotopos(int line, int pos_x, int pos_y, size_t pos_pww);
#endif #endif
void do_find_bracket(void); void do_find_bracket(void);
...@@ -479,6 +483,7 @@ void nperror(const char *s); ...@@ -479,6 +483,7 @@ void nperror(const char *s);
void *nmalloc(size_t howmuch); void *nmalloc(size_t howmuch);
void *nrealloc(void *ptr, size_t howmuch); void *nrealloc(void *ptr, size_t howmuch);
char *mallocstrcpy(char *dest, const char *src); char *mallocstrcpy(char *dest, const char *src);
char *mallocstrassn(char *dest, char *src);
void new_magicline(void); void new_magicline(void);
#ifndef NANO_SMALL #ifndef NANO_SMALL
void mark_order(const filestruct **top, size_t *top_x, const filestruct void mark_order(const filestruct **top, size_t *top_x, const filestruct
......
...@@ -619,13 +619,13 @@ void parse_rcfile(FILE *rcstream) ...@@ -619,13 +619,13 @@ void parse_rcfile(FILE *rcstream)
} else } else
SET(rcopts[i].flag); SET(rcopts[i].flag);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "set flag %d!\n", fprintf(stderr, "set flag %ld!\n",
rcopts[i].flag); rcopts[i].flag);
#endif #endif
} else { } else {
UNSET(rcopts[i].flag); UNSET(rcopts[i].flag);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "unset flag %d!\n", fprintf(stderr, "unset flag %ld!\n",
rcopts[i].flag); rcopts[i].flag);
#endif #endif
} }
......
...@@ -616,7 +616,7 @@ int do_replace_loop(const char *needle, const filestruct *real_current, ...@@ -616,7 +616,7 @@ int do_replace_loop(const char *needle, const filestruct *real_current,
bool begin_line = FALSE, bol_or_eol = FALSE; bool begin_line = FALSE, bol_or_eol = FALSE;
#endif #endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
bool old_mark_isset = ISSET(MARK_ISSET); bool old_mark_set = ISSET(MARK_ISSET);
UNSET(MARK_ISSET); UNSET(MARK_ISSET);
edit_refresh(); edit_refresh();
...@@ -758,7 +758,7 @@ int do_replace_loop(const char *needle, const filestruct *real_current, ...@@ -758,7 +758,7 @@ int do_replace_loop(const char *needle, const filestruct *real_current,
new_magicline(); new_magicline();
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (old_mark_isset) if (old_mark_set)
SET(MARK_ISSET); SET(MARK_ISSET);
#endif #endif
......
...@@ -396,7 +396,7 @@ void *nrealloc(void *ptr, size_t howmuch) ...@@ -396,7 +396,7 @@ void *nrealloc(void *ptr, size_t howmuch)
} }
/* Copy one malloc()ed string to another pointer. Should be used as: /* Copy one malloc()ed string to another pointer. Should be used as:
* dest = mallocstrcpy(dest, src); */ * "dest = mallocstrcpy(dest, src);". */
char *mallocstrcpy(char *dest, const char *src) char *mallocstrcpy(char *dest, const char *src)
{ {
if (src == NULL) if (src == NULL)
...@@ -411,7 +411,16 @@ char *mallocstrcpy(char *dest, const char *src) ...@@ -411,7 +411,16 @@ char *mallocstrcpy(char *dest, const char *src)
return dest; return dest;
} }
/* Append a new magic-line to filebot. */ /* Free the malloc()ed string at dest and return the malloc()ed string
* at src. Should be used as: "answer = mallocstrassn(answer,
* real_dir_from_tilde(answer));". */
char *mallocstrassn(char *dest, char *src)
{
free(dest);
return src;
}
/* Append a new magicline to filebot. */
void new_magicline(void) void new_magicline(void)
{ {
filebot->next = (filestruct *)nmalloc(sizeof(filestruct)); filebot->next = (filestruct *)nmalloc(sizeof(filestruct));
......
...@@ -2385,13 +2385,15 @@ size_t get_page_start(size_t column) ...@@ -2385,13 +2385,15 @@ size_t get_page_start(size_t column)
} }
/* Resets current_y, based on the position of current, and puts the /* Resets current_y, based on the position of current, and puts the
* cursor at (current_y, current_x). */ * cursor in the edit window at (current_y, current_x). */
void reset_cursor(void) void reset_cursor(void)
{ {
/* Yuck. This condition can be true after open_file() when opening /* If we haven't opened any files yet, put the cursor in the top
* the first file. */ * left corner of the edit window and get out. */
if (edittop == NULL) if (edittop == NULL || current == NULL) {
wmove(edit, 0, 0);
return; return;
}
current_y = current->lineno - edittop->lineno; current_y = current->lineno - edittop->lineno;
if (current_y < editwinrows) { if (current_y < editwinrows) {
...@@ -2884,14 +2886,6 @@ void edit_redraw(const filestruct *old_current, size_t old_pww) ...@@ -2884,14 +2886,6 @@ void edit_redraw(const filestruct *old_current, size_t old_pww)
/* Refresh the screen without changing the position of lines. */ /* Refresh the screen without changing the position of lines. */
void edit_refresh(void) void edit_refresh(void)
{ {
/* Neither of these conditions should occur, but they do. edittop
* is NULL when you open an existing file on the command line, and
* ENABLE_COLOR is defined. Yuck. */
if (current == NULL)
return;
if (edittop == NULL)
edittop = current;
if (current->lineno < edittop->lineno || if (current->lineno < edittop->lineno ||
current->lineno >= edittop->lineno + editwinrows) current->lineno >= edittop->lineno + editwinrows)
/* Note that edit_update() changes edittop so that it's in range /* Note that edit_update() changes edittop so that it's in range
...@@ -2932,10 +2926,6 @@ void edit_update(topmidnone location) ...@@ -2932,10 +2926,6 @@ void edit_update(topmidnone location)
{ {
filestruct *foo = current; filestruct *foo = current;
/* We shouldn't need this check. Yuck. */
if (current == NULL)
return;
if (location != TOP) { if (location != TOP) {
/* If location is CENTER, we move edittop up (editwinrows / 2) /* If location is CENTER, we move edittop up (editwinrows / 2)
* lines. This puts current at the center of the screen. If * lines. This puts current at the center of the screen. If
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment