From 48b06708ff284c91703300426df5588c77f78836 Mon Sep 17 00:00:00 2001 From: Chris Allegretta Date: Fri, 22 Feb 2002 04:30:50 +0000 Subject: [PATCH] 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 --- ChangeLog | 12 ++- files.c | 216 +++++++++++++++--------------------------------------- global.c | 3 +- nano.1 | 3 + nano.c | 39 +++++----- nano.h | 1 - proto.h | 11 +-- utils.c | 15 ++++ 8 files changed, 116 insertions(+), 184 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7aac8d75..9a154a8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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). diff --git a/files.c b/files.c index 12fb009a..af75e57e 100644 --- a/files.c +++ b/files.c @@ -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 - diff --git a/global.c b/global.c index cb8b08e5..ad26f8e7 100644 --- a/global.c +++ b/global.c @@ -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; diff --git a/nano.1 b/nano.1 index 95ae6578..c4b1376c 100644 --- a/nano.1 +++ b/nano.1 @@ -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. diff --git a/nano.c b/nano.c index eef586aa..84545abb 100644 --- a/nano.c +++ b/nano.c @@ -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 " diff --git a/nano.h b/nano.h index c00cf8f0..697a7039 100644 --- a/nano.h +++ b/nano.h @@ -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 */ diff --git a/proto.h b/proto.h index fb0b2022..668b9e03 100644 --- a/proto.h +++ b/proto.h @@ -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 - - diff --git a/utils.c b/utils.c index 71c8193e..ed1c3068 100644 --- a/utils.c +++ b/utils.c @@ -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) { -- 2.39.5