aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2013-07-09 23:26:23 -0700
committerPaul Eggert2013-07-09 23:26:23 -0700
commit954b166e9037de5fdd43b4fbe7b8c73a36ac402e (patch)
tree4a1aa065be1ec87b53fdaff13f1129863ba2ebb5
parent56973319b58a66e97ae45e050f9f943ff8f1439b (diff)
downloademacs-954b166e9037de5fdd43b4fbe7b8c73a36ac402e.tar.gz
emacs-954b166e9037de5fdd43b4fbe7b8c73a36ac402e.zip
Timestamp fixes for undo.
* doc/lispref/text.texi (Undo): Document (t . 0) and (t . -1) in buffer-undo-list. * etc/NEWS: Changes to visited-file-modtime, set-visited-file-modtime. * lisp/files.el (clear-visited-file-modtime): Move here from fileio.c. * src/atimer.c (schedule_atimer): * src/fileio.c (Ffile_newer_than_file_p): Minor cleanup: use EMACS_TIME_LT so that we can remove EMACS_TIME_GT. * src/buffer.c (buffer-undo-list): Document (t . 0) and (t . -1). * src/fileio.c (Fclear_visited_file_modtime): Move to lisp/files.el. (syms_of_fileio): Remove Sclear_visited_file_name. (Fvisited_file_modtime): Return -1, not (-1 ...), when the visited file doesn't exist; this avoids an ambiguity with negative timestamps. (Fset_visited_file_modtime): Accept -1 and 0 as time-list arg. * src/systime.h (make_emacs_time, invalid_emacs_time): Don't assume struct timespec layout; POSIX doesn't guarantee it. (EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE): Remove. * src/undo.c (record_first_change): Push (visited-file-modtime) onto undo list rather than reimplementing it by hand, incorrectly. Fixes: debbugs:14824
-rw-r--r--doc/lispref/ChangeLog5
-rw-r--r--doc/lispref/text.texi12
-rw-r--r--etc/ChangeLog5
-rw-r--r--etc/NEWS6
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/files.el5
-rw-r--r--src/ChangeLog18
-rw-r--r--src/atimer.c2
-rw-r--r--src/buffer.c5
-rw-r--r--src/fileio.c46
-rw-r--r--src/systime.h23
-rw-r--r--src/undo.c7
12 files changed, 86 insertions, 53 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index e4bc6eb5bcc..f8b7406c427 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,8 @@
12013-07-10 Paul Eggert <eggert@cs.ucla.edu>
2
3 Timestamp fixes for undo (Bug#14824).
4 * text.texi (Undo): Document (t . 0) and (t . -1) in buffer-undo-list.
5
12013-07-06 Eli Zaretskii <eliz@gnu.org> 62013-07-06 Eli Zaretskii <eliz@gnu.org>
2 7
3 * nonascii.texi (Text Representations): Document that 8 * nonascii.texi (Text Representations): Document that
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index c10458b39ae..7cace70ad07 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -1250,14 +1250,18 @@ reinsert it is @code{(abs @var{position})}. If @var{position} is
1250positive, point was at the beginning of the deleted text, otherwise it 1250positive, point was at the beginning of the deleted text, otherwise it
1251was at the end. 1251was at the end.
1252 1252
1253@item (t @var{sec-high} @var{sec-low} @var{microsec} @var{picosec}) 1253@item (t . @var{time-flag})
1254This kind of element indicates that an unmodified buffer became 1254This kind of element indicates that an unmodified buffer became
1255modified. The list @code{(@var{sec-high} @var{sec-low} @var{microsec} 1255modified. A @var{time-flag} of the form
1256@code{(@var{sec-high} @var{sec-low} @var{microsec}
1256@var{picosec})} represents the visited file's modification time as of 1257@var{picosec})} represents the visited file's modification time as of
1257when it was previously visited or saved, using the same format as 1258when it was previously visited or saved, using the same format as
1258@code{current-time}; see @ref{Time of Day}. @code{primitive-undo} uses those 1259@code{current-time}; see @ref{Time of Day}.
1260A @var{time-flag} of 0 means the buffer does not correspond to any file;
1261@minus{}1 means the visited file previously did not exist.
1262@code{primitive-undo} uses these
1259values to determine whether to mark the buffer as unmodified once again; 1263values to determine whether to mark the buffer as unmodified once again;
1260it does so only if the file's modification time matches those numbers. 1264it does so only if the file's status matches that of @var{time-flag}.
1261 1265
1262@item (nil @var{property} @var{value} @var{beg} . @var{end}) 1266@item (nil @var{property} @var{value} @var{beg} . @var{end})
1263This kind of element records a change in a text property. 1267This kind of element records a change in a text property.
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 843f176a6a8..9ed1b6e0df7 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,8 @@
12013-07-10 Paul Eggert <eggert@cs.ucla.edu>
2
3 Timestamp fixes for undo (Bug#14824).
4 * NEWS: Changes to visited-file-modtime, set-visited-file-modtime.
5
12013-07-08 Jan Djärv <jan.h.d@swipnet.se> 62013-07-08 Jan Djärv <jan.h.d@swipnet.se>
2 7
3 * NEWS: NS can be build with ImageMagick. 8 * NEWS: NS can be build with ImageMagick.
diff --git a/etc/NEWS b/etc/NEWS
index 1c81c8329aa..6dd89fcd4d7 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -537,6 +537,9 @@ alist of extended attributes as returned by the new function
537`file-extended-attributes'. The attributes can be applied to another 537`file-extended-attributes'. The attributes can be applied to another
538file using `set-file-extended-attributes'. 538file using `set-file-extended-attributes'.
539 539
540** `visited-file-modtime' now returns -1 for nonexistent files.
541Formerly it returned a list (-1 LOW USEC PSEC), but this was ambiguous
542in the presence of files with negative time stamps.
540 543
541* Lisp Changes in Emacs 24.4 544* Lisp Changes in Emacs 24.4
542 545
@@ -613,6 +616,9 @@ Emacs uses `image-default-frame-delay'.
613*** New functions `image-current-frame' and `image-show-frame' for getting 616*** New functions `image-current-frame' and `image-show-frame' for getting
614and setting the current frame of a multi-frame image. 617and setting the current frame of a multi-frame image.
615 618
619** The function `set-visited-file-modtime' now accepts a 0 or -1 argument
620with the same interpretation as the returned value of `visited-file-modtime'.
621
616** time-to-seconds is not obsolete any more. 622** time-to-seconds is not obsolete any more.
617** New function special-form-p. 623** New function special-form-p.
618** Docstrings can be made dynamic by adding a `dynamic-docstring-function' 624** Docstrings can be made dynamic by adding a `dynamic-docstring-function'
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 3b7d95837b0..91ce836617c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,8 @@
12013-07-10 Paul Eggert <eggert@cs.ucla.edu>
2
3 Timestamp fixes for undo (Bug#14824).
4 * files.el (clear-visited-file-modtime): Move here from fileio.c.
5
12013-07-10 Leo Liu <sdl.web@gmail.com> 62013-07-10 Leo Liu <sdl.web@gmail.com>
2 7
3 * files.el (require-final-newline): Allow safe local value. 8 * files.el (require-final-newline): Allow safe local value.
diff --git a/lisp/files.el b/lisp/files.el
index a8ccf81fa17..26f229ec981 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4918,6 +4918,11 @@ change the additional actions you can take on files."
4918 (length autosaved-buffers) 4918 (length autosaved-buffers)
4919 (mapconcat 'identity autosaved-buffers ", ")))))))) 4919 (mapconcat 'identity autosaved-buffers ", "))))))))
4920 4920
4921(defun clear-visited-file-modtime ()
4922 "Clear out records of last mod time of visited file.
4923Next attempt to save will certainly not complain of a discrepancy."
4924 (set-visited-file-modtime 0))
4925
4921(defun not-modified (&optional arg) 4926(defun not-modified (&optional arg)
4922 "Mark current buffer as unmodified, not needing to be saved. 4927 "Mark current buffer as unmodified, not needing to be saved.
4923With prefix ARG, mark buffer as modified, so \\[save-buffer] will save. 4928With prefix ARG, mark buffer as modified, so \\[save-buffer] will save.
diff --git a/src/ChangeLog b/src/ChangeLog
index a96f1153ef0..049c917eddd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,21 @@
12013-07-10 Paul Eggert <eggert@cs.ucla.edu>
2
3 Timestamp fixes for undo (Bug#14824).
4 * atimer.c (schedule_atimer):
5 * fileio.c (Ffile_newer_than_file_p):
6 Minor cleanup: use EMACS_TIME_LT so that we can remove EMACS_TIME_GT.
7 * buffer.c (buffer-undo-list): Document (t . 0) and (t . -1).
8 * fileio.c (Fclear_visited_file_modtime): Move to lisp/files.el.
9 (syms_of_fileio): Remove Sclear_visited_file_name.
10 (Fvisited_file_modtime): Return -1, not (-1 ...), when the visited
11 file doesn't exist; this avoids an ambiguity with negative timestamps.
12 (Fset_visited_file_modtime): Accept -1 and 0 as time-list arg.
13 * systime.h (make_emacs_time, invalid_emacs_time):
14 Don't assume struct timespec layout; POSIX doesn't guarantee it.
15 (EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE): Remove.
16 * undo.c (record_first_change): Push (visited-file-modtime) onto
17 undo list rather than reimplementing it by hand, incorrectly.
18
12013-07-09 Ken Brown <kbrown@cornell.edu> 192013-07-09 Ken Brown <kbrown@cornell.edu>
2 20
3 * sheap.c (STATIC_HEAP_SIZE) [__x86_64__]: Increase to 18MB. 21 * sheap.c (STATIC_HEAP_SIZE) [__x86_64__]: Increase to 18MB.
diff --git a/src/atimer.c b/src/atimer.c
index 73c7aa5686b..bb5294670d3 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -336,7 +336,7 @@ schedule_atimer (struct atimer *t)
336 struct atimer *a = atimers, *prev = NULL; 336 struct atimer *a = atimers, *prev = NULL;
337 337
338 /* Look for the first atimer that is ripe after T. */ 338 /* Look for the first atimer that is ripe after T. */
339 while (a && EMACS_TIME_GT (t->expiration, a->expiration)) 339 while (a && EMACS_TIME_LT (a->expiration, t->expiration))
340 prev = a, a = a->next; 340 prev = a, a = a->next;
341 341
342 /* Insert T in front of the atimer found, if any. */ 342 /* Insert T in front of the atimer found, if any. */
diff --git a/src/buffer.c b/src/buffer.c
index 94104ef535c..81768849a4b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -6095,6 +6095,11 @@ and is the visited file's modification time, as of that time. If the
6095modification time of the most recent save is different, this entry is 6095modification time of the most recent save is different, this entry is
6096obsolete. 6096obsolete.
6097 6097
6098An entry (t . 0) means means the buffer was previously unmodified but
6099its time stamp was unknown because it was not associated with a file.
6100An entry (t . -1) is similar, except that it means the buffer's visited
6101file did not exist.
6102
6098An entry (nil PROPERTY VALUE BEG . END) indicates that a text property 6103An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
6099was modified between BEG and END. PROPERTY is the property name, 6104was modified between BEG and END. PROPERTY is the property name,
6100and VALUE is the old value. 6105and VALUE is the old value.
diff --git a/src/fileio.c b/src/fileio.c
index d030c78c422..cb863410ccf 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3345,7 +3345,7 @@ otherwise, if FILE2 does not exist, the answer is t. */)
3345 if (stat (SSDATA (absname2), &st2) < 0) 3345 if (stat (SSDATA (absname2), &st2) < 0)
3346 return Qt; 3346 return Qt;
3347 3347
3348 return (EMACS_TIME_GT (get_stat_mtime (&st1), get_stat_mtime (&st2)) 3348 return (EMACS_TIME_LT (get_stat_mtime (&st2), get_stat_mtime (&st1))
3349 ? Qt : Qnil); 3349 ? Qt : Qnil);
3350} 3350}
3351 3351
@@ -5375,36 +5375,19 @@ See Info node `(elisp)Modification Time' for more details. */)
5375 return Qnil; 5375 return Qnil;
5376} 5376}
5377 5377
5378DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
5379 Sclear_visited_file_modtime, 0, 0, 0,
5380 doc: /* Clear out records of last mod time of visited file.
5381Next attempt to save will certainly not complain of a discrepancy. */)
5382 (void)
5383{
5384 current_buffer->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS);
5385 current_buffer->modtime_size = -1;
5386 return Qnil;
5387}
5388
5389DEFUN ("visited-file-modtime", Fvisited_file_modtime, 5378DEFUN ("visited-file-modtime", Fvisited_file_modtime,
5390 Svisited_file_modtime, 0, 0, 0, 5379 Svisited_file_modtime, 0, 0, 0,
5391 doc: /* Return the current buffer's recorded visited file modification time. 5380 doc: /* Return the current buffer's recorded visited file modification time.
5392The value is a list of the form (HIGH LOW USEC PSEC), like the time values that 5381The value is a list of the form (HIGH LOW USEC PSEC), like the time values that
5393`file-attributes' returns. If the current buffer has no recorded file 5382`file-attributes' returns. If the current buffer has no recorded file
5394modification time, this function returns 0. If the visited file 5383modification time, this function returns 0. If the visited file
5395doesn't exist, HIGH will be -1. 5384doesn't exist, return -1.
5396See Info node `(elisp)Modification Time' for more details. */) 5385See Info node `(elisp)Modification Time' for more details. */)
5397 (void) 5386 (void)
5398{ 5387{
5399 if (EMACS_NSECS (current_buffer->modtime) < 0) 5388 int ns = EMACS_NSECS (current_buffer->modtime);
5400 { 5389 if (ns < 0)
5401 if (EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) 5390 return make_number (UNKNOWN_MODTIME_NSECS - ns);
5402 {
5403 /* make_lisp_time won't work here if time_t is unsigned. */
5404 return list4i (-1, 65535, 0, 0);
5405 }
5406 return make_number (0);
5407 }
5408 return make_lisp_time (current_buffer->modtime); 5391 return make_lisp_time (current_buffer->modtime);
5409} 5392}
5410 5393
@@ -5415,12 +5398,22 @@ Useful if the buffer was not read from the file normally
5415or if the file itself has been changed for some known benign reason. 5398or if the file itself has been changed for some known benign reason.
5416An argument specifies the modification time value to use 5399An argument specifies the modification time value to use
5417\(instead of that of the visited file), in the form of a list 5400\(instead of that of the visited file), in the form of a list
5418\(HIGH LOW USEC PSEC) as returned by `current-time'. */) 5401\(HIGH LOW USEC PSEC) or an integer flag as returned by
5419 (Lisp_Object time_list) 5402`visited-file-modtime'. */)
5403 (Lisp_Object time_flag)
5420{ 5404{
5421 if (!NILP (time_list)) 5405 if (!NILP (time_flag))
5422 { 5406 {
5423 current_buffer->modtime = lisp_time_argument (time_list); 5407 EMACS_TIME mtime;
5408 if (INTEGERP (time_flag))
5409 {
5410 CHECK_RANGED_INTEGER (time_flag, -1, 0);
5411 mtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS - XINT (time_flag));
5412 }
5413 else
5414 mtime = lisp_time_argument (time_flag);
5415
5416 current_buffer->modtime = mtime;
5424 current_buffer->modtime_size = -1; 5417 current_buffer->modtime_size = -1;
5425 } 5418 }
5426 else 5419 else
@@ -6121,7 +6114,6 @@ This includes interactive calls to `delete-file' and
6121 defsubr (&Swrite_region); 6114 defsubr (&Swrite_region);
6122 defsubr (&Scar_less_than_car); 6115 defsubr (&Scar_less_than_car);
6123 defsubr (&Sverify_visited_file_modtime); 6116 defsubr (&Sverify_visited_file_modtime);
6124 defsubr (&Sclear_visited_file_modtime);
6125 defsubr (&Svisited_file_modtime); 6117 defsubr (&Svisited_file_modtime);
6126 defsubr (&Sset_visited_file_modtime); 6118 defsubr (&Sset_visited_file_modtime);
6127 defsubr (&Sdo_auto_save); 6119 defsubr (&Sdo_auto_save);
diff --git a/src/systime.h b/src/systime.h
index c3bc00c1479..df733b290c3 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -67,7 +67,9 @@ SYSTIME_INLINE time_t *emacs_secs_addr (EMACS_TIME *t) { return &t->tv_sec; }
67SYSTIME_INLINE EMACS_TIME 67SYSTIME_INLINE EMACS_TIME
68make_emacs_time (time_t s, int ns) 68make_emacs_time (time_t s, int ns)
69{ 69{
70 EMACS_TIME r = { s, ns }; 70 EMACS_TIME r;
71 r.tv_sec = s;
72 r.tv_nsec = ns;
71 return r; 73 return r;
72} 74}
73 75
@@ -75,7 +77,9 @@ make_emacs_time (time_t s, int ns)
75SYSTIME_INLINE EMACS_TIME 77SYSTIME_INLINE EMACS_TIME
76invalid_emacs_time (void) 78invalid_emacs_time (void)
77{ 79{
78 EMACS_TIME r = { 0, -1 }; 80 EMACS_TIME r;
81 r.tv_sec = 0;
82 r.tv_nsec = -1;
79 return r; 83 return r;
80} 84}
81 85
@@ -166,21 +170,6 @@ EMACS_TIME_EQ (EMACS_TIME t1, EMACS_TIME t2)
166 return timespec_cmp (t1, t2) == 0; 170 return timespec_cmp (t1, t2) == 0;
167} 171}
168SYSTIME_INLINE int 172SYSTIME_INLINE int
169EMACS_TIME_NE (EMACS_TIME t1, EMACS_TIME t2)
170{
171 return timespec_cmp (t1, t2) != 0;
172}
173SYSTIME_INLINE int
174EMACS_TIME_GT (EMACS_TIME t1, EMACS_TIME t2)
175{
176 return timespec_cmp (t1, t2) > 0;
177}
178SYSTIME_INLINE int
179EMACS_TIME_GE (EMACS_TIME t1, EMACS_TIME t2)
180{
181 return timespec_cmp (t1, t2) >= 0;
182}
183SYSTIME_INLINE int
184EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2) 173EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2)
185{ 174{
186 return timespec_cmp (t1, t2) < 0; 175 return timespec_cmp (t1, t2) < 0;
diff --git a/src/undo.c b/src/undo.c
index d8711882fbf..234b8510f0a 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -229,10 +229,9 @@ record_first_change (void)
229 if (base_buffer->base_buffer) 229 if (base_buffer->base_buffer)
230 base_buffer = base_buffer->base_buffer; 230 base_buffer = base_buffer->base_buffer;
231 231
232 bset_undo_list 232 bset_undo_list (current_buffer,
233 (current_buffer, 233 Fcons (Fcons (Qt, Fvisited_file_modtime ()),
234 Fcons (Fcons (Qt, make_lisp_time (base_buffer->modtime)), 234 BVAR (current_buffer, undo_list)));
235 BVAR (current_buffer, undo_list)));
236} 235}
237 236
238/* Record a change in property PROP (whose old value was VAL) 237/* Record a change in property PROP (whose old value was VAL)