extend-for-key-in-array-syntax: update to key=val syntax
[nedit-bw.git] / enhanced-backup-files.patch
blob37e2f8f44fe679dbe1f70e9f51ba0981e1decf2b
1 ---
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
8 --- /dev/null
9 +++ new/source/backup.c
10 @@ -0,0 +1,313 @@
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
58 + suffix. */
60 +/* Written by jla, based on code from djm (see `patch') */
62 +#include <ctype.h>
63 +#include <string.h>
64 +#ifndef isascii
65 +#define ISDIGIT(c) (isdigit ((int) (c)))
66 +#else
67 +#define ISDIGIT(c) (isascii ((int)c) && isdigit ((int)c))
68 +#endif
69 +#include <unistd.h>
70 +#include <stdio.h>
71 +#include <stdlib.h>
72 +#include <dirent.h>
73 +# define NAMLEN(dirent) strlen((dirent)->d_name)
74 +#include "backup.h"
76 +#ifndef NODIR
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
81 +#else
82 +#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
83 +#endif
84 +#else /* NODIR */
85 +#define generate_backup_filename(v,f) simple_backup_name((f))
86 +#endif /* NODIR */
88 +#ifndef BACKUP_SUFFIX_STR
89 +#define BACKUP_SUFFIX_STR ".bck"
90 +#endif
92 +#ifndef BACKUP_SUFFIX_CHAR
93 +#define BACKUP_SUFFIX_CHAR '~'
94 +#endif
96 +#ifndef BACKUP_SUFFIX_FORMAT
97 +#define BACKUP_SUFFIX_FORMAT "%s.~%0*d~"
98 +#endif
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'. */
108 +static char *
109 +simple_backup_name (pathname)
110 + char *pathname;
112 + char *backup_name;
114 + backup_name =
115 + malloc (strlen (pathname) + strlen (simple_backup_suffix) + 2);
116 + sprintf (backup_name, "%s%s", pathname, simple_backup_suffix);
117 + return backup_name;
120 +#ifndef NODIR
121 +/* If DIRENTRY is a numbered backup version of file BASE, return
122 + that number. BASE_LENGTH is the string length of BASE. */
124 +static int
125 +version_number (base, direntry, base_length)
126 + char *base;
127 + char *direntry;
128 + int base_length;
130 + int version;
131 + char *p;
133 + version = 0;
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])
140 + version = 0;
143 + return version;
147 +/* Return the highest version of file FILENAME in directory
148 + DIRNAME. Return 0 if there are no numbered versions. */
150 +static int
151 +highest_version (filename, dirname)
152 + char *filename, *dirname;
154 + DIR *dirp;
155 + struct dirent *dp;
156 + int highest_version;
157 + int this_version;
158 + int file_name_length;
160 + dirp = opendir (dirname);
161 + if (!dirp)
162 + return 0;
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)
170 + continue;
172 + this_version = version_number (filename, dp->d_name, file_name_length);
173 + if (this_version > highest_version)
174 + highest_version = this_version;
177 + closedir (dirp);
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. */
185 +static int
186 +max_version (pathname)
187 + char *pathname;
189 + char *p;
190 + char *filename;
191 + int pathlen = strlen (pathname);
192 + int version;
194 + p = pathname + pathlen - 1;
195 + while (p > pathname && *p != '/')
196 + p--;
198 + if (*p == '/')
200 + int dirlen = p - pathname;
201 + char *dirname;
203 + filename = p + 1;
204 + dirname = malloc (dirlen + 1);
205 + strncpy (dirname, pathname, (dirlen));
206 + dirname[dirlen] = '\0';
207 + version = highest_version (filename, dirname);
208 + free (dirname);
209 + return version;
212 + filename = pathname;
213 + version = highest_version (filename, ".");
214 + return version;
218 +/* Generate a backup filename for PATHNAME, dependent on the
219 + value of VERSION_CONTROL. */
221 +char *
222 +generate_backup_filename (version_control, pathname)
223 + enum backup_mode version_control;
224 + char *pathname;
226 + int last_numbered_version;
227 + char *backup_name;
229 + if (version_control == none)
230 + return 0;
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);
241 + if (!backup_name)
242 + return 0;
244 + sprintf (backup_name, BACKUP_SUFFIX_FORMAT, pathname, version_width,
245 + (int) last_numbered_version);
247 + return backup_name;
250 +#endif /* !NODIR */
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. */
268 +enum backup_mode
269 +version_control_value ()
271 + char *version;
272 + struct version_control_values *v;
274 + version = getenv ("VERSION_CONTROL");
275 + if (version == 0 || *version == 0)
276 + return numbered_existing;
278 + v = &values[0];
279 + while (v->name)
281 + if (strcmp (version, v->name) == 0)
282 + return v->value;
283 + v++;
286 + return unknown;
290 +/* Initialize information used in determining backup filenames. */
292 +void
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;
302 +void
303 +initialize_backups ()
305 + char *v = getenv ("SIMPLE_BACKUP_SUFFIX");
307 + if (v && *v)
308 + simple_backup_suffix = v;
309 +#ifdef NODIR
310 + version_control = simple;
311 +#else /* !NODIR */
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;
319 +#endif /* !NODIR */
320 + set_version_width ();
324 diff --quilt /dev/null new/source/backup.h
325 --- /dev/null
326 +++ new/source/backup.h
327 @@ -0,0 +1,66 @@
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 $");
349 +#include "io.h"
352 +/* When to make backup files. Analagous to 'version-control' in Emacs. */
353 +enum backup_mode
355 + /* Uninitialized */
356 + unset,
358 + /* Uninitialized or indeterminate value */
359 + unknown,
361 + /* Never make backups. */
362 + none,
364 + /* Make simple backups of every file. */
365 + simple,
367 + /* Make numbered backups of files that already have numbered backups,
368 + and simple backups of the others. */
369 + numbered_existing,
371 + /* Make numbered backups of every file. */
372 + numbered
375 +struct version_control_values
377 + enum backup_mode value;
378 + char *name;
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. */
389 +char *
390 +generate_backup_filename(enum backup_mode version_control, char *pathname);
391 +#endif /* NEDIT_BACKUP_H */