X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fbackupfile.c;h=b0c39760747375692a3cad2087a40df01410c30f;hb=f90389a769861bdfeeed82dbbc71169017f2b56b;hp=b6a557df05dabcc1c76aa42176b2f0a14e0c5e1e;hpb=c125570a0c27088f009b9d536ee28f9ba37c608b;p=gnulib.git diff --git a/lib/backupfile.c b/lib/backupfile.c index b6a557df0..b0c397607 100644 --- a/lib/backupfile.c +++ b/lib/backupfile.c @@ -1,5 +1,6 @@ /* backupfile.c -- make Emacs style backup file names - Copyright (C) 1990-1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1990,91,92,93,94,95,96,97,98,99,2000, 2001, 2002 Free Software + Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,9 +24,6 @@ # include #endif -#include -#include - #include #include #if HAVE_STRING_H @@ -58,9 +56,21 @@ # define CLOSEDIR(d) closedir (d) #endif -#if STDC_HEADERS +#if HAVE_STDLIB_H # include -#else +#endif + +#ifndef HAVE_DECL_GETENV +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_GETENV +char *getenv (); +#endif + +#ifndef HAVE_DECL_MALLOC +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_MALLOC char *malloc (); #endif @@ -85,10 +95,9 @@ char *malloc (); - Its arg may be any int or unsigned int; it need not be an unsigned char. - It's guaranteed to evaluate its argument exactly once. - It's typically faster. - Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that - only '0' through '9' are digits. Prefer ISDIGIT to isdigit unless - it's important to use the locale's definition of `digit' even when the - host does not conform to Posix. */ + POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to + ISDIGIT_LOCALE unless it's important to use the locale's definition + of `digit' even when the host does not conform to POSIX. */ #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) #if D_INO_IN_DIRENT @@ -97,6 +106,10 @@ char *malloc (); # define REAL_DIR_ENTRY(dp) 1 #endif +#include "argmatch.h" +#include "backupfile.h" +#include "dirname.h" + /* The extension added to file names to produce a simple (as opposed to numbered) backup file name. */ const char *simple_backup_suffix = "~"; @@ -123,29 +136,31 @@ find_backup_file_name (const char *file, enum backup_type backup_type) if (HAVE_DIR && backup_suffix_size_max < numbered_suffix_size_max) backup_suffix_size_max = numbered_suffix_size_max; - s = malloc (file_len + backup_suffix_size_max + numbered_suffix_size_max); + s = malloc (file_len + 1 + + backup_suffix_size_max + numbered_suffix_size_max); if (s) { - strcpy (s, file); - #if HAVE_DIR if (backup_type != simple) { int highest_backup; - size_t dir_len = base_name (s) - s; + size_t dirlen = dir_len (file); - strcpy (s + dir_len, "."); - highest_backup = max_backup_version (file + dir_len, s); + memcpy (s, file, dirlen); + if (dirlen == FILESYSTEM_PREFIX_LEN (file)) + s[dirlen++] = '.'; + s[dirlen] = '\0'; + highest_backup = max_backup_version (base_name (file), s); if (! (backup_type == numbered_existing && highest_backup == 0)) { char *numbered_suffix = s + (file_len + backup_suffix_size_max); sprintf (numbered_suffix, ".~%d~", highest_backup + 1); suffix = numbered_suffix; } - strcpy (s, file); } #endif /* HAVE_DIR */ + strcpy (s, file); addext (s, suffix, '~'); } return s; @@ -172,7 +187,7 @@ max_backup_version (const char *file, const char *dir) return 0; highest_version = 0; - file_name_length = strlen (file); + file_name_length = base_len (file); while ((dp = readdir (dirp)) != 0) { @@ -214,25 +229,49 @@ version_number (const char *base, const char *backup, size_t base_length) static const char * const backup_args[] = { - "never", "simple", "nil", "existing", "t", "numbered", 0 + /* In a series of synonyms, present the most meaning full first, so + that argmatch_valid be more readable. */ + "none", "off", + "simple", "never", + "existing", "nil", + "numbered", "t", + 0 }; static const enum backup_type backup_types[] = { - simple, simple, numbered_existing, numbered_existing, numbered, numbered + none, none, + simple, simple, + numbered_existing, numbered_existing, + numbered, numbered }; -/* Return the type of backup indicated by VERSION. - Unique abbreviations are accepted. */ +/* Return the type of backup specified by VERSION. + If VERSION is NULL or the empty string, return numbered_existing. + If VERSION is invalid or ambiguous, fail with a diagnostic appropriate + for the specified CONTEXT. Unambiguous abbreviations are accepted. */ enum backup_type -get_version (const char *version) +get_version (const char *context, const char *version) { - enum backup_type type; if (version == 0 || *version == 0) - type = numbered_existing; + return numbered_existing; + else + return XARGMATCH (context, version, backup_args, backup_types); +} + + +/* Return the type of backup specified by VERSION. + If VERSION is NULL, use the value of the envvar VERSION_CONTROL. + If the specified string is invalid or ambiguous, fail with a diagnostic + appropriate for the specified CONTEXT. + Unambiguous abbreviations are accepted. */ + +enum backup_type +xget_version (const char *context, const char *version) +{ + if (version && *version) + return get_version (context, version); else - XARGMATCH (&type, "version control type", version, - backup_args, backup_types, exit (2)); - return type; + return get_version ("$VERSION_CONTROL", getenv ("VERSION_CONTROL")); }