Multiple unnamed buffers allowed, multiple filename extensions on die_save_file(), more DLR fixes

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1081 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2002-02-22 04:30:50 +00:00
parent 3a6d70dfb6
commit 48b06708ff
8 changed files with 116 additions and 184 deletions

View File

@ -5,20 +5,26 @@ CVS code -
the translation of files from DOS or Mac format (DLR).
- New functions wheck_writable_directory() and safe_tempnam()
to get around the tempnam warning. More improvements (DLR)
Still eeds testing.
Still needs testing.
- Added DOS and Mac format options to write file routine.
Changes to shortcut_init() and do_writeout().
- Removed stupid static definitions of toggles and shortcut
lists. Many changes to shortcut_init(), toggle_init(),
statusq(), nanogetstr(), main(), and many other places.
FIXME: Mouse support broken by this change.
- Multibuffer mode now allows multiple empty filenames.
Changes to add_open_files(), removed open_file_dup_search(),
open_file_dup_fix(), etc (DLR).
- New code to handle multiple .save files. Changes to
die_save_file(), new function files.c:get_next_filename()
and utils.c:num_of_digits(). (Dwayne Rightler, DLR & Chris)
- Makefile.am:
- Add SYSCONFDIR to DEFS, so we can have an /etc/nanorc.
- Change localedir line to 1.0's version.
- files.c:
read_byte()
- Added check for conrol characters (indicative of a binary
file), set NO_CONVERT if found.
file), set NO_CONVERT if found (fixes by DLR).
- global.c:
- Move openprev and opennext functions to shortcuts, they really
aren't toggles (DLR).
@ -28,6 +34,8 @@ CVS code -
for *ptr+1 is not the end of the regex.
do_rcfile()
- Parse rcfile in $SYSCONFDIR as well (Dwayne Rightler).
- nano.1:
- Added Noconvert option to man page (DLR).
- nano.c:
help_init()
- Added message re: having multiple blank buffers (DLR).

216
files.c
View File

@ -54,18 +54,10 @@ void load_file(int quiet)
current = fileage;
#ifdef ENABLE_MULTIBUFFER
/* if quiet is zero, add a new entry to the open_files structure, and
do duplicate checking; otherwise, update the current entry and
don't do duplicate checking (the latter is needed in the case of
the alternate spell checker); if a duplicate entry was found,
reload the currently open file (it may have been changed during
duplicate handling) */
if (quiet != 0)
quiet = 1;
if (add_open_file(quiet, 1 - quiet) == 2) {
load_open_file();
statusbar(_("File already loaded"));
}
/* if quiet 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(quiet);
#endif
wmove(edit, current_y, current_x);
@ -89,12 +81,11 @@ void new_file(void)
#ifdef ENABLE_MULTIBUFFER
/* if there aren't any entries in open_files, create the entry for
this new file, and, of course, don't bother checking for
duplicates; 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, leading to problems later on */
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, leading to problems later on */
if (!open_files) {
add_open_file(0, 0);
add_open_file(0);
/* turn off view mode in this case; this is for consistency
whether multibuffers are compiled in or not */
UNSET(VIEW_MODE);
@ -210,8 +201,9 @@ int read_file(int fd, char *filename, int quiet)
buf[0] = 0;
i = 0;
#ifndef NANO_SMALL
} else if (!ISSET(NO_CONVERT) && input[0] < 32
&& input[0] != '\r' && input[0] != '\n')
} else if (!ISSET(NO_CONVERT) && input[0] >= 0 && input[0] <= 31
&& input[0] != '\t' && input[0] != '\r'
&& input[0] != '\n')
/* If the file has binary chars in it, don't stupidly
assume it's a DOS or Mac formatted file! */
SET(NO_CONVERT);
@ -295,9 +287,8 @@ int open_file(char *filename, int insert, int quiet)
struct stat fileinfo;
if (!strcmp(filename, "") || stat(filename, &fileinfo) == -1) {
if (insert) {
if (!quiet)
statusbar(_("\"%s\" not found"), filename);
if (insert && !quiet) {
statusbar(_("\"%s\" not found"), filename);
return -1;
} else {
/* We have a new file */
@ -332,6 +323,38 @@ int open_file(char *filename, int insert, int quiet)
return 1;
}
/* This function will return the name of the first available extension
of a filename (starting with the filename, then filename.1, etc).
Memory is allocated for the return value. If no writable extension
exists we return "" */
char *get_next_filename(char *name)
{
int i = 0;
char *buf = NULL;
struct stat fs;
buf = charalloc(strlen(name) + num_of_digits(INT_MAX) + 2);
strcpy(buf, name);
while(1) {
if (stat(buf, &fs) == -1)
break;
if (i == INT_MAX)
break;
i++;
strcpy(buf, name);
sprintf(&buf[strlen(name)], ".%d", i);
}
if (i == INT_MAX)
buf[0] = '\0';
return buf;
}
int do_insertfile(int loading_file)
{
int i;
@ -386,10 +409,8 @@ int do_insertfile(int loading_file)
#ifdef ENABLE_MULTIBUFFER
if (loading_file) {
/* update the current entry in the open_files structure; we
don't need to check for duplicate entries (the conditions
that could create them are taken care of elsewhere) */
add_open_file(1, 0);
/* update the current entry in the open_files structure */
add_open_file(1);
free_filestruct(fileage);
new_file();
@ -397,7 +418,7 @@ int do_insertfile(int loading_file)
}
#endif
i = open_file(realname, 1, 0);
i = open_file(realname, 1, loading_file);
#ifdef ENABLE_MULTIBUFFER
if (loading_file)
@ -471,25 +492,15 @@ int do_insertfile_void(void)
/*
* Add/update an entry to the open_files filestruct. If update is
* zero, a new entry is created; otherwise, the current entry is updated.
* If dup_fix is zero, checking for and handling duplicate entries is not
* done; otherwise, it is. Return 0 on success, 1 on error, or 2 on
* finding a duplicate entry.
* Return 0 on success or 1 on error.
*/
int add_open_file(int update, int dup_fix)
int add_open_file(int update)
{
filestruct *tmp;
if (!fileage || !current || !filename)
return 1;
/* first, if duplicate checking is allowed, do it */
if (dup_fix) {
/* if duplicates were found and handled, we're done */
if (open_file_dup_fix(update))
return 2;
}
/* if no entries, make the first one */
if (!open_files) {
open_files = make_new_node(NULL);
@ -520,9 +531,6 @@ int add_open_file(int update, int dup_fix)
/* save current filename */
open_files->data = mallocstrcpy(open_files->data, filename);
/* save the full path location */
open_files->file_path = get_full_path(open_files->data);
/* save current total number of lines */
open_files->file_totlines = totlines;
@ -574,9 +582,6 @@ int open_file_change_name(void)
/* save current filename */
open_files->data = mallocstrcpy(open_files->data, filename);
/* save the full path location */
open_files->file_path = get_full_path(open_files->data);
return 0;
}
@ -629,95 +634,6 @@ int load_open_file(void)
return 0;
}
/*
* Search the open_files structure for an entry with the same value for
* the file_path member as the current entry (i. e. a duplicate entry).
* If one is found, return a pointer to it; otherwise, return NULL.
*
* Note: This should only be called inside open_file_dup_fix().
*/
filestruct *open_file_dup_search(int update)
{
filestruct *tmp;
char *path;
if (!open_files || !filename)
return NULL;
tmp = open_files;
path = get_full_path(filename);
/* if there's only one entry, handle it */
if (!tmp->prev && !tmp->next) {
if (!strcmp(tmp->file_path, path))
return tmp;
}
/* otherwise, go to the beginning */
while (tmp->prev)
tmp = tmp->prev;
/* and search the entries one by one */
while (tmp) {
if (!strcmp(tmp->file_path, path)) {
if (!update)
/* if we're making a new entry and there's an entry with
the same full path, we've found a duplicate */
return tmp;
else {
/* if we're updating an existing entry and there's an
entry with the same full path that isn't the current
entry, we've found a duplicate */
if (tmp != open_files)
return tmp;
}
}
/* go to the next entry */
tmp = tmp->next;
}
return NULL;
}
/*
* Search for duplicate entries in the open_files structure using
* open_file_dup_search(), and, if one is found, handle it properly.
* Return 0 if no duplicates were found, and 1 otherwise.
*/
int open_file_dup_fix(int update)
{
filestruct *tmp = open_file_dup_search(update);
if (!tmp)
return 0;
/* if there's only one entry, handle it */
if (!tmp->prev && !tmp->next)
return 1;
/* otherwise, if we're not updating, the user's trying to load a
duplicate; switch to the original instead */
if (!update) {
open_files = tmp;
return 1;
}
/* if we are updating, the filename's been changed via a save; it's
thus more recent than the original, so remove the original */
else {
unlink_node(tmp);
free_filestruct(tmp->file);
free(tmp->file_path);
delete_node(tmp);
}
return 0;
}
/*
* Open the previous entry in the open_files structure. If closing_file
* is zero, update the current entry before switching from it.
@ -730,10 +646,9 @@ int open_prevfile(int closing_file)
return 1;
/* if we're not about to close the current entry, update it before
doing anything; since we're only switching, we don't need to check
for duplicate entries */
doing anything */
if (!closing_file)
add_open_file(1, 0);
add_open_file(1);
if (!open_files->prev && !open_files->next) {
@ -792,10 +707,9 @@ int open_nextfile(int closing_file)
return 1;
/* if we're not about to close the current entry, update it before
doing anything; since we're only switching, we don't need to check
for duplicate entries */
doing anything */
if (!closing_file)
add_open_file(1, 0);
add_open_file(1);
if (!open_files->prev && !open_files->next) {
@ -862,7 +776,6 @@ int close_open_file(void)
unlink_node(tmp);
free_filestruct(tmp->file);
free(tmp->file_path);
delete_node(tmp);
shortcut_init(0);
@ -871,7 +784,7 @@ int close_open_file(void)
}
#endif /* MULTIBUFFER */
#if defined (ENABLE_MULTIBUFFER) || !defined (DISABLE_SPELLER) || !defined (DISABLE_OPERATINGDIR)
#if !defined (DISABLE_SPELLER) || !defined (DISABLE_OPERATINGDIR)
/*
* When passed "[relative path]" or "[relative path][filename]" in
* origpath, return "[full path]" or "[full path][filename]" on success,
@ -1020,7 +933,7 @@ char *get_full_path(const char *origpath)
return newpath;
}
#endif /* ENABLE_MULTIBUFFER || !DISABLE_SPELLER || !DISABLE_OPERATINGDIR */
#endif /* !DISABLE_SPELLER || !DISABLE_OPERATINGDIR */
#ifndef DISABLE_SPELLER
/*
@ -1602,18 +1515,16 @@ int do_writeout(char *path, int exiting, int append)
if (!exiting) {
/* first, if the filename was changed during the save,
update the filename and full path stored in the
current entry, and then update the current entry,
checking for duplicate entries */
update the filename stored in the current entry, and
then update the current entry */
if (strcmp(open_files->data, filename)) {
open_file_change_name();
add_open_file(1, 1);
add_open_file(1);
}
else {
/* otherwise, just update the current entry without
checking for duplicate entries */
add_open_file(1, 0);
/* otherwise, just update the current entry */
add_open_file(1);
}
}
#endif
@ -2127,7 +2038,6 @@ int diralphasort(const void *va, const void *vb) {
}
/* Initialize the browser code, including the list of files in *path */
char **browser_init(char *path, int *longest, int *numents)
{
@ -2618,8 +2528,4 @@ char *do_browse_from(char *inpath)
return do_browser(tmp);
}
#endif

View File

@ -35,6 +35,7 @@
/*
* Global variables
*/
int flags = 0; /* Our new flag containing many options */
WINDOW *edit; /* The file portion of the editor */
WINDOW *topwin; /* Top line of screen */
@ -87,7 +88,7 @@ char *alt_speller; /* Alternative spell command */
shortcut *main_list = NULL;
shortcut *whereis_list = NULL;
shortcut *replace_list = NULL;
shortcut *replace_list_2; /* 2nd half of replace dialog */
shortcut *replace_list_2 = NULL; /* 2nd half of replace dialog */
shortcut *goto_list = NULL;
shortcut *gotodir_list = NULL;
shortcut *writefile_list = NULL;

3
nano.1
View File

@ -45,6 +45,9 @@ under nano.
.B \-M (\-\-mac)
Write file in Mac format.
.TP
.B \-N (\-\-noconvert)
Disable automatic conversion of files from DOS/Mac format.
.TP
.B \-R (\-\-regexp)
Enable regular expression matching for search strings, as well as
\\n subexpression replacement for replace strings, if available.

39
nano.c
View File

@ -158,27 +158,34 @@ void die(char *msg, ...)
void die_save_file(char *die_filename)
{
char *name;
int i;
char *name, *ret;
int i = -1;
/* if we can't save we have REAL bad problems,
* but we might as well TRY. */
if (die_filename[0] == '\0') {
name = "nano.save";
i = write_file(name, 1, 0, 0);
} else {
ret = get_next_filename(name);
if (strcmp(ret, ""))
i = write_file(ret, 1, 0, 0);
name = ret;
}
else {
char *buf = charalloc(strlen(die_filename) + 6);
strcpy(buf, die_filename);
strcat(buf, ".save");
i = write_file(buf, 1, 0, 0);
name = buf;
ret = get_next_filename(buf);
if (strcmp(ret, ""))
i = write_file(ret, 1, 0, 0);
name = ret;
}
if (i != -1)
fprintf(stderr, _("\nBuffer written to %s\n"), name);
else
fprintf(stderr, _("\nNo %s written (file exists?)\n"), name);
fprintf(stderr, _("\nNo %s written (too many backup files?)\n"), name);
free(ret);
}
/* Die with an error message that the screen was too small if, well, the
@ -1744,9 +1751,8 @@ int do_spell(void)
#ifdef ENABLE_MULTIBUFFER
/* update the current open_files entry before spell-checking, in case
any problems occur; the case of there being no open_files entries
is handled elsewhere (before we reach this point); no duplicate
checking is needed here */
add_open_file(1, 0);
is handled elsewhere (before we reach this point) */
add_open_file(1);
#endif
if (alt_speller)
@ -2454,12 +2460,11 @@ void help_init(void)
"or --multibuffer command line flags, the Meta-F toggle or "
"using a nanorc file, inserting a file will cause it to be "
"loaded into a separate buffer (use Meta-< and > to switch "
"between file buffers).\n\n In multiple buffer mode, the "
"same file cannot be loaded twice, not even a \"New "
"Buffer.\" A workaround to load another blank buffer is to "
"load a nonexistent filename into a separate buffer.\n\n "
"The following function keys are available in Insert File "
"mode:\n\n");
"between file buffers).\n\n If you need another blank "
"buffer, just press Enter at the prompt without typing in a "
"filename, or type in a nonexistent filename at the prompt "
"and press Enter.\n\n The following function keys are "
"available in Insert File mode:\n\n");
else if (currshortcut == writefile_list)
ptr = _("Write File Help Text\n\n "
"Type the name that you wish to save the current file "

1
nano.h
View File

@ -79,7 +79,6 @@ typedef struct filestruct {
int file_current_x; /* Current file's x-coordinate position */
int file_current_y; /* Current file's y-coordinate position */
int file_modified; /* Current file's modification status */
char *file_path; /* Current file's full path location */
int file_placewewant; /* Current file's place we want */
int file_totlines; /* Current file's total number of lines */
long file_totsize; /* Current file's total size */

11
proto.h
View File

@ -104,9 +104,10 @@ int renumber_all(void);
int open_file(char *filename, int insert, int quiet);
int do_insertfile(int loading_file);
int length_of_list(shortcut *s);
int num_of_digits(int n);
#ifdef ENABLE_MULTIBUFFER
int add_open_file(int update, int dup_fix);
int add_open_file(int update);
#endif
#ifndef DISABLE_OPERATINGDIR
@ -212,12 +213,12 @@ int do_replace(void), do_help(void), do_enter_void(void);
int keypad_on(WINDOW * win, int newval);
#ifdef ENABLE_MULTIBUFFER
int open_file_dup_fix(int update);
int open_prevfile(int closing_file), open_nextfile(int closing_file);
int open_prevfile_void(void), open_nextfile_void(void);
#endif
char *charalloc (size_t howmuch);
char *get_next_filename(char *name);
#if defined (ENABLE_MULTIBUFFER) || !defined (DISABLE_SPELLER) || !defined (DISABLE_OPERATINGDIR)
char *get_full_path(const char *origpath);
@ -250,12 +251,6 @@ filestruct *make_new_node(filestruct * prevnode);
filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin,
int beginx, char *needle);
#ifdef ENABLE_MULTIBUFFER
filestruct *open_file_dup_search(int update);
#endif
#ifndef DISABLE_HELP
void help_init(void);
#endif

15
utils.c
View File

@ -36,6 +36,21 @@
#define _(string) (string)
#endif
int num_of_digits(int n)
{
int i = 1;
if (n < 0)
n = 0 - n;
while (n > 10) {
n /= 10;
i++;
}
return i;
}
/* Lower case a string - must be null terminated */
void lowercase(char *src)
{