3 source/backup.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 source/backup.h | 66 +++++++++++
5 2 files changed, 379 insertions(+)
7 diff --quilt /dev/null new/source/backup.c
9 +++ new/source/backup.c
11 +/* Copyright (c) 2000, Andy Hood. All rights reserved.
12 + Copyright (c) 1993,1994, Joseph Arceneaux. All rights reserved.
14 + This file is subject to the terms of the GNU General Public License as
15 + published by the Free Software Foundation. A copy of this license is
16 + included with this software distribution in the file COPYING. If you
17 + do not have a copy, you may obtain a copy by writing to the Free
18 + Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 + This software is distributed in the hope that it will be useful,
21 + but WITHOUT ANY WARRANTY; without even the implied warranty of
22 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 + GNU General Public License for more details. */
25 +/* GNU/Emacs style backups --
26 + This behaviour is controlled by two environment variables,
27 + VERSION_CONTROL and SIMPLE_BACKUP_SUFFIX.
29 + VERSION_CONTROL determines what kinds of backups are made. If it's
30 + value is "numbered", then the first modification of some file
31 + "eraserhead.c" will yield a backup file "eraserhead.c.~1~", the
32 + second modification will yield "eraserhead.c.~2~", and so on. It
33 + does not matter if the version numbers are not a sequence; the next
34 + version will be one greater than the highest in that directory.
36 + If the value of VERSION_CONTROL is "numbered_existing", then such
37 + numbered backups will be made if there are already numbered backup
38 + versions of the file. Otherwise, the backup name will be that of
39 + the original file with "~" (tilde) appended. E.g., "eraserhead.c~".
41 + If the value of VERSION_CONTROL is "simple", then the backup name
42 + will be that of the original file with "~" appended, regardless of
43 + whether or not there exist numbered versions in the directory.
45 + For simple backups, the value of SIMPLE_BACKUP_SUFFIX will be used
46 + rather than "~" if it is set.
48 + If VERSION_CONTROL is unset, "numbered_existing" is assumed. For
49 + Emacs lovers, "nil" is equivalent to "numbered_existing" and "t" is
50 + equivalent to "numbered".
52 + Finally, if VERSION_CONTROL is "none" or "never", backups are not
53 + made. I suggest you avoid this behaviour.
55 + Added, october 1999 (by Chris F.A. Johnson):
57 + If VERSION_WIDTH is set, then it controls zero padding of a numbered
60 +/* Written by jla, based on code from djm (see `patch') */
65 +#define ISDIGIT(c) (isdigit ((int) (c)))
67 +#define ISDIGIT(c) (isascii ((int)c) && isdigit ((int)c))
73 +# define NAMLEN(dirent) strlen((dirent)->d_name)
77 +#if defined (_POSIX_VERSION) /* Might be defined in unistd.h. */
78 +/* POSIX does not require that the d_ino field be present, and some
79 + systems do not provide it. */
80 +#define REAL_DIR_ENTRY(dp) 1
82 +#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
85 +#define generate_backup_filename(v,f) simple_backup_name((f))
88 +#ifndef BACKUP_SUFFIX_STR
89 +#define BACKUP_SUFFIX_STR ".bck"
92 +#ifndef BACKUP_SUFFIX_CHAR
93 +#define BACKUP_SUFFIX_CHAR '~'
96 +#ifndef BACKUP_SUFFIX_FORMAT
97 +#define BACKUP_SUFFIX_FORMAT "%s.~%0*d~"
100 +/* Default backup file suffix to use */
101 +static char *simple_backup_suffix = BACKUP_SUFFIX_STR;
102 +static enum backup_mode version_control = unset;
103 +int version_width = 1;
105 +/* Construct a simple backup name for PATHNAME by appending
106 + the value of `simple_backup_suffix'. */
109 +simple_backup_name (pathname)
115 + malloc (strlen (pathname) + strlen (simple_backup_suffix) + 2);
116 + sprintf (backup_name, "%s%s", pathname, simple_backup_suffix);
117 + return backup_name;
121 +/* If DIRENTRY is a numbered backup version of file BASE, return
122 + that number. BASE_LENGTH is the string length of BASE. */
125 +version_number (base, direntry, base_length)
134 + if (!strncmp (base, direntry, base_length)
135 + && ISDIGIT (direntry[base_length + 2]))
137 + for (p = &direntry[base_length + 2]; ISDIGIT (*p); ++p)
138 + version = version * 10 + *p - '0';
139 + if (p[0] != BACKUP_SUFFIX_CHAR || p[1])
147 +/* Return the highest version of file FILENAME in directory
148 + DIRNAME. Return 0 if there are no numbered versions. */
151 +highest_version (filename, dirname)
152 + char *filename, *dirname;
156 + int highest_version;
158 + int file_name_length;
160 + dirp = opendir (dirname);
164 + highest_version = 0;
165 + file_name_length = strlen (filename);
167 + while ((dp = readdir (dirp)) != 0)
169 + if (!REAL_DIR_ENTRY (dp) || NAMLEN (dp) <= file_name_length + 2)
172 + this_version = version_number (filename, dp->d_name, file_name_length);
173 + if (this_version > highest_version)
174 + highest_version = this_version;
178 + return highest_version;
182 +/* Return the highest version number for file PATHNAME. If there
183 + are no backups, or only a simple backup, return 0. */
186 +max_version (pathname)
191 + int pathlen = strlen (pathname);
194 + p = pathname + pathlen - 1;
195 + while (p > pathname && *p != '/')
200 + int dirlen = p - pathname;
204 + dirname = malloc (dirlen + 1);
205 + strncpy (dirname, pathname, (dirlen));
206 + dirname[dirlen] = '\0';
207 + version = highest_version (filename, dirname);
212 + filename = pathname;
213 + version = highest_version (filename, ".");
218 +/* Generate a backup filename for PATHNAME, dependent on the
219 + value of VERSION_CONTROL. */
222 +generate_backup_filename (version_control, pathname)
223 + enum backup_mode version_control;
226 + int last_numbered_version;
229 + if (version_control == none)
232 + if (version_control == simple)
233 + return simple_backup_name (pathname);
235 + last_numbered_version = max_version (pathname);
236 + if (version_control == numbered_existing && last_numbered_version == 0)
237 + return simple_backup_name (pathname);
239 + last_numbered_version++;
240 + backup_name = malloc (strlen (pathname) + 16);
244 + sprintf (backup_name, BACKUP_SUFFIX_FORMAT, pathname, version_width,
245 + (int) last_numbered_version);
247 + return backup_name;
252 +static struct version_control_values values[] = {
253 + {none, "never"}, /* Don't make backups. */
254 + {none, "none"}, /* Ditto */
255 + {simple, "simple"}, /* Only simple backups */
256 + {numbered_existing, "existing"}, /* Numbered if they already exist */
257 + {numbered_existing, "nil"}, /* Ditto */
258 + {numbered, "numbered"}, /* Numbered backups */
259 + {numbered, "t"}, /* Ditto */
260 + {unknown, 0} /* Initial, undefined value. */
264 +/* Determine the value of `version_control' by looking in the
265 + environment variable "VERSION_CONTROL". Defaults to
266 + numbered_existing. */
269 +version_control_value ()
272 + struct version_control_values *v;
274 + version = getenv ("VERSION_CONTROL");
275 + if (version == 0 || *version == 0)
276 + return numbered_existing;
281 + if (strcmp (version, v->name) == 0)
290 +/* Initialize information used in determining backup filenames. */
293 +set_version_width(void)
295 + char *v = getenv ("VERSION_WIDTH");
296 + if (v && ISDIGIT(*v))
297 + version_width = atoi(v);
298 + if (version_width > 16)
299 + version_width = 16;
303 +initialize_backups ()
305 + char *v = getenv ("SIMPLE_BACKUP_SUFFIX");
308 + simple_backup_suffix = v;
310 + version_control = simple;
312 + version_control = version_control_value ();
313 + if (version_control == unknown)
315 + fprintf (stderr, "nedit: Strange version-control value\n");
316 + fprintf (stderr, "nedit: Using numbered-existing\n");
317 + version_control = numbered_existing;
320 + set_version_width ();
324 diff --quilt /dev/null new/source/backup.h
326 +++ new/source/backup.h
328 +/* Copyright (c) 2000, Andy Hood. All rights reserved.
329 + Copyright (c) 1999, Carlo Wood. All rights reserved.
330 + Copyright (c) 1993,1994, Joseph Arceneaux. All rights reserved.
332 + This file is subject to the terms of the GNU General Public License as
333 + published by the Free Software Foundation. A copy of this license is
334 + included with this software distribution in the file COPYING. If you
335 + do not have a copy, you may obtain a copy by writing to the Free
336 + Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
338 + This software is distributed in the hope that it will be useful,
339 + but WITHOUT ANY WARRANTY; without even the implied warranty of
340 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
341 + GNU General Public License for more details. */
343 +#ifndef NEDIT_BACKUP_H
344 +#define NEDIT_BACKUP_H
347 +RCSTAG_H (backup, "$Id: backup.h,v 1.6 1999/08/07 12:54:31 carlo Exp $");
352 +/* When to make backup files. Analagous to 'version-control' in Emacs. */
355 + /* Uninitialized */
358 + /* Uninitialized or indeterminate value */
361 + /* Never make backups. */
364 + /* Make simple backups of every file. */
367 + /* Make numbered backups of files that already have numbered backups,
368 + and simple backups of the others. */
371 + /* Make numbered backups of every file. */
375 +struct version_control_values
377 + enum backup_mode value;
381 +/* Determine the value of `version_control' by looking in the environment
382 + variable "VERSION_CONTROL". Defaults to numbered_existing. */
383 +extern enum backup_mode version_control_value(void);
385 +/* Initialize information used in determining backup filenames. */
386 +extern void initialize_backups(void);
388 +/* Make a filename to use for backup. */
390 +generate_backup_filename(enum backup_mode version_control, char *pathname);
391 +#endif /* NEDIT_BACKUP_H */