commit 8b98d158a75b94b80d17b3af3419b3163c64945c (HEAD, refs/remotes/origin/master) Author: Albert Krewinkel Date: Mon Nov 17 17:54:57 2014 +0900 lisp/gnus/message.el (message-valid-fqdn-regexp): Add non-internaional new TLDs diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 1d9b146..f18565a 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,8 @@ +2014-11-17 Albert Krewinkel + + * message.el (message-valid-fqdn-regexp): Add non-internaional new + TLDs. + 2014-11-16 Adam Sjøgren * mml2015.el (mml2015-display-key-image): New variable. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 3cd9e93..0af4784 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -1919,7 +1919,45 @@ You must have the \"hashcash\" binary installed, see `hashcash-path'." "cat\\|com\\|coop\\|edu\\|gov\\|" "info\\|int\\|jobs\\|" "mil\\|mobi\\|museum\\|name\\|net\\|" - "org\\|pro\\|tel\\|travel\\|uucp\\)") + "org\\|pro\\|tel\\|travel\\|uucp\\|" + ;; ICANN-era generic top-level domains + "academy\\|actor\\|agency\\|airforce\\|archi\\|associates\\|axa\\|" + "bar\\|bargains\\|bayern\\|beer\\|berlin\\|best\\|bid\\|bike\\|" + "biz\\|black\\|blackfriday\\|blue\\|boutique\\|build\\|builders\\|" + "buzz\\|cab\\|camera\\|camp\\|capital\\|cards\\|care\\|career\\|" + "careers\\|cash\\|catering\\|center\\|ceo\\|cheap\\|christmas\\|" + "church\\|citic\\|cleaning\\|clinic\\|clothing\\|club\\|codes\\|" + "coffee\\|college\\|cologne\\|com\\|community\\|company\\|computer\\|" + "construction\\|contractors\\|cooking\\|cool\\|country\\|creditcard\\|" + "cruises\\|dance\\|dating\\|democrat\\|dental\\|desi\\|design\\|" + "diamonds\\|directory\\|discount\\|domains\\|education\\|email\\|" + "engineering\\|enterprises\\|equipment\\|estate\\|eus\\|events\\|" + "exchange\\|expert\\|exposed\\|fail\\|farm\\|feedback\\|finance\\|" + "financial\\|fish\\|fishing\\|fitness\\|flights\\|florist\\|foo\\|" + "foundation\\|frogans\\|fund\\|furniture\\|futbol\\|gal\\|" + "gallery\\|gift\\|glass\\|globo\\|gmo\\|gop\\|graphics\\|gratis\\|" + "gripe\\|guide\\|guitars\\|guru\\|hamburg\\|haus\\|hiphop\\|" + "holdings\\|holiday\\|homes\\|horse\\|house\\|immobilien\\|" + "industries\\|info\\|ink\\|institute\\|insure\\|international\\|" + "investments\\|jetzt\\|juegos\\|kaufen\\|kim\\|kitchen\\|kiwi\\|" + "koeln\\|kred\\|land\\|lat\\|latino\\|lease\\|life\\|lighting\\|" + "limited\\|limo\\|link\\|loans\\|london\\|luxe\\|luxury\\|" + "management\\|mango\\|marketing\\|media\\|meet\\|menu\\|miami\\|" + "moda\\|moe\\|monash\\|moscow\\|motorcycles\\|nagoya\\|name\\|" + "net\\|neustar\\|ninja\\|nyc\\|okinawa\\|onl\\|org\\|paris\\|" + "partners\\|parts\\|photo\\|photography\\|photos\\|pics\\|" + "pictures\\|pink\\|plumbing\\|pro\\|productions\\|properties\\|" + "pub\\|qpon\\|quebec\\|recipes\\|red\\|reisen\\|ren\\|rentals\\|" + "repair\\|report\\|rest\\|reviews\\|rich\\|rocks\\|rodeo\\|" + "ruhr\\|ryukyu\\|saarland\\|schule\\|scot\\|services\\|sexy\\|" + "shiksha\\|shoes\\|singles\\|social\\|sohu\\|solar\\|solutions\\|" + "soy\\|supplies\\|supply\\|support\\|surgery\\|systems\\|tattoo\\|" + "tax\\|technology\\|tienda\\|tips\\|today\\|tokyo\\|tools\\|" + "town\\|toys\\|trade\\|training\\|university\\|uno\\|vacations\\|" + "vegas\\|ventures\\|viajes\\|villas\\|vision\\|vodka\\|vote\\|" + "voting\\|voto\\|voyage\\|wang\\|watch\\|webcam\\|wed\\|wien\\|" + "wiki\\|works\\|wtc\\|wtf\\|xyz\\|yachts\\|yokohama\\|you\\|" + "zone\\)") ;; http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains ;; http://en.wikipedia.org/wiki/GTLD ;; `approved, but not yet in operation': .xxx commit ed7b50515cabc0de7036b823221ac758a6d9c1d1 Author: Paul Eggert Date: Sun Nov 16 23:37:19 2014 -0800 Port new time stamp handling to old Emacs and to XEmacs. This is needed for Gnus, which copies time-date.el and which runs on older Emacs implementations. * calendar/time-date.el (with-decoded-time-value): Handle 'nil' and floating-point arg more compatibly with new Emacs. (encode-time-value, with-decoded-time-value): Obsolete only if new Emacs. (time-add, time-subtract, time-less-p): Define if not new Emacs. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7e516b9..c30a2dd 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,14 @@ 2014-11-17 Paul Eggert + Port new time stamp handling to old Emacs and to XEmacs. + This is needed for Gnus, which copies time-date.el and which + runs on older Emacs implementations. + * calendar/time-date.el (with-decoded-time-value): + Handle 'nil' and floating-point arg more compatibly with new Emacs. + (encode-time-value, with-decoded-time-value): + Obsolete only if new Emacs. + (time-add, time-subtract, time-less-p): Define if not new Emacs. + Improve time stamp handling, and be more consistent about it. This implements a suggestion made in: http://lists.gnu.org/archive/html/emacs-devel/2014-10/msg00587.html diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 100e856..a9c30f4 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -65,12 +65,36 @@ list (HIGH LOW MICRO PICO)." (pop elt))) (time-value (car elt)) (gensym (make-symbol "time"))) - `(let* ,(append `((,gensym ,time-value) + `(let* ,(append `((,gensym (or ,time-value (current-time))) + (,gensym + (cond + ((integerp ,gensym) + (list (ash ,gensym -16) + (logand ,gensym 65535))) + ((floatp ,gensym) + (let* ((usec (* 1000000 (mod ,gensym 1))) + (ps (round (* 1000000 (mod usec 1)))) + (us (floor usec)) + (lo (floor (mod ,gensym 65536))) + (hi (floor ,gensym 65536))) + (if (eq ps 1000000) + (progn + (setq ps 0) + (setq us (1+ us)) + (if (eq us 1000000) + (progn + (setq us 0) + (setq lo (1+ lo)) + (if (eq lo 65536) + (progn + (setq lo 0) + (setq hi (1+ hi)))))))) + (list hi lo us ps))) + (t ,gensym))) (,high (pop ,gensym)) ,low ,micro) (when pico `(,pico)) (when type `(,type))) - (or ,gensym (setq ,gensym (current-time))) (if (consp ,gensym) (progn (setq ,low (pop ,gensym)) @@ -108,7 +132,7 @@ it is assumed that PICO was omitted and should be treated as zero." ((eq type 3) (list high low micro pico)) ((null type) (encode-time-value high low micro 0 pico)))) -(when (featurep 'emacs) +(when (and (fboundp 'time-add) (subrp (symbol-function 'time-add))) (make-obsolete 'encode-time-value nil "25.1") (make-obsolete 'with-decoded-time-value nil "25.1")) @@ -192,7 +216,7 @@ TIME should be either a time value or a date-time string." ;;;###autoload(autoload 'time-less-p "time-date") (eval-when-compile - (when (not (featurep 'emacs)) + (when (not (and (fboundp 'time-add) (subrp (symbol-function 'time-add)))) (defun time-add (t1 t2) "Add two time values T1 and T2. One should represent a time difference." commit 1c7b6b3e0a8e6fe5c8a476b2c45c4b61c609bdfe Author: Paul Eggert Date: Sun Nov 16 22:26:17 2014 -0800 Spelling fixes. diff --git a/lisp/cedet/ede/config.el b/lisp/cedet/ede/config.el index 3ac3c06..65713d9 100644 --- a/lisp/cedet/ede/config.el +++ b/lisp/cedet/ede/config.el @@ -25,7 +25,7 @@ ;; can be enhanced by also saving a configuration file that is EDE ;; specific. EDE will be able to load that configuration from the save ;; file as a way of augmenting what is normally already detected. -;; +;; ;; How To Use: ;; ;; Subclass `ede-extra-config', and add the features you want to use. @@ -74,7 +74,7 @@ was ignored. Use this to warn the user that they might want to load in an on-disk version.") ) - "Baseclass for auxilliary configuration files for EDE. + "Baseclass for auxiliary configuration files for EDE. This should be subclassed by projects that auto detect a project and also want to save some extra level of configuration.") @@ -93,7 +93,7 @@ and also want to save some extra level of configuration.") :documentation "The filename to use for saving the configuration. This filename excludes the directory name and is used to -initalize the :file slot of the persistent baseclass.") +initialize the :file slot of the persistent baseclass.") (config-class :initform ede-extra-config :allocation :class @@ -109,7 +109,7 @@ initalize the :file slot of the persistent baseclass.") (defclass ede-target-with-config (ede-target) () - "Baseclass for targetes of classes that use a config object.") + "Baseclass for targets of classes that use a config object.") ;;; Rescanning @@ -141,8 +141,8 @@ the directory isn't on the `safe' list, ask to add it to the safe list." (let* ((top (oref proj :directory)) (fname (expand-file-name (oref proj config-file-basename) top)) (class (oref proj config-class)) - (ignore-type nil)) - (if (and (file-exists-p fname) + (ignore-type nil)) + (if (and (file-exists-p fname) (or (ede-directory-safe-p top) ;; Only force the load if someone asked. (and loadask (ede-check-project-directory top)))) @@ -217,13 +217,13 @@ the new configuration." ;;; PROJECT MIXINS ;; -;; These are project part mixins. Use multiple inheritence for each -;; piece of these configuration optiosn you would like to have as part +;; These are project part mixins. Use multiple inheritance for each +;; piece of these configuration options you would like to have as part ;; of your project. ;;; PROGRAM ;; If there is a program that can be run or debugged that is unknown -;; and needs to be configured. +;; and needs to be configured. (defclass ede-extra-config-program () ((debug-command :initarg :debug-command :initform "gdb " @@ -332,7 +332,7 @@ The include path is used when searching for symbols.") :documentation "Preprocessor Symbols for this project. When files within this project are parsed by CEDET, these symbols will be -used to resolve macro occurrences in source fies. +used to resolve macro occurrences in source files. If you modify this slot, you will need to force your source files to be parsed again.") (c-preprocessor-files :initarg :c-preprocessor-files @@ -343,7 +343,7 @@ parsed again.") :documentation "Files parsed and used to populate preprocessor tables. When files within this project are parsed by CEDET, these symbols will be used to -resolve macro occurences in source files. +resolve macro occurrences in source files. If you modify this slot, you will need to force your source files to be parsed again.")) "Class to mix into a configuration for compilation.") diff --git a/lisp/cedet/ede/cpp-root.el b/lisp/cedet/ede/cpp-root.el index 7ea9236..0ccdc06 100644 --- a/lisp/cedet/ede/cpp-root.el +++ b/lisp/cedet/ede/cpp-root.el @@ -298,7 +298,7 @@ Each directory needs a project file to control it.") (oset this :directory (file-name-directory f)) (ede-project-directory-remove-hash (file-name-directory f)) ;; NOTE: We must add to global list here because these classes are not - ;; created via the typial loader, but instead via calls from a .emacs + ;; created via the typical loader, but instead via calls from a .emacs ;; file. (ede-add-project-to-global-list this) diff --git a/lisp/cedet/ede/detect.el b/lisp/cedet/ede/detect.el index 2b32918..cc73104 100644 --- a/lisp/cedet/ede/detect.el +++ b/lisp/cedet/ede/detect.el @@ -28,7 +28,7 @@ ;; `ede-detect-scan-directory-for-project' - ;; Scan for a project via the file system. ;; `ede-detect-directory-for-project' - -;; Check our file cache for a project. If that failes, use +;; Check our file cache for a project. If that fails, use ;; the scan fcn above. ;;; Code: @@ -57,7 +57,7 @@ ;;stop)) (defvar ede--detect-found-project nil - "When searching for a project, temporarilly save that file.") + "When searching for a project, temporarily save that file.") (defun ede--detect-ldf-predicate (dir) "Non-nil if DIR contain any known EDE project types." @@ -81,7 +81,7 @@ use any file caches. Return a cons cell: ( ROOTDIR . PROJECT-AUTOLOAD)" (let* ((ede--detect-found-project nil) - (root + (root (catch 'stopscan (locate-dominating-file directory 'ede--detect-ldf-predicate)))) @@ -90,7 +90,7 @@ Return a cons cell: ;;; Root Only project detect ;; -;; For projects that only have a detectible ROOT file, but may in fact +;; For projects that only have a detectable ROOT file, but may in fact ;; contain a generic file such as a Makefile, we need to do a second scan ;; to make sure we don't miss-match. (defun ede--detect-ldf-rootonly-predicate (dir) @@ -117,7 +117,7 @@ use any file caches. Return a cons cell: ( ROOTDIR . PROJECT-AUTOLOAD)" (let* ((ede--detect-found-project nil) - (root + (root (catch 'stopscan (locate-dominating-file directory 'ede--detect-ldf-rootonly-predicate)))) @@ -149,7 +149,7 @@ Return a cons cell: "If DIRECTORY has already been detected with AUTO, find the root. Some projects have their dominating file in all their directories, such as Project.ede. In that case we will detect quickly, but then need -to scan upward to find the topmost occurance of that file." +to scan upward to find the topmost occurrence of that file." (let* ((ede--detect-nomatch-auto auto) (root (locate-dominating-file directory 'ede--detect-ldf-root-predicate))) @@ -179,7 +179,7 @@ Return a cons cell: (if moreroot moreroot - ;; If we didn't find a root from the generic project, then + ;; If we didn't find a root from the generic project, then ;; we need to rescan upward. (cons (ede--detect-scan-directory-for-project-root root auto) auto))) @@ -203,7 +203,7 @@ Return a cons cell: (car ans) (eieio-object-name-string (cdr ans))) (message "No Project found.") ))) - + (provide 'ede/detect) diff --git a/lisp/cedet/ede/files.el b/lisp/cedet/ede/files.el index 1a97bfc..f9a8558 100644 --- a/lisp/cedet/ede/files.el +++ b/lisp/cedet/ede/files.el @@ -85,7 +85,7 @@ of the anchor file for the project." ;; Why INODEs? -;; An inode represents is a unique id that trancends symlinks, hardlinks, etc +;; An inode represents a unique ID that transcends symlinks, hardlinks, etc. ;; so when we cache an inode in a project, and hash directories to inodes, we ;; can avoid costly filesystem queries and regex matches. @@ -196,7 +196,7 @@ If optional EXACT is non-nil, only return exact matches for DIR." (let ((pin (ede--project-inode (car all))) (inode (ede--inode-for-dir dir))) (and (not (eql pin 0)) (equal pin inode)))) - (setq ans (car all))) + (setq ans (car all))) ;; Subdir via truename - slower by far, but faster than a traditional lookup. ;; Note that we must resort to truename in order to resolve issues such as ;; cross-symlink projects. @@ -339,7 +339,7 @@ Optional FORCE means to ignore the hash of known directories." (ede--directory-project-add-description-to-hash dirtest (or detect 'nomatch)) detect) ))))) - + ;;; TOPLEVEL ;; diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el index 7eddf82..6bd090c 100644 --- a/lisp/cedet/semantic.el +++ b/lisp/cedet/semantic.el @@ -1136,7 +1136,7 @@ Semantic mode. 'semantic-analyze-notc-completion-at-point-function) (add-hook 'completion-at-point-functions 'semantic-analyze-completion-at-point-function) - + (if global-ede-mode (define-key cedet-menu-map [cedet-menu-separator] '("--"))) (dolist (b (buffer-list)) @@ -1171,7 +1171,7 @@ Semantic mode. ;;; Completion At Point functions (defun semantic-analyze-completion-at-point-function () - "Return possible analasis completions at point. + "Return possible analysis completions at point. The completions provided are via `semantic-analyze-possible-completions'. This function can be used by `completion-at-point-functions'." (let* ((ctxt (semantic-analyze-current-context)) @@ -1187,7 +1187,7 @@ This function can be used by `completion-at-point-functions'." )) (defun semantic-analyze-notc-completion-at-point-function () - "Return possible analasis completions at point. + "Return possible analysis completions at point. The completions provided are via `semantic-analyze-possible-completions', but with the 'no-tc option passed in, which means constraints based on what is being assigned to are ignored. @@ -1202,7 +1202,7 @@ This function can be used by `completion-at-point-functions'." )) (defun semantic-analyze-nolongprefix-completion-at-point-function () - "Return possible analasis completions at point. + "Return possible analysis completions at point. The completions provided are via `semantic-analyze-possible-completions', but with the 'no-tc and 'no-longprefix option passed in, which means constraints resulting in a long multi-symbol dereference are ignored. diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el index 12be662..13e2d1b 100644 --- a/lisp/cedet/semantic/db.el +++ b/lisp/cedet/semantic/db.el @@ -128,7 +128,7 @@ If the buffer is not in memory, load it with `find-file-noselect'." ;; functions treat "table" as something that could be a buffer, ;; file name, or other. This makes use of table more robust. (defmethod semanticdb-full-filename (buffer-or-string) - "Fetch the full filename that BUFFER-OR-STRING referrs to. + "Fetch the full filename that BUFFER-OR-STRING refers to. This uses semanticdb to get a better file name." (cond ((bufferp buffer-or-string) (with-current-buffer buffer-or-string diff --git a/src/w32fns.c b/src/w32fns.c index 502154d..1b290b7 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7434,7 +7434,7 @@ title bar and decorations. */) } DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0, - doc: /* Return geometric atributes of frame FRAME. + doc: /* Return geometric attributes of frame FRAME. FRAME must be a live frame and defaults to the selected one. The return value is an association list containing the following diff --git a/src/xfns.c b/src/xfns.c index 3ca8f20..aaa75f2 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4235,7 +4235,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) } DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0, - doc: /* Return geometric atributes of frame FRAME. + doc: /* Return geometric attributes of frame FRAME. FRAME must be a live frame and defaults to the selected one. diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el index e4ce535..1b9d774 100644 --- a/test/automated/python-tests.el +++ b/test/automated/python-tests.el @@ -797,7 +797,7 @@ def f(): expected))))) (ert-deftest python-indent-region-4 () - "Test region indentation block starts, dedenders and enders." + "Test region indentation block starts, dedenters and enders." (let ((contents " def f(): if True: commit 0921dbc3ab4dcc6b291ef45e46a24b322bbcb885 Author: Paul Eggert Date: Sun Nov 16 20:38:15 2014 -0800 Improve time stamp handling, and be more consistent about it. This implements a suggestion made in: http://lists.gnu.org/archive/html/emacs-devel/2014-10/msg00587.html Among other things, this means timer.el no longer needs to autoload the time-date module. * doc/lispref/os.texi (Time of Day, Time Conversion, Time Parsing) (Processor Run Time, Time Calculations): Document the new behavior, plus be clearer about the old behavior. (Idle Timers): Take advantage of new functionality. * etc/NEWS: Document the changes. * lisp/allout-widgets.el (allout-elapsed-time-seconds): Doc fix. * lisp/arc-mode.el (archive-ar-summarize): * lisp/calendar/time-date.el (seconds-to-time, days-to-time, time-since): * lisp/emacs-lisp/timer.el (timer-relative-time, timer-event-handler) (run-at-time, with-timeout-suspend, with-timeout-unsuspend): * lisp/net/tramp.el (tramp-time-less-p, tramp-time-subtract): * lisp/proced.el (proced-time-lessp): * lisp/timezone.el (timezone-time-from-absolute): * lisp/type-break.el (type-break-schedule, type-break-time-sum): Simplify by using new functionality. * lisp/calendar/cal-dst.el (calendar-next-time-zone-transition): Do not return time values in obsolete and undocumented (HI . LO) format; use (HI LO) instead. * lisp/calendar/time-date.el (with-decoded-time-value): Treat 'nil' as current time. This is mostly for XEmacs. (encode-time-value, with-decoded-time-value): Obsolete. (time-add, time-subtract, time-less-p): Use no-op autoloads, for XEmacs. Define only if XEmacs, as they're now C builtins in Emacs. * lisp/ldefs-boot.el: Update to match new time-date.el * lisp/proced.el: Do not require time-date. * src/editfns.c (invalid_time): New function. Use it instead of 'error ("Invalid time specification")'. (time_add, time_subtract, time_arith, Ftime_add, Ftime_less_p) (decode_float_time, lisp_to_timespec, lisp_time_struct): New functions. (make_time_tail, make_time): Remove. All uses changed to use new functions or plain list4i. (disassemble_lisp_time): Return effective length if successful. Check that LOW is an integer, if it's combined with other components. (decode_time_components): Decode into struct lisp_time, not struct timespec, so that we can support a wide set of times regardless of whether time_t is signed. Decode plain numbers as seconds since the Epoch, and nil as the current time. (lisp_time_argument, lisp_seconds_argument, Ffloat_time): Reimplement in terms of new functions. (Fencode_time): Just use list2i. (syms_of_editfns): Add time-add, time-subtract, time-less-p. * src/keyboard.c (decode_timer): Don't allow the new formats (floating point or nil) in timers. * src/systime.h (LO_TIME_BITS): New constant. Use it everywhere in place of the magic number '16'. (struct lisp_time): New type. (decode_time_components): Use it. (lisp_to_timespec): New decl. diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index b7423af..0a8a0a8 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,11 @@ +2014-11-17 Paul Eggert + + Improve time stamp handling, and be more consistent about it. + * os.texi (Time of Day, Time Conversion, Time Parsing) + (Processor Run Time, Time Calculations): + Document the new behavior, plus be clearer about the old behavior. + (Idle Timers): Take advantage of new functionality. + 2014-11-16 Lars Magne Ingebrigtsen * text.texi (Special Properties): Mention `inhibit-read-only'. diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 167ecb3..b709447 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1213,37 +1213,34 @@ return value is @code{nil}. zone. @cindex epoch - Most of these functions represent time as a list of either four -integers, @code{(@var{sec-high} @var{sec-low} @var{microsec} -@var{picosec})}, or of three -integers, @code{(@var{sec-high} @var{sec-low} @var{microsec})}, or of -two integers, @code{(@var{sec-high} @var{sec-low})}. The integers -@var{sec-high} and @var{sec-low} give the high and low bits of an -integer number of seconds. This integer, + Most of these functions represent time as a list of four integers +@code{(@var{sec-high} @var{sec-low} @var{microsec} @var{picosec})}. +This represents the number of seconds from the @dfn{epoch} (January +1, 1970 at 00:00 UTC), using the formula: @ifnottex -@var{high} * 2**16 + @var{low}, +@var{high} * 2**16 + @var{low} + @var{micro} * 10**@minus{}6 + +@var{pico} * 10**@minus{}12. @end ifnottex @tex -$high*2^{16}+low$, +$high*2^{16} + low + micro*10^{-6} + pico*10^{-12}$. @end tex -is the number of seconds from the @dfn{epoch} (January 1, 1970 at 00:00 -UTC) to the specified time. The third list element @var{microsec}, if -present, gives the number of microseconds from the start of that -second to the specified time. -Similarly, the fourth list element @var{picosec}, if present, gives -the number of picoseconds from the start of that microsecond to the -specified time. - - The return value of @code{current-time} represents time using four -integers, as do the timestamps in the return value of -@code{file-attributes} (@pxref{Definition of -file-attributes}). In function arguments, e.g., the @var{time-value} -argument to @code{current-time-string}, two-, three-, and four-integer -lists are accepted. You can convert times from the list -representation into standard human-readable strings using -@code{current-time-string}, or to other forms using the -@code{decode-time} and @code{format-time-string} functions documented -in the following sections. +The return value of @code{current-time} represents time using this +form, as do the timestamps in the return values of other functions +such as @code{file-attributes} (@pxref{Definition of +file-attributes}). In some cases, functions may return two- or +three-element lists, with omitted @var{microsec} and @var{picosec} +components defaulting to zero. + +@cindex time value + Function arguments, e.g., the @var{time-value} argument to +@code{current-time-string}, accept a more-general @dfn{time value} +format, which can be a list of integers as above, or a single number +for seconds since the epoch, or @code{nil} for the current time. You +can convert a time value into a human-readable string using +@code{current-time-string} and @code{format-time-string}, into a list +of integers using @code{seconds-to-time}, and into other forms using +@code{decode-time} and @code{float-time}. These functions are +described in the following sections. @defun current-time-string &optional time-value This function returns the current time and date as a human-readable @@ -1256,8 +1253,8 @@ characters from the beginning of the string rather than from the end, as the year might not have exactly four digits, and additional information may some day be added at the end. -The argument @var{time-value}, if given, specifies a time to format -(represented as a list of integers), instead of the current time. +The argument @var{time-value}, if given, specifies a time to format, +instead of the current time. @example @group @@ -1279,11 +1276,19 @@ become available. @defun float-time &optional time-value This function returns the current time as a floating-point number of seconds since the epoch. The optional argument @var{time-value}, if -given, specifies a time (represented as a list of integers) to convert -instead of the current time. +given, specifies a time to convert instead of the current time. @emph{Warning}: Since the result is floating point, it may not be exact. Do not use this function if precise time stamps are required. + +@code{time-to-seconds} is an alias for this function. +@end defun + +@defun seconds-to-time time-value +This function converts a time value to list-of-integer form. +For example, if @var{time-value} is a number, @code{(time-to-seconds +(seconds-to-time @var{time-value}))} equals the number unless overflow +or rounding errors occur. @end defun @defun current-time-zone &optional time-value @@ -1302,8 +1307,8 @@ adjustment, then the value is constant through time. If the operating system doesn't supply all the information necessary to compute the value, the unknown elements of the list are @code{nil}. -The argument @var{time-value}, if given, specifies a time (represented -as a list of integers) to analyze instead of the current time. +The argument @var{time-value}, if given, specifies a time value to +analyze instead of the current time. @end defun The current time zone is determined by the @env{TZ} environment @@ -1316,15 +1321,15 @@ time zone. @section Time Conversion @cindex calendrical information - These functions convert time values (lists of two to four integers, -as explained in the previous section) into calendrical information and -vice versa. + These functions convert time values (@pxref{Time of Day}) into +calendrical information and vice versa. - Many 32-bit operating systems are limited to time values containing -32 bits of information; these systems typically handle only the times -from 1901-12-13 20:45:52 UTC through 2038-01-19 03:14:07 UTC@. -However, 64-bit and some 32-bit operating systems have larger time -values, and can represent times far in the past or future. + Many 32-bit operating systems are limited to system times containing +32 bits of information in their seconds component; these systems +typically handle only the times from 1901-12-13 20:45:52 UTC through +2038-01-19 03:14:07 UTC@. However, 64-bit and some 32-bit operating +systems have larger seconds components, and can represent times far in +the past or future. Time conversion functions always use the Gregorian calendar, even for dates before the Gregorian calendar was introduced. Year numbers @@ -1332,9 +1337,9 @@ count the number of years since the year 1 B.C., and do not skip zero as traditional Gregorian years do; for example, the year number @minus{}37 represents the Gregorian year 38 B.C@. -@defun decode-time &optional time +@defun decode-time &optional time-value This function converts a time value into calendrical information. If -you don't specify @var{time}, it decodes the current time. The return +you don't specify @var{time-value}, it decodes the current time. The return value is a list of nine elements, as follows: @example @@ -1373,8 +1378,9 @@ Greenwich. @defun encode-time seconds minutes hour day month year &optional zone This function is the inverse of @code{decode-time}. It converts seven -items of calendrical data into a time value. For the meanings of the -arguments, see the table above under @code{decode-time}. +items of calendrical data into a list-of-integer time value. For the +meanings of the arguments, see the table above under +@code{decode-time}. Year numbers less than 100 are not treated specially. If you want them to stand for years above 1900, or years above 2000, you must alter them @@ -1418,9 +1424,11 @@ This function parses the time-string @var{string} and returns the corresponding time value. @end defun -@defun format-time-string format-string &optional time universal -This function converts @var{time} (or the current time, if @var{time} is -omitted) to a string according to @var{format-string}. The argument +@defun format-time-string format-string &optional time-value universal + +This function converts @var{time-value} (or the current time, if +@var{time-value} is omitted) to a string according to +@var{format-string}. The argument @var{format-string} may contain @samp{%}-sequences which say to substitute parts of the time. Here is a table of what the @samp{%}-sequences mean: @@ -1540,12 +1548,6 @@ specified by @code{locale-coding-system} (@pxref{Locales}); after system. @end defun -@defun seconds-to-time seconds -This function converts @var{seconds}, the number of seconds since the -epoch, to a time value and returns that. To convert back, use -@code{float-time} (@pxref{Time of Day}). -@end defun - @defun format-seconds format-string seconds This function converts its argument @var{seconds} into a string of years, days, hours, etc., according to @var{format-string}. The @@ -1619,7 +1621,7 @@ When called interactively, it prints the uptime in the echo area. @defun get-internal-run-time This function returns the processor run time used by Emacs as a list -of four integers: @code{(@var{high} @var{low} @var{microsec} +of four integers: @code{(@var{sec-high} @var{sec-low} @var{microsec} @var{picosec})}, using the same format as @code{current-time} (@pxref{Time of Day}). @@ -1643,7 +1645,7 @@ interactively, it prints the duration in the echo area. @section Time Calculations These functions perform calendrical computations using time values -(the kind of list that @code{current-time} returns). +(@pxref{Time of Day}). @defun time-less-p t1 t2 This returns @code{t} if time value @var{t1} is less than time value @@ -1652,26 +1654,26 @@ This returns @code{t} if time value @var{t1} is less than time value @defun time-subtract t1 t2 This returns the time difference @var{t1} @minus{} @var{t2} between -two time values, in the same format as a time value. +two time values, as a time value. @end defun @defun time-add t1 t2 -This returns the sum of two time values, one of which ought to -represent a time difference rather than a point in time. +This returns the sum of two time values, as a time value. +One argument should represent a time difference rather than a point in time. Here is how to add a number of seconds to a time value: @example -(time-add @var{time} (seconds-to-time @var{seconds})) +(time-add @var{time} @var{seconds}) @end example @end defun -@defun time-to-days time +@defun time-to-days time-value This function returns the number of days between the beginning of year -1 and @var{time}. +1 and @var{time-value}. @end defun -@defun time-to-day-in-year time -This returns the day number within the year corresponding to @var{time}. +@defun time-to-day-in-year time-value +This returns the day number within the year corresponding to @var{time-value}. @end defun @defun date-leap-year-p year @@ -1915,8 +1917,7 @@ idleness. Here's an example: (run-with-idle-timer ;; Compute an idle time @var{break-length} ;; more than the current value. - (time-add (current-idle-time) - (seconds-to-time @var{break-length})) + (time-add (current-idle-time) @var{break-length}) nil 'my-timer-function)))) @end example diff --git a/etc/ChangeLog b/etc/ChangeLog index 983fcaa..ed8c345 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,8 @@ +2014-11-17 Paul Eggert + + Improve time stamp handling, and be more consistent about it. + * NEWS: Document the changes. + 2014-11-14 Lars Magne Ingebrigtsen * NEWS: Mention the new `M-s M-s' keystroke. diff --git a/etc/NEWS b/etc/NEWS index b0e08d4..cb34e9b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -377,6 +377,25 @@ optional repeat-count argument. *** New macros `thread-first' and `thread-last' allow threading a form as the first or last argument of subsequent forms. ++++ +** Time-related changes: + +*** Time-related functions now consistently accept numbers +(representing seconds since the epoch) and nil (representing the +current time) as well as the usual list-of-integer representation. +Affected functions include `current-time-string', `current-time-zone', +`decode-time', `float-time', `format-time-string', `seconds-to-time', +`time-add', `time-less-p', `time-subtract', `time-to-day-in-year', +`time-to-days', and `time-to-seconds'. + +*** The `encode-time-value' and `with-decoded-time-value' macros have +been obsoleted. + +*** `calendar-next-time-zone-transition', `time-add', and +`time-subtract' no longer return time values in the obsolete and +undocumented integer-pair format. Instead, they return a list of two +integers. + * Changes in Frames and Windows Code in Emacs 25.1 diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7659d3c..7e516b9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,31 @@ +2014-11-17 Paul Eggert + + Improve time stamp handling, and be more consistent about it. + This implements a suggestion made in: + http://lists.gnu.org/archive/html/emacs-devel/2014-10/msg00587.html + Among other things, this means timer.el no longer needs to + autoload the time-date module. + * allout-widgets.el (allout-elapsed-time-seconds): Doc fix. + * arc-mode.el (archive-ar-summarize): + * calendar/time-date.el (seconds-to-time, days-to-time, time-since): + * emacs-lisp/timer.el (timer-relative-time, timer-event-handler) + (run-at-time, with-timeout-suspend, with-timeout-unsuspend): + * net/tramp.el (tramp-time-less-p, tramp-time-subtract): + * proced.el (proced-time-lessp): + * timezone.el (timezone-time-from-absolute): + * type-break.el (type-break-schedule, type-break-time-sum): + Simplify by using new functionality. + * calendar/cal-dst.el (calendar-next-time-zone-transition): + Do not return time values in obsolete and undocumented (HI . LO) + format; use (HI LO) instead. + * calendar/time-date.el (with-decoded-time-value): + Treat 'nil' as current time. This is mostly for XEmacs. + (encode-time-value, with-decoded-time-value): Obsolete. + (time-add, time-subtract, time-less-p): Use no-op autoloads, for + XEmacs. Define only if XEmacs, as they're now C builtins in Emacs. + * ldefs-boot.el: Update to match new time-date.el + * proced.el: Do not require time-date. + 2014-11-16 Lars Magne Ingebrigtsen * net/eww.el (eww-mode): Make the buffer read-only. diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el index f2dcdb4..25abf3f 100644 --- a/lisp/allout-widgets.el +++ b/lisp/allout-widgets.el @@ -2342,9 +2342,9 @@ We use a caching strategy, so the caller doesn't need to do so." got))) ;;;_ : Miscellaneous -;;;_ > allout-elapsed-time-seconds (triple) +;;;_ > allout-elapsed-time-seconds (time-value time-value) (defun allout-elapsed-time-seconds (end start) - "Return seconds between `current-time' style time START/END triples." + "Return seconds between START/END time values." (let ((elapsed (time-subtract end start))) (float-time elapsed))) ;;;_ > allout-frame-property (frame property) diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index ef155ee..a9f0ec7 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -2181,11 +2181,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." (size (string-to-number (match-string 6)))) ;; Move to the beginning of the data. (goto-char (match-end 0)) - (setq time - (format-time-string - "%Y-%m-%d %H:%M" - (let ((high (truncate (/ time 65536)))) - (list high (truncate (- time (* 65536.0 high))))))) + (setq time (format-time-string "%Y-%m-%d %H:%M" time)) (setq extname (cond ((equal name "// ") (propertize ".." 'face 'italic)) diff --git a/lisp/calendar/cal-dst.el b/lisp/calendar/cal-dst.el index e3cb690..2a9cdee 100644 --- a/lisp/calendar/cal-dst.el +++ b/lisp/calendar/cal-dst.el @@ -179,6 +179,7 @@ Return nil if no such transition can be found." (if (eq (car (current-time-zone probe)) hi-utc-diff) (setq hi probe) (setq lo probe))) + (setcdr hi (list (cdr hi))) hi)))) (autoload 'calendar-persian-to-absolute "cal-persia") diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 82bc05f..100e856 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -30,10 +30,9 @@ ;; value equal to HIGH * 2^16 + LOW + USEC * 10^-6 + PSEC * 10^-12 ;; seconds, where missing components are treated as zero. HIGH can be ;; negative, either because the value is a time difference, or because -;; the machine supports negative time stamps that fall before the epoch. -;; The macro `with-decoded-time-value' and the function -;; `encode-time-value' make it easier to deal with these formats. -;; See `time-subtract' for an example of how to use them. +;; it represents a time stamp before the epoch. Typically, there are +;; more time values than the underlying system time type supports, +;; but the reverse can also be true. ;;; Code: @@ -71,6 +70,7 @@ list (HIGH LOW MICRO PICO)." ,low ,micro) (when pico `(,pico)) (when type `(,type))) + (or ,gensym (setq ,gensym (current-time))) (if (consp ,gensym) (progn (setq ,low (pop ,gensym)) @@ -108,6 +108,10 @@ it is assumed that PICO was omitted and should be treated as zero." ((eq type 3) (list high low micro pico)) ((null type) (encode-time-value high low micro 0 pico)))) +(when (featurep 'emacs) + (make-obsolete 'encode-time-value nil "25.1") + (make-obsolete 'with-decoded-time-value nil "25.1")) + (autoload 'parse-time-string "parse-time") (autoload 'timezone-make-date-arpa-standard "timezone") @@ -158,47 +162,17 @@ TIME defaults to the current time." ;;;###autoload (defun seconds-to-time (seconds) - "Convert SECONDS (a floating point number) to a time value." - (let* ((usec (* 1000000 (mod seconds 1))) - (ps (round (* 1000000 (mod usec 1)))) - (us (floor usec)) - (lo (floor (mod seconds 65536))) - (hi (floor seconds 65536))) - (if (eq ps 1000000) - (progn - (setq ps 0) - (setq us (1+ us)) - (if (eq us 1000000) - (progn - (setq us 0) - (setq lo (1+ lo)) - (if (eq lo 65536) - (progn - (setq lo 0) - (setq hi (1+ hi)))))))) - (list hi lo us ps))) - -;;;###autoload -(defun time-less-p (t1 t2) - "Return non-nil if time value T1 is earlier than time value T2." - (with-decoded-time-value ((high1 low1 micro1 pico1 type1 t1) - (high2 low2 micro2 pico2 type2 t2)) - (or (< high1 high2) - (and (= high1 high2) - (or (< low1 low2) - (and (= low1 low2) - (or (< micro1 micro2) - (and (= micro1 micro2) - (< pico1 pico2))))))))) + "Convert SECONDS to a time value." + (time-add 0 seconds)) ;;;###autoload (defun days-to-time (days) "Convert DAYS into a time value." - (let* ((seconds (* 1.0 days 60 60 24)) - (high (condition-case nil (floor (/ seconds 65536)) - (range-error most-positive-fixnum)))) - (list high (condition-case nil (floor (- seconds (* 1.0 high 65536))) - (range-error 65535))))) + (let ((time (condition-case nil (seconds-to-time (* 86400.0 days)) + (range-error (list most-positive-fixnum 65535))))) + (if (integerp days) + (setcdr (cdr time) nil)) + time)) ;;;###autoload (defun time-since (time) @@ -207,53 +181,71 @@ TIME should be either a time value or a date-time string." (when (stringp time) ;; Convert date strings to internal time. (setq time (date-to-time time))) - (time-subtract (current-time) time)) + (time-subtract nil time)) ;;;###autoload (defalias 'subtract-time 'time-subtract) -;;;###autoload -(defun time-subtract (t1 t2) - "Subtract two time values, T1 minus T2. -Return the difference in the format of a time value." - (with-decoded-time-value ((high low micro pico type t1) - (high2 low2 micro2 pico2 type2 t2)) - (setq high (- high high2) - low (- low low2) - micro (- micro micro2) - pico (- pico pico2) - type (max type type2)) - (when (< pico 0) - (setq micro (1- micro) - pico (+ pico 1000000))) - (when (< micro 0) - (setq low (1- low) - micro (+ micro 1000000))) - (when (< low 0) - (setq high (1- high) - low (+ low 65536))) - (encode-time-value high low micro pico type))) +;; These autoloads do nothing in Emacs 25, where the functions are builtin. +;;;###autoload(autoload 'time-add "time-date") +;;;###autoload(autoload 'time-subtract "time-date") +;;;###autoload(autoload 'time-less-p "time-date") -;;;###autoload -(defun time-add (t1 t2) - "Add two time values T1 and T2. One should represent a time difference." - (with-decoded-time-value ((high low micro pico type t1) - (high2 low2 micro2 pico2 type2 t2)) - (setq high (+ high high2) - low (+ low low2) - micro (+ micro micro2) - pico (+ pico pico2) - type (max type type2)) - (when (>= pico 1000000) - (setq micro (1+ micro) - pico (- pico 1000000))) - (when (>= micro 1000000) - (setq low (1+ low) - micro (- micro 1000000))) - (when (>= low 65536) - (setq high (1+ high) - low (- low 65536))) - (encode-time-value high low micro pico type))) +(eval-when-compile + (when (not (featurep 'emacs)) + + (defun time-add (t1 t2) + "Add two time values T1 and T2. One should represent a time difference." + (with-decoded-time-value ((high low micro pico type t1) + (high2 low2 micro2 pico2 type2 t2)) + (setq high (+ high high2) + low (+ low low2) + micro (+ micro micro2) + pico (+ pico pico2) + type (max type type2)) + (when (>= pico 1000000) + (setq micro (1+ micro) + pico (- pico 1000000))) + (when (>= micro 1000000) + (setq low (1+ low) + micro (- micro 1000000))) + (when (>= low 65536) + (setq high (1+ high) + low (- low 65536))) + (encode-time-value high low micro pico type))) + + (defun time-subtract (t1 t2) + "Subtract two time values, T1 minus T2. +Return the difference in the format of a time value." + (with-decoded-time-value ((high low micro pico type t1) + (high2 low2 micro2 pico2 type2 t2)) + (setq high (- high high2) + low (- low low2) + micro (- micro micro2) + pico (- pico pico2) + type (max type type2)) + (when (< pico 0) + (setq micro (1- micro) + pico (+ pico 1000000))) + (when (< micro 0) + (setq low (1- low) + micro (+ micro 1000000))) + (when (< low 0) + (setq high (1- high) + low (+ low 65536))) + (encode-time-value high low micro pico type))) + + (defun time-less-p (t1 t2) + "Return non-nil if time value T1 is earlier than time value T2." + (with-decoded-time-value ((high1 low1 micro1 pico1 type1 t1) + (high2 low2 micro2 pico2 type2 t2)) + (or (< high1 high2) + (and (= high1 high2) + (or (< low1 low2) + (and (= low1 low2) + (or (< micro1 micro2) + (and (= micro1 micro2) + (< pico1 pico2))))))))))) ;;;###autoload (defun date-to-day (date) diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index 7fc6bf7..a189d24 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -125,9 +125,7 @@ of SECS seconds since the epoch. SECS may be a fraction." "Advance TIME by SECS seconds and optionally USECS microseconds and PSECS picoseconds. SECS may be either an integer or a floating point number." - (let ((delta (if (floatp secs) - (seconds-to-time secs) - (list (floor secs 65536) (mod secs 65536))))) + (let ((delta secs)) (if (or usecs psecs) (setq delta (time-add delta (list 0 0 (or usecs 0) (or psecs 0))))) (time-add time delta))) @@ -307,8 +305,8 @@ This function is called, by name, directly by the C code." ;; perhaps because Emacs was suspended for a long time, ;; limit how many times things get repeated. (if (and (numberp timer-max-repeats) - (< 0 (timer-until timer (current-time)))) - (let ((repeats (/ (timer-until timer (current-time)) + (< 0 (timer-until timer nil))) + (let ((repeats (/ (timer-until timer nil) (timer--repeat-delay timer)))) (if (> repeats timer-max-repeats) (timer-inc-time timer (* (timer--repeat-delay timer) @@ -374,13 +372,13 @@ This function returns a timer object which you can use in `cancel-timer'." ;; Handle numbers as relative times in seconds. (if (numberp time) - (setq time (timer-relative-time (current-time) time))) + (setq time (timer-relative-time nil time))) ;; Handle relative times like "2 hours 35 minutes" (if (stringp time) (let ((secs (timer-duration time))) (if secs - (setq time (timer-relative-time (current-time) secs))))) + (setq time (timer-relative-time nil secs))))) ;; Handle "11:23pm" and the like. Interpret it as meaning today ;; which admittedly is rather stupid if we have passed that time @@ -486,7 +484,7 @@ The value is a list that the debugger can pass to `with-timeout-unsuspend' when it exits, to make these timers start counting again." (mapcar (lambda (timer) (cancel-timer timer) - (list timer (time-subtract (timer--time timer) (current-time)))) + (list timer (time-subtract (timer--time timer) nil))) with-timeout-timers)) (defun with-timeout-unsuspend (timer-spec-list) @@ -495,7 +493,7 @@ The argument should be a value previously returned by `with-timeout-suspend'." (dolist (elt timer-spec-list) (let ((timer (car elt)) (delay (cadr elt))) - (timer-set-time timer (time-add (current-time) delay)) + (timer-set-time timer (time-add nil delay)) (timer-activate timer)))) (defun y-or-n-p-with-timeout (prompt seconds default-value) diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index b78c906..f60d660 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -27478,15 +27478,10 @@ If DATE lacks timezone information, GMT is assumed. (autoload 'time-to-seconds "time-date")) (autoload 'seconds-to-time "time-date" "\ -Convert SECONDS (a floating point number) to a time value. +Convert SECONDS to a time value. \(fn SECONDS)" nil nil) -(autoload 'time-less-p "time-date" "\ -Return non-nil if time value T1 is earlier than time value T2. - -\(fn T1 T2)" nil nil) - (autoload 'days-to-time "time-date" "\ Convert DAYS into a time value. @@ -27499,17 +27494,9 @@ TIME should be either a time value or a date-time string. \(fn TIME)" nil nil) (defalias 'subtract-time 'time-subtract) - -(autoload 'time-subtract "time-date" "\ -Subtract two time values, T1 minus T2. -Return the difference in the format of a time value. - -\(fn T1 T2)" nil nil) - -(autoload 'time-add "time-date" "\ -Add two time values T1 and T2. One should represent a time difference. - -\(fn T1 T2)" nil nil) +(autoload 'time-add "time-date") +(autoload 'time-subtract "time-date") +(autoload 'time-less-p "time-date") (autoload 'date-to-day "time-date" "\ Return the number of days between year 1 and DATE. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 5889743..01cd819 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4236,25 +4236,15 @@ Invokes `password-read' if available, `read-passwd' else." ("oct" . 10) ("nov" . 11) ("dec" . 12)) "Alist mapping month names to integers.") -;; FIXME: Shouldn't this also look at any subseconds parts of T1 and T2? ;;;###tramp-autoload (defun tramp-time-less-p (t1 t2) "Say whether time value T1 is less than time value T2." - (unless t1 (setq t1 '(0 0))) - (unless t2 (setq t2 '(0 0))) - (or (< (car t1) (car t2)) - (and (= (car t1) (car t2)) - (< (nth 1 t1) (nth 1 t2))))) + (time-less-p (or t1 0) (or t2 0))) -;; FIXME: Shouldn't this also look at any subseconds parts of T1 and T2? (defun tramp-time-subtract (t1 t2) "Subtract two time values. Return the difference in the format of a time value." - (unless t1 (setq t1 '(0 0))) - (unless t2 (setq t2 '(0 0))) - (let ((borrow (< (cadr t1) (cadr t2)))) - (list (- (car t1) (car t2) (if borrow 1 0)) - (- (+ (if borrow 65536 0) (cadr t1)) (cadr t2))))) + (time-subtract (or t1 0) (or t2 0))) ;;;###tramp-autoload (defun tramp-time-diff (t1 t2) diff --git a/lisp/proced.el b/lisp/proced.el index 592c0d0..188b8c3 100644 --- a/lisp/proced.el +++ b/lisp/proced.el @@ -49,8 +49,6 @@ ;;; Code: -(require 'time-date) ; for `with-decoded-time-value' - (defgroup proced nil "Proced mode." :group 'processes @@ -1186,17 +1184,8 @@ Return nil otherwise." (defun proced-time-lessp (t1 t2) "Return t if time value T1 is less than time value T2. Return `equal' if T1 equals T2. Return nil otherwise." - (with-decoded-time-value ((high1 low1 micro1 pico1 type1 t1) - (high2 low2 micro2 pico2 type2 t2)) - (cond ((< high1 high2)) - ((< high2 high1) nil) - ((< low1 low2)) - ((< low2 low1) nil) - ((< micro1 micro2)) - ((< micro2 micro1) nil) - ((< pico1 pico2)) - ((< pico2 pico1) nil) - (t 'equal)))) + (or (time-less-p t1 t2) + (if (not (time-less-p t2 t1)) 'equal))) ;;; Sorting diff --git a/lisp/timezone.el b/lisp/timezone.el index 1135092..8ff4396 100644 --- a/lisp/timezone.el +++ b/lisp/timezone.el @@ -295,13 +295,9 @@ Gregorian date Sunday, December 31, 1 BC." ;; (timezone-absolute-from-gregorian 1 1 1970) (days (- date current-time-origin)) (seconds-per-day (float 86400)) - (seconds (+ seconds (* days seconds-per-day))) - (current-time-arithmetic-base (float 65536)) - (hi (floor (/ seconds current-time-arithmetic-base))) - (hibase (* hi current-time-arithmetic-base)) - (lo (floor (- seconds hibase)))) - (and (< (abs (- seconds (+ hibase lo))) 2) ;; Check for integer overflow. - (cons hi lo)))) + (day-seconds (* days seconds-per-day))) + (condition-case nil (time-add day-seconds seconds) + (range-error)))) (defun timezone-time-zone-from-absolute (date seconds) "Compute the local time zone for DATE at time SECONDS after midnight. diff --git a/lisp/type-break.el b/lisp/type-break.el index f954e5d..a3af407 100644 --- a/lisp/type-break.el +++ b/lisp/type-break.el @@ -604,8 +604,7 @@ INTERVAL is the full length of an interval (defaults to TIME)." (type-break-time-warning-schedule time 'reset) (type-break-run-at-time (max 1 time) nil 'type-break-alarm) (setq type-break-time-next-break - (type-break-time-sum (or start (current-time)) - (or interval time)))) + (type-break-time-sum start (or interval time)))) (defun type-break-cancel-schedule () (type-break-cancel-time-warning-schedule) @@ -961,19 +960,11 @@ FRAC should be the inverse of the fractional value; for example, a value of (defun type-break-time-difference (a b) (round (float-time (time-subtract b a)))) -;; Return (in a new list the same in structure to that returned by -;; `current-time') the sum of the arguments. Each argument may be a time -;; list or a single integer, a number of seconds. -;; This function keeps the high and low 16 bits of the seconds properly -;; balanced so that the lower value never exceeds 16 bits. Otherwise, when -;; the result is passed to `current-time-string' it will toss some of the -;; "low" bits and format the time incorrectly. +;; Return a time value that is the sum of the time-value arguments. (defun type-break-time-sum (&rest tmlist) - (let ((sum '(0 0 0))) + (let ((sum '(0 0))) (dolist (tem tmlist) - (setq sum (time-add sum (if (integerp tem) - (list (floor tem 65536) (mod tem 65536)) - tem)))) + (setq sum (time-add sum tem))) sum)) (defun type-break-time-stamp (&optional when) diff --git a/src/ChangeLog b/src/ChangeLog index d188898..b169479 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,31 @@ +2014-11-17 Paul Eggert + + Improve time stamp handling, and be more consistent about it. + * editfns.c (invalid_time): New function. + Use it instead of 'error ("Invalid time specification")'. + (time_add, time_subtract, time_arith, Ftime_add, Ftime_less_p) + (decode_float_time, lisp_to_timespec, lisp_time_struct): + New functions. + (make_time_tail, make_time): Remove. All uses changed to use + new functions or plain list4i. + (disassemble_lisp_time): Return effective length if successful. + Check that LOW is an integer, if it's combined with other components. + (decode_time_components): Decode into struct lisp_time, not + struct timespec, so that we can support a wide set of times + regardless of whether time_t is signed. Decode plain numbers + as seconds since the Epoch, and nil as the current time. + (lisp_time_argument, lisp_seconds_argument, Ffloat_time): + Reimplement in terms of new functions. + (Fencode_time): Just use list2i. + (syms_of_editfns): Add time-add, time-subtract, time-less-p. + * keyboard.c (decode_timer): Don't allow the new formats (floating + point or nil) in timers. + * systime.h (LO_TIME_BITS): New constant. Use it everywhere in + place of the magic number '16'. + (struct lisp_time): New type. + (decode_time_components): Use it. + (lisp_to_timespec): New decl. + 2014-11-16 Lars Magne Ingebrigtsen * intervals.h (INTERVAL_WRITABLE_P): Check the `inhibit-read-only' diff --git a/src/editfns.c b/src/editfns.c index 376d8e3..0a07886 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -64,6 +64,7 @@ along with GNU Emacs. If not, see . */ extern Lisp_Object w32_get_internal_run_time (void); #endif +static struct lisp_time lisp_time_struct (Lisp_Object, int *); static void set_time_zone_rule (char const *); static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec, bool, struct tm *); @@ -1392,6 +1393,12 @@ time_overflow (void) error ("Specified time is not representable"); } +static void +invalid_time (void) +{ + error ("Invalid time specification"); +} + /* A substitute for mktime_z on platforms that lack it. It's not thread-safe, but should be good enough for Emacs in typical use. */ #ifndef HAVE_TZALLOC @@ -1420,26 +1427,26 @@ mktime_z (timezone_t tz, struct tm *tm) static EMACS_INT hi_time (time_t t) { - time_t hi = t >> 16; + time_t hi = t >> LO_TIME_BITS; /* Check for overflow, helping the compiler for common cases where no runtime check is needed, and taking care not to convert negative numbers to unsigned before comparing them. */ if (! ((! TYPE_SIGNED (time_t) - || MOST_NEGATIVE_FIXNUM <= TIME_T_MIN >> 16 + || MOST_NEGATIVE_FIXNUM <= TIME_T_MIN >> LO_TIME_BITS || MOST_NEGATIVE_FIXNUM <= hi) - && (TIME_T_MAX >> 16 <= MOST_POSITIVE_FIXNUM + && (TIME_T_MAX >> LO_TIME_BITS <= MOST_POSITIVE_FIXNUM || hi <= MOST_POSITIVE_FIXNUM))) time_overflow (); return hi; } -/* Return the bottom 16 bits of the time T. */ +/* Return the bottom bits of the time T. */ static int lo_time (time_t t) { - return t & ((1 << 16) - 1); + return t & ((1 << LO_TIME_BITS) - 1); } DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0, @@ -1453,6 +1460,96 @@ picosecond counts. */) return make_lisp_time (current_timespec ()); } +static struct lisp_time +time_add (struct lisp_time ta, struct lisp_time tb) +{ + EMACS_INT hi = ta.hi + tb.hi; + int lo = ta.lo + tb.lo; + int us = ta.us + tb.us; + int ps = ta.ps + tb.ps; + us += (1000000 <= ps); + ps -= (1000000 <= ps) * 1000000; + lo += (1000000 <= us); + us -= (1000000 <= us) * 1000000; + hi += (1 << LO_TIME_BITS <= lo); + lo -= (1 << LO_TIME_BITS <= lo) << LO_TIME_BITS; + return (struct lisp_time) { hi, lo, us, ps }; +} + +static struct lisp_time +time_subtract (struct lisp_time ta, struct lisp_time tb) +{ + EMACS_INT hi = ta.hi - tb.hi; + int lo = ta.lo - tb.lo; + int us = ta.us - tb.us; + int ps = ta.ps - tb.ps; + us -= (ps < 0); + ps += (ps < 0) * 1000000; + lo -= (us < 0); + us += (us < 0) * 1000000; + hi -= (lo < 0); + lo += (lo < 0) << LO_TIME_BITS; + return (struct lisp_time) { hi, lo, us, ps }; +} + +static Lisp_Object +time_arith (Lisp_Object a, Lisp_Object b, + struct lisp_time (*op) (struct lisp_time, struct lisp_time)) +{ + int alen, blen; + struct lisp_time ta = lisp_time_struct (a, &alen); + struct lisp_time tb = lisp_time_struct (b, &blen); + struct lisp_time t = op (ta, tb); + if (! (MOST_NEGATIVE_FIXNUM <= t.hi && t.hi <= MOST_POSITIVE_FIXNUM)) + time_overflow (); + Lisp_Object val = Qnil; + + switch (max (alen, blen)) + { + default: + val = Fcons (make_number (t.ps), val); + /* Fall through. */ + case 3: + val = Fcons (make_number (t.us), val); + /* Fall through. */ + case 2: + val = Fcons (make_number (t.lo), val); + val = Fcons (make_number (t.hi), val); + break; + } + + return val; +} + +DEFUN ("time-add", Ftime_add, Stime_add, 2, 2, 0, + doc: /* Return the sum of two time values A and B, as a time value. */) + (Lisp_Object a, Lisp_Object b) +{ + return time_arith (a, b, time_add); +} + +DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0, + doc: /* Return the difference between two time values A and B, as a time value. */) + (Lisp_Object a, Lisp_Object b) +{ + return time_arith (a, b, time_subtract); +} + +DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0, + doc: /* Return non-nil if time value T1 is earlier than time value T2. */) + (Lisp_Object t1, Lisp_Object t2) +{ + int t1len, t2len; + struct lisp_time a = lisp_time_struct (t1, &t1len); + struct lisp_time b = lisp_time_struct (t2, &t2len); + return ((a.hi != b.hi ? a.hi < b.hi + : a.lo != b.lo ? a.lo < b.lo + : a.us != b.us ? a.us < b.us + : a.ps < b.ps) + ? Qt : Qnil); +} + + DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time, 0, 0, 0, doc: /* Return the current run time used by Emacs. @@ -1491,21 +1588,6 @@ does the same thing as `current-time'. */) } -/* Make a Lisp list that represents the time T with fraction TAIL. */ -static Lisp_Object -make_time_tail (time_t t, Lisp_Object tail) -{ - return Fcons (make_number (hi_time (t)), - Fcons (make_number (lo_time (t)), tail)); -} - -/* Make a Lisp list that represents the system time T. */ -static Lisp_Object -make_time (time_t t) -{ - return make_time_tail (t, Qnil); -} - /* Make a Lisp list that represents the Emacs time T. T may be an invalid time, with a slightly negative tv_nsec value such as UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a @@ -1513,23 +1595,30 @@ make_time (time_t t) Lisp_Object make_lisp_time (struct timespec t) { + time_t s = t.tv_sec; int ns = t.tv_nsec; - return make_time_tail (t.tv_sec, list2i (ns / 1000, ns % 1000 * 1000)); + return list4i (hi_time (s), lo_time (s), ns / 1000, ns % 1000 * 1000); } /* Decode a Lisp list SPECIFIED_TIME that represents a time. Set *PHIGH, *PLOW, *PUSEC, *PPSEC to its parts; do not check their values. - Return true if successful. */ -static bool + Return 2, 3, or 4 to indicate the effective length of SPECIFIED_TIME + if successful, 0 if unsuccessful. */ +static int disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh, Lisp_Object *plow, Lisp_Object *pusec, Lisp_Object *ppsec) { + Lisp_Object high = make_number (0); + Lisp_Object low = specified_time; + Lisp_Object usec = make_number (0); + Lisp_Object psec = make_number (0); + int len = 4; + if (CONSP (specified_time)) { - Lisp_Object low = XCDR (specified_time); - Lisp_Object usec = make_number (0); - Lisp_Object psec = make_number (0); + high = XCAR (specified_time); + low = XCDR (specified_time); if (CONSP (low)) { Lisp_Object low_tail = XCDR (low); @@ -1540,40 +1629,119 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh, low_tail = XCDR (low_tail); if (CONSP (low_tail)) psec = XCAR (low_tail); + else + len = 3; } else if (!NILP (low_tail)) - usec = low_tail; + { + usec = low_tail; + len = 3; + } + else + len = 2; } + else + len = 2; - *phigh = XCAR (specified_time); - *plow = low; - *pusec = usec; - *ppsec = psec; - return 1; + /* When combining components, require LOW to be an integer, + as otherwise it would be a pain to add up times. */ + if (! INTEGERP (low)) + return 0; } + else if (INTEGERP (specified_time)) + len = 2; + + *phigh = high; + *plow = low; + *pusec = usec; + *ppsec = psec; + return len; +} - return 0; +/* Convert T into an Emacs time *RESULT, truncating toward minus infinity. + Return true if T is in range, false otherwise. */ +static bool +decode_float_time (double t, struct lisp_time *result) +{ + double lo_multiplier = 1 << LO_TIME_BITS; + double emacs_time_min = MOST_NEGATIVE_FIXNUM * lo_multiplier; + if (! (emacs_time_min <= t && t < -emacs_time_min)) + return false; + + double small_t = t / lo_multiplier; + EMACS_INT hi = small_t; + double t_sans_hi = t - hi * lo_multiplier; + int lo = t_sans_hi; + long double fracps = (t_sans_hi - lo) * 1e12L; +#ifdef INT_FAST64_MAX + int_fast64_t ifracps = fracps; + int us = ifracps / 1000000; + int ps = ifracps % 1000000; +#else + int us = fracps / 1e6L; + int ps = fracps - us * 1e6L; +#endif + us -= (ps < 0); + ps += (ps < 0) * 1000000; + lo -= (us < 0); + us += (us < 0) * 1000000; + hi -= (lo < 0); + lo += (lo < 0) << LO_TIME_BITS; + result->hi = hi; + result->lo = lo; + result->us = us; + result->ps = ps; + return true; } /* From the time components HIGH, LOW, USEC and PSEC taken from a Lisp list, generate the corresponding time value. + If LOW is floating point, the other components should be zero. - If RESULT is not null, store into *RESULT the converted time; - if the converted time does not fit into struct timespec, - store an invalid timespec to indicate the overflow. + If RESULT is not null, store into *RESULT the converted time. If *DRESULT is not null, store into *DRESULT the number of seconds since the start of the POSIX Epoch. - Return true if successful. */ + Return true if successful, false if the components are of the + wrong type or represent a time out of range. */ bool decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, Lisp_Object psec, - struct timespec *result, double *dresult) + struct lisp_time *result, double *dresult) { EMACS_INT hi, lo, us, ps; - if (! (INTEGERP (high) && INTEGERP (low) + if (! (INTEGERP (high) && INTEGERP (usec) && INTEGERP (psec))) return false; + if (! INTEGERP (low)) + { + if (FLOATP (low)) + { + double t = XFLOAT_DATA (low); + if (result && ! decode_float_time (t, result)) + return false; + if (dresult) + *dresult = t; + return true; + } + else if (NILP (low)) + { + struct timespec now = current_timespec (); + if (result) + { + result->hi = hi_time (now.tv_sec); + result->lo = lo_time (now.tv_sec); + result->us = now.tv_nsec / 1000; + result->ps = now.tv_nsec % 1000 * 1000; + } + if (dresult) + *dresult = now.tv_sec + now.tv_nsec / 1e9; + return true; + } + else + return false; + } + hi = XINT (high); lo = XINT (low); us = XINT (usec); @@ -1583,53 +1751,68 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, each overflow into the next higher-order component. */ us += ps / 1000000 - (ps % 1000000 < 0); lo += us / 1000000 - (us % 1000000 < 0); - hi += lo >> 16; + hi += lo >> LO_TIME_BITS; ps = ps % 1000000 + 1000000 * (ps % 1000000 < 0); us = us % 1000000 + 1000000 * (us % 1000000 < 0); - lo &= (1 << 16) - 1; + lo &= (1 << LO_TIME_BITS) - 1; if (result) { - if ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> 16 <= hi : 0 <= hi) - && hi <= TIME_T_MAX >> 16) - { - /* Return the greatest representable time that is not greater - than the requested time. */ - time_t sec = hi; - *result = make_timespec ((sec << 16) + lo, us * 1000 + ps / 1000); - } - else - *result = invalid_timespec (); + if (! (MOST_NEGATIVE_FIXNUM <= hi && hi <= MOST_POSITIVE_FIXNUM)) + return false; + result->hi = hi; + result->lo = lo; + result->us = us; + result->ps = ps; } if (dresult) - *dresult = (us * 1e6 + ps) / 1e12 + lo + hi * 65536.0; + { + double dhi = hi; + *dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS); + } return true; } +struct timespec +lisp_to_timespec (struct lisp_time t) +{ + if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi) + && t.hi <= TIME_T_MAX >> LO_TIME_BITS)) + return invalid_timespec (); + time_t s = (t.hi << LO_TIME_BITS) + t.lo; + int ns = t.us * 1000 + t.ps / 1000; + return make_timespec (s, ns); +} + /* Decode a Lisp list SPECIFIED_TIME that represents a time. + Store its effective length into *PLEN. If SPECIFIED_TIME is nil, use the current time. + Signal an error if SPECIFIED_TIME does not represent a time. */ +static struct lisp_time +lisp_time_struct (Lisp_Object specified_time, int *plen) +{ + Lisp_Object high, low, usec, psec; + struct lisp_time t; + int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec); + if (! (len && decode_time_components (high, low, usec, psec, &t, 0))) + invalid_time (); + *plen = len; + return t; +} - Round the time down to the nearest struct timespec value. - Return seconds since the Epoch. - Signal an error if unsuccessful. */ +/* Like lisp_time_struct, except return a struct timespec. + Discard any low-order digits. */ struct timespec lisp_time_argument (Lisp_Object specified_time) { - if (NILP (specified_time)) - return current_timespec (); - else - { - Lisp_Object high, low, usec, psec; - struct timespec t; - if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) - && decode_time_components (high, low, usec, psec, &t, 0))) - error ("Invalid time specification"); - if (! timespec_valid_p (t)) - time_overflow (); - return t; - } + int len; + struct lisp_time lt = lisp_time_struct (specified_time, &len); + struct timespec t = lisp_to_timespec (lt); + if (! timespec_valid_p (t)) + time_overflow (); + return t; } /* Like lisp_time_argument, except decode only the seconds part, @@ -1637,20 +1820,16 @@ lisp_time_argument (Lisp_Object specified_time) static time_t lisp_seconds_argument (Lisp_Object specified_time) { - if (NILP (specified_time)) - return time (NULL); - else - { - Lisp_Object high, low, usec, psec; - struct timespec t; - if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) - && decode_time_components (high, low, make_number (0), - make_number (0), &t, 0))) - error ("Invalid time specification"); - if (! timespec_valid_p (t)) - time_overflow (); - return t.tv_sec; - } + Lisp_Object high, low, usec, psec; + struct lisp_time t; + if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) + && decode_time_components (high, low, make_number (0), + make_number (0), &t, 0))) + invalid_time (); + if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi) + && t.hi <= TIME_T_MAX >> LO_TIME_BITS)) + time_overflow (); + return (t.hi << LO_TIME_BITS) + t.lo; } DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0, @@ -1668,18 +1847,10 @@ or (if you need time as a string) `format-time-string'. */) (Lisp_Object specified_time) { double t; - if (NILP (specified_time)) - { - struct timespec now = current_timespec (); - t = now.tv_sec + now.tv_nsec / 1e9; - } - else - { - Lisp_Object high, low, usec, psec; - if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) - && decode_time_components (high, low, usec, psec, 0, &t))) - error ("Invalid time specification"); - } + Lisp_Object high, low, usec, psec; + if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) + && decode_time_components (high, low, usec, psec, 0, &t))) + invalid_time (); return make_float (t); } @@ -1969,7 +2140,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) if (value == (time_t) -1) time_overflow (); - return make_time (value); + return list2i (hi_time (value), lo_time (value)); } DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0, @@ -4874,6 +5045,9 @@ functions if all the text being accessed has this property. */); defsubr (&Suser_full_name); defsubr (&Semacs_pid); defsubr (&Scurrent_time); + defsubr (&Stime_add); + defsubr (&Stime_subtract); + defsubr (&Stime_less_p); defsubr (&Sget_internal_run_time); defsubr (&Sformat_time_string); defsubr (&Sfloat_time); diff --git a/src/keyboard.c b/src/keyboard.c index 060784c..908eb59 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4429,10 +4429,15 @@ decode_timer (Lisp_Object timer, struct timespec *result) vector = XVECTOR (timer)->contents; if (! NILP (vector[0])) return 0; - - return (decode_time_components (vector[1], vector[2], vector[3], vector[8], - result, 0) - && timespec_valid_p (*result)); + if (! INTEGERP (vector[2])) + return false; + + struct lisp_time t; + if (! decode_time_components (vector[1], vector[2], vector[3], vector[8], + &t, 0)) + return false; + *result = lisp_to_timespec (t); + return timespec_valid_p (*result); } diff --git a/src/systime.h b/src/systime.h index 8f01804..e0f7eec 100644 --- a/src/systime.h +++ b/src/systime.h @@ -86,10 +86,23 @@ extern void set_waiting_for_input (struct timespec *); happen when this files is used outside the src directory). Use GCPRO1 to determine if lisp.h was included. */ #ifdef GCPRO1 + +/* Emacs uses the integer list (HI LO US PS) to represent the time + (HI << LO_TIME_BITS) + LO + US / 1e6 + PS / 1e12. */ +enum { LO_TIME_BITS = 16 }; + +/* A Lisp time (HI LO US PS), sans the cons cells. */ +struct lisp_time +{ + EMACS_INT hi; + int lo, us, ps; +}; + /* defined in editfns.c */ extern Lisp_Object make_lisp_time (struct timespec); extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, - Lisp_Object, struct timespec *, double *); + Lisp_Object, struct lisp_time *, double *); +extern struct timespec lisp_to_timespec (struct lisp_time); extern struct timespec lisp_time_argument (Lisp_Object); #endif commit 058f56d24f776bdc25bcac86fe1f8969a78374e9 Author: Lars Magne Ingebrigtsen Date: Sun Nov 16 23:39:53 2014 +0100 Make the eww buffers read-only Fixes: debbugs:16476 * net/eww.el (eww-mode): Make the buffer read-only. (eww-form-text): Inhibit read-only-ness in text input fields (bug#16476). diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0a73c57..7659d3c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2014-11-16 Lars Magne Ingebrigtsen + + * net/eww.el (eww-mode): Make the buffer read-only. + (eww-form-text): Inhibit read-only-ness in text input fields + (bug#16476). + 2014-11-16 Stefan Monnier * simple.el (execute-extended-command--shorter): Cut search here. diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 3373aac..fbac428 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -584,8 +584,7 @@ the like." (when (boundp 'tool-bar-map) (setq-local tool-bar-map eww-tool-bar-map)) (buffer-disable-undo) - ;;(setq buffer-read-only t) - ) + (setq buffer-read-only t)) ;;;###autoload (defun eww-browse-url (url &optional _new-window) @@ -837,6 +836,7 @@ appears in a or tag." (when (< (length value) width) (insert (make-string (- width (length value)) ? ))) (put-text-property start (point) 'face 'eww-form-text) + (put-text-property start (point) 'inhibit-read-only t) (put-text-property start (point) 'local-map eww-text-map) (put-text-property start (point) readonly-property t) (put-text-property start (point) 'eww-form @@ -920,6 +920,7 @@ See URL `https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input'.") (insert (make-string pad ? )))) (add-face-text-property (line-beginning-position) (point) 'eww-form-textarea) + (put-text-property (line-beginning-position) (point) 'inhibit-read-only t) (put-text-property (line-beginning-position) (point) 'local-map eww-textarea-map) (forward-line 1)) commit d1b04a9e7ada7070dbd84bb450411c1f169b3739 Author: Lars Magne Ingebrigtsen Date: Sun Nov 16 23:36:58 2014 +0100 Implement an `inhibit-read-only' text property * doc/lispref/text.texi (Special Properties): Mention `inhibit-read-only'. * src/buffer.c (Fbarf_if_buffer_read_only): Don't raise an error if the text at POSITION (new optional argument) has the `inhibit-read-only' text property set. * src/callint.c (Fcall_interactively): Pass in nil as argument to Fbarf_if_buffer_read_only. * src/fileio.c (Finsert_file_contents): Ditto. * src/insdel.c (prepare_to_modify_buffer_1): Pass start region in. * src/intervals.h (INTERVAL_WRITABLE_P): Check the `inhibit-read-only' text property. * src/textprop.c (verify_interval_modification): Check buffer readedness after the last interval. diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 9772391..b7423af 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,7 @@ +2014-11-16 Lars Magne Ingebrigtsen + + * text.texi (Special Properties): Mention `inhibit-read-only'. + 2014-11-14 Paul Eggert * os.texi (Time of Day): diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index f21d2b7..d1a1e6f 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -3241,6 +3241,11 @@ possible to remove a @code{read-only} property unless you know the special trick: bind @code{inhibit-read-only} to a non-@code{nil} value and then remove the property. @xref{Read Only Buffers}. +@item inhibit-read-only +@kindex inhibit-read-only @r{(text property)} +If a character has the property @code{inhibit-read-only}, and the +buffer is read-only, editing the character in question is allowed. + @item invisible @kindex invisible @r{(text property)} A non-@code{nil} @code{invisible} property can make a character invisible diff --git a/etc/NEWS b/etc/NEWS index 2172d07..b0e08d4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -107,6 +107,9 @@ non-native NS fullscreen. The default is nil. Set to t to enable animation when entering and leaving fullscreen. For native OSX fullscreen this has no effect. +*** A new text property `inhibit-read-only' can be used in read-only +buffers to allow certain parts of the text to be writable. + * Editing Changes in Emacs 25.1 diff --git a/src/ChangeLog b/src/ChangeLog index 7bb1666..d188898 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,22 @@ +2014-11-16 Lars Magne Ingebrigtsen + + * intervals.h (INTERVAL_WRITABLE_P): Check the `inhibit-read-only' + text property. + + * callint.c (Fcall_interactively): Pass in nil as argument to + Fbarf_if_buffer_read_only. + + * fileio.c (Finsert_file_contents): Ditto. + + * insdel.c (prepare_to_modify_buffer_1): Pass start region in. + + * textprop.c (verify_interval_modification): Check buffer + readedness after the last interval. + + * buffer.c (Fbarf_if_buffer_read_only): Don't raise an error if + the text at POSITION (new optional argument) has the + `inhibit-read-only' text property set. + 2014-11-16 Eli Zaretskii * window.c (window_scroll_pixel_based): Avoid truncation/rounding diff --git a/src/buffer.c b/src/buffer.c index 80791a1..9bdbfb8 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2184,12 +2184,20 @@ set_buffer_if_live (Lisp_Object buffer) } DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only, - Sbarf_if_buffer_read_only, 0, 0, 0, - doc: /* Signal a `buffer-read-only' error if the current buffer is read-only. */) - (void) + Sbarf_if_buffer_read_only, 0, 1, 0, + doc: /* Signal a `buffer-read-only' error if the current buffer is read-only. +If the text under POSITION (which defaults to point) has the +`inhibit-read-only' text property set, the error will not be raised. */) + (Lisp_Object pos) { + if (NILP (pos)) + XSETFASTINT (pos, PT); + else + CHECK_NUMBER (pos); + if (!NILP (BVAR (current_buffer, read_only)) - && NILP (Vinhibit_read_only)) + && NILP (Vinhibit_read_only) + && NILP (Fget_text_property (pos, Qinhibit_read_only, Qnil))) xsignal1 (Qbuffer_read_only, Fcurrent_buffer ()); return Qnil; } diff --git a/src/callint.c b/src/callint.c index 9a4573c..9467695 100644 --- a/src/callint.c +++ b/src/callint.c @@ -448,13 +448,13 @@ invoke it. If KEYS is omitted or nil, the return value of { if (! (*p == 'r' || *p == 'p' || *p == 'P' || *p == '\n')) - Fbarf_if_buffer_read_only (); + Fbarf_if_buffer_read_only (Qnil); p++; } record_then_fail = 1; } else - Fbarf_if_buffer_read_only (); + Fbarf_if_buffer_read_only (Qnil); } } /* Ignore this for semi-compatibility with Lucid. */ @@ -865,7 +865,7 @@ invoke it. If KEYS is omitted or nil, the return value of XSETINT (args[i], marker_position (args[i])); if (record_then_fail) - Fbarf_if_buffer_read_only (); + Fbarf_if_buffer_read_only (Qnil); Vthis_command = save_this_command; Vthis_original_command = save_this_original_command; diff --git a/src/fileio.c b/src/fileio.c index 7d7b0b3..b8dec3a 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3471,7 +3471,7 @@ by calling `format-decode', which see. */) error ("Cannot do file visiting in an indirect buffer"); if (!NILP (BVAR (current_buffer, read_only))) - Fbarf_if_buffer_read_only (); + Fbarf_if_buffer_read_only (Qnil); val = Qnil; p = Qnil; diff --git a/src/insdel.c b/src/insdel.c index 463392d..3133ca4 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1797,9 +1797,11 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end, ptrdiff_t *preserve_ptr) { struct buffer *base_buffer; + Lisp_Object temp; + XSETFASTINT (temp, start); if (!NILP (BVAR (current_buffer, read_only))) - Fbarf_if_buffer_read_only (); + Fbarf_if_buffer_read_only (temp); bset_redisplay (current_buffer); diff --git a/src/intervals.h b/src/intervals.h index 4e7a177..bd1f49d 100644 --- a/src/intervals.h +++ b/src/intervals.h @@ -197,6 +197,7 @@ set_interval_plist (INTERVAL i, Lisp_Object plist) /* Is this interval writable? Replace later with cache access. */ #define INTERVAL_WRITABLE_P(i) \ (i && (NILP (textget ((i)->plist, Qread_only)) \ + || !NILP (textget ((i)->plist, Qinhibit_read_only)) \ || ((CONSP (Vinhibit_read_only) \ ? !NILP (Fmemq (textget ((i)->plist, Qread_only), \ Vinhibit_read_only)) \ diff --git a/src/textprop.c b/src/textprop.c index 91ade8a..7ecac62 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -2298,6 +2298,11 @@ verify_interval_modification (struct buffer *buf, } } + if (i->position + LENGTH (i) < end + && (!NILP (BVAR (current_buffer, read_only)) + && NILP (Vinhibit_read_only))) + xsignal1 (Qbuffer_read_only, Fcurrent_buffer ()); + i = next_interval (i); } /* Keep going thru the interval containing the char before END. */ commit c94988f4b740738cbc4660ee9c64637e55ad5d76 Author: Stefan Monnier Date: Sun Nov 16 17:24:55 2014 -0500 * lisp/simple.el (execute-extended-command--shorter): Cut search here. (execute-extended-command): Instead of here. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 984f4ce..0a73c57 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-11-16 Stefan Monnier + + * simple.el (execute-extended-command--shorter): Cut search here. + (execute-extended-command): Instead of here. + 2014-11-16 Fabián Ezequiel Gallina * progmodes/python.el (python-mode): Avoid use of set-local to @@ -15,8 +20,8 @@ 2014-11-16 Ulf Jasper - * calendar/icalendar.el (icalendar--convert-tz-offset): Return - complete cons when offsets of standard time and daylight saving + * calendar/icalendar.el (icalendar--convert-tz-offset): + Return complete cons when offsets of standard time and daylight saving time are equal. (icalendar-export-region): Fix unbound variable warning. @@ -27,8 +32,8 @@ 2014-11-16 Fabián Ezequiel Gallina - * progmodes/python.el (python-shell-calculate-command): Rename - from python-shell-parse-command. Cleanup. + * progmodes/python.el (python-shell-calculate-command): + Rename from python-shell-parse-command. Cleanup. (run-python, run-python-internal): Use it. (python-shell-calculate-pythonpath): Rename from python-new-pythonpath. diff --git a/lisp/simple.el b/lisp/simple.el index 9665cd5..031970e 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1621,7 +1621,9 @@ If the value is non-nil and not a number, we wait 2 seconds." (setq len (1+ len)) (setq candidates (execute-extended-command--shorter-1 name len))) - (< len max))) + ;; Don't show the help message if the binding isn't + ;; significantly shorter than the M-x command the user typed. + (< len (- max 5)))) (let ((candidate (pop candidates))) (when (equal name (car-safe (completion-try-completion @@ -1686,13 +1688,7 @@ invoking, give a prefix argument to `execute-extended-command'." (while-no-input (setq binding (execute-extended-command--shorter (symbol-name function) typed)))) - (when (and binding - (or (not (stringp binding)) - (> (- (length (symbol-name function)) (length binding)) - ;; Don't show the help message if the - ;; binding isn't significantly shorter than - ;; the M-x command the user typed. - 5))) + (when binding (with-temp-message (format "You can run the command `%s' with %s" function commit c2e145b237b92e37c7ba5b004d5372178da723e8 Author: Fabián Ezequiel Gallina Date: Sun Nov 16 17:59:42 2014 -0300 * lisp/progmodes/python.el (python-mode): Avoid use of set-local to keep Emacs 24.x compatibility. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c4873c2..984f4ce 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-11-16 Fabián Ezequiel Gallina + + * progmodes/python.el (python-mode): Avoid use of set-local to + keep Emacs 24.x compatibility. + 2014-11-16 Lars Magne Ingebrigtsen * net/shr.el (shr): Move to the new defgroup `web'. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index d6c4199..3e204a9 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -4301,8 +4301,9 @@ Arguments START and END narrow the buffer region to work on." #'python-indent-line-function) (set (make-local-variable 'indent-region-function) #'python-indent-region) ;; Because indentation is not redundant, we cannot safely reindent code. - (setq-local electric-indent-inhibit t) - (setq-local electric-indent-chars (cons ?: electric-indent-chars)) + (set (make-local-variable 'electric-indent-inhibit) t) + (set (make-local-variable 'electric-indent-chars) + (cons ?: electric-indent-chars)) ;; Add """ ... """ pairing to electric-pair-mode. (add-hook 'post-self-insert-hook commit cbd90e1d30e7dd40d09780ac9924c7f3fe3b2905 Author: Lars Magne Ingebrigtsen Date: Sun Nov 16 21:29:40 2014 +0100 Move eww and shr to customization group `web' * net/eww.el (eww): Ditto. * net/shr.el (shr): Move to the new defgroup `web'. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e2ca228..c4873c2 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,9 @@ 2014-11-16 Lars Magne Ingebrigtsen + * net/shr.el (shr): Move to the new defgroup `web'. + + * net/eww.el (eww): Ditto. + * simple.el (execute-extended-command): Don't show the help message if the binding isn't significantly shorter than the M-x command the user typed (bug#19013). diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 93aecb6..3373aac 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -34,9 +34,9 @@ (defgroup eww nil "Emacs Web Wowser" - :version "24.4" + :version "25.1" :link '(custom-manual "(eww) Top") - :group 'hypermedia + :group 'web :prefix "eww-") (defcustom eww-header-line-format "%t: %u" diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 26fb647..1ced4e0 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -36,8 +36,8 @@ (defgroup shr nil "Simple HTML Renderer" - :version "24.1" - :group 'hypermedia) + :version "25.1" + :group 'web) (defcustom shr-max-image-proportion 0.9 "How big pictures displayed are in relation to the window they're in. commit 716492429686736f14e3d4f6285116b46b437ec9 Author: Lars Magne Ingebrigtsen Date: Sun Nov 16 20:37:51 2014 +0100 Only show the "You can run" message if it's significantly shorter * simple.el (execute-extended-command): Don't show the help message if the binding isn't significantly shorter than the M-x command the user typed (bug#19013). diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9d22d76..e2ca228 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2014-11-16 Lars Magne Ingebrigtsen + + * simple.el (execute-extended-command): Don't show the help + message if the binding isn't significantly shorter than the + M-x command the user typed (bug#19013). + 2014-11-16 Ulf Jasper * calendar/icalendar.el (icalendar--convert-tz-offset): Return diff --git a/lisp/simple.el b/lisp/simple.el index 203ea51..9665cd5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1686,7 +1686,13 @@ invoking, give a prefix argument to `execute-extended-command'." (while-no-input (setq binding (execute-extended-command--shorter (symbol-name function) typed)))) - (when binding + (when (and binding + (or (not (stringp binding)) + (> (- (length (symbol-name function)) (length binding)) + ;; Don't show the help message if the + ;; binding isn't significantly shorter than + ;; the M-x command the user typed. + 5))) (with-temp-message (format "You can run the command `%s' with %s" function commit 7261b4d9b2f35c3e520b488a8ba3cfde30f84a24 Author: Ulf Jasper Date: Sun Nov 16 17:23:45 2014 +0100 icalendar: fix issues regarding timezones without dst * lisp/calendar/icalendar.el (icalendar--convert-tz-offset): Return complete cons when offsets of standard time and daylight saving time are equal. (icalendar-export-region): Fix unbound variable warning. * test/automated/icalendar-tests.el (icalendar--parse-vtimezone): Add testcase where offsets of standard time and daylight saving time are equal. (icalendar-real-world): Fix error in test case. Expected result was wrong when offsets of standard time and daylight saving time were equal. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index bdf73e8..9d22d76 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2014-11-16 Ulf Jasper + + * calendar/icalendar.el (icalendar--convert-tz-offset): Return + complete cons when offsets of standard time and daylight saving + time are equal. + (icalendar-export-region): Fix unbound variable warning. + 2014-11-16 Fabián Ezequiel Gallina * progmodes/python.el (run-python): Allow CMD to be optional and diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index b024a38..9dba6ff 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -509,15 +509,19 @@ The strings are suitable for assembling into a TZ variable." ":" (substring offsetto 3 5)) ;; The start time. - (unless no-dst - (let* ((day (icalendar--get-weekday-number (substring byday -2))) - (week (if (eq day -1) + (let* ((day (if no-dst + 1 + (icalendar--get-weekday-number (substring byday -2)))) + (week (if no-dst + "1" + (if (eq day -1) byday - (substring byday 0 -2)))) + (substring byday 0 -2))))) ;; "Translate" the iCalendar way to specify the last ;; (sun|mon|...)day in month to the tzset way. (if (string= week "-1") ; last day as iCalendar calls it (setq week "5")) ; last day as tzset calls it + (when no-dst (setq bymonth "1")) (concat "M" bymonth "." week "." (if (eq day -1) "0" (int-to-string day)) ;; Start time. @@ -526,7 +530,7 @@ The strings are suitable for assembling into a TZ variable." ":" (substring dtstart -4 -2) ":" - (substring dtstart -2)))))))))) + (substring dtstart -2))))))))) (defun icalendar--parse-vtimezone (alist) "Turn a VTIMEZONE ALIST into a cons (ID . TZ-STRING). @@ -1025,7 +1029,8 @@ FExport diary data into iCalendar file: ") (found-error nil) (nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol) "?")) - (other-elements nil)) + (other-elements nil) + (cns-cons-or-list nil)) ;; prepare buffer with error messages (save-current-buffer (set-buffer (get-buffer-create "*icalendar-errors*")) diff --git a/test/ChangeLog b/test/ChangeLog index e0e04bc..4a6f005 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,12 @@ +2014-11-16 Ulf Jasper + + * automated/icalendar-tests.el (icalendar--parse-vtimezone): Add + testcase where offsets of standard time and daylight saving time + are equal. + (icalendar-real-world): Fix error in test case. Expected result + was wrong when offsets of standard time and daylight saving time + were equal. + 2014-11-16 Fabián Ezequiel Gallina * automated/python-tests.el diff --git a/test/automated/icalendar-tests.el b/test/automated/icalendar-tests.el index a6a5da2..23afb14 100644 --- a/test/automated/icalendar-tests.el +++ b/test/automated/icalendar-tests.el @@ -232,6 +232,27 @@ END:VTIMEZONE (should (string= "anothername, with a comma" (car result))) (message (cdr result)) (should (string= "STD-02:00DST-03:00,M3.2.1/03:00:00,M10.2.1/04:00:00" + (cdr result))) + ;; offsetfrom = offsetto + (setq vtimezone (icalendar-tests--get-ical-event "BEGIN:VTIMEZONE +TZID:Kolkata\, Chennai\, Mumbai\, New Delhi +X-MICROSOFT-CDO-TZID:23 +BEGIN:STANDARD +DTSTART:16010101T000000 +TZOFFSETFROM:+0530 +TZOFFSETTO:+0530 +END:STANDARD +BEGIN:DAYLIGHT +DTSTART:16010101T000000 +TZOFFSETFROM:+0530 +TZOFFSETTO:+0530 +END:DAYLIGHT +END:VTIMEZONE +")) + (setq result (icalendar--parse-vtimezone vtimezone)) + (should (string= "Kolkata, Chennai, Mumbai, New Delhi" (car result))) + (message (cdr result)) + (should (string= "STD-05:30DST-05:30,M1.1.1/00:00:00,M1.1.1/00:00:00" (cdr result))))) (ert-deftest icalendar--convert-ordinary-to-ical () @@ -1389,14 +1410,14 @@ END:VALARM END:VEVENT END:VCALENDAR" nil - "&9/5/2003 10:30-15:30 On-Site Interview + "&9/5/2003 07:00-12:00 On-Site Interview Desc: 10:30am - Blah Location: Cccc Organizer: MAILTO:aaaaaaa@aaaaaaa.com Status: CONFIRMED UID: 040000008200E00074C5B7101A82E0080000000080B6DE661216C301000000000000000010000000DB823520692542408ED02D7023F9DFF9 " - "&5/9/2003 10:30-15:30 On-Site Interview + "&5/9/2003 07:00-12:00 On-Site Interview Desc: 10:30am - Blah Location: Cccc Organizer: MAILTO:aaaaaaa@aaaaaaa.com commit a97fd0eb8d043170601808e6e5a349e6981c30c4 Author: Oscar Fuentes Date: Sun Nov 16 15:55:33 2014 +0100 lisp/ChangeLog: removed duplicate entry diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 129859c..bdf73e8 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -3,15 +3,6 @@ * progmodes/python.el (run-python): Allow CMD to be optional and default it to a safe command, even for Windows. (bug#18596) -2014-11-13 Oscar Fuentes - - Add faces for the VC modeline state indicator. - * lisp/vc/vc-hooks.el: (vc-state-faces, vc-state-base-face - vc-up-to-date-state, vc-needs-update-state, vc-locked-state) - vc-locally-added-state, vc-conflict-state, vc-removed-state, - vc-missing-state, vc-edited-state): New faces. - (vc-default-mode-line-string): Use them (bug#19043). - 2014-11-16 Fabián Ezequiel Gallina * progmodes/python.el (python-shell-calculate-command): Rename commit 1af9075908ed922e13d6d5a6b4f51f093d79f7f1 Author: Lars Magne Ingebrigtsen Date: Sun Nov 16 15:54:12 2014 +0100 Set the push default to "current", which should work everywhere diff --git a/admin/notes/git-workflow b/admin/notes/git-workflow index 33ba39f..71ebd2a 100644 --- a/admin/notes/git-workflow +++ b/admin/notes/git-workflow @@ -20,9 +20,11 @@ mkdir ~/emacs cd ~/emacs git clone @git.sv.gnu.org:/srv/git/emacs.git mv emacs trunk +(cd trunk; git config push.default current) ./trunk/admin/git-new-workdir trunk emacs-24 cd emacs-24 git checkout emacs-24 +git config push.default current You now have both branches conveniently accessible, and you can do "git pull" in them once in a while to keep updated. commit af19cccc837b1371911988cf99c8c6140bb9cc4a Author: Lars Magne Ingebrigtsen Date: Sun Nov 16 15:31:20 2014 +0100 Mention how to get rid of X11 warnings diff --git a/admin/notes/git-workflow b/admin/notes/git-workflow index 798f363..33ba39f 100644 --- a/admin/notes/git-workflow +++ b/admin/notes/git-workflow @@ -70,3 +70,18 @@ Merging emacs-24 to trunk ========================= This has yet to be written. + + +Warnings about X11 forwarding +============================= + +If you get warnings like + +Warning: No xauth data; using fake authentication data for X11 forwarding. +X11 forwarding request failed on channel 0 + +when pulling or pushing data, add the following to the start of +~/.ssh/config: + +Host git.sv.gnu.org + ForwardX11 no commit 651ebee618d9ee31b5a6035cbb06d575a626a42c Author: Fabián Ezequiel Gallina Date: Sun Nov 16 11:20:25 2014 -0300 Fixes: debbugs:18596 * lisp/progmodes/python.el (run-python): Allow CMD to be optional and default it to a safe command, even for Windows. (bug#18596) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0753c40..129859c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-11-16 Fabián Ezequiel Gallina + + * progmodes/python.el (run-python): Allow CMD to be optional and + default it to a safe command, even for Windows. (bug#18596) + 2014-11-13 Oscar Fuentes Add faces for the VC modeline state indicator. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index f849025..d6c4199 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2473,16 +2473,17 @@ killed." proc-buffer-name))) ;;;###autoload -(defun run-python (cmd &optional dedicated show) +(defun run-python (&optional cmd dedicated show) "Run an inferior Python process. Input and output via buffer named after `python-shell-buffer-name'. If there is a process already running in that buffer, just switch to it. -With argument, allows you to define CMD so you can edit the -command used to call the interpreter and define DEDICATED, so a -dedicated process for the current buffer is open. When numeric -prefix arg is other than 0 or 4 do not SHOW. +Argument CMD defaults to `python-shell-calculate-command' return +value. When called interactively with `prefix-arg', it allows +the user to edit such value and choose whether the interpreter +should be DEDICATED for the current buffer. When numeric prefix +arg is other than 0 or 4 do not SHOW. Runs the hook `inferior-python-mode-hook' after `comint-mode-hook' is run. (Type \\[describe-mode] in the @@ -2495,7 +2496,8 @@ process buffer for a list of commands.)" (= (prefix-numeric-value current-prefix-arg) 4)) (list (python-shell-calculate-command) nil t))) (python-shell-make-comint - cmd (python-shell-get-process-name dedicated) show) + (or cmd (python-shell-calculate-command)) + (python-shell-get-process-name dedicated) show) dedicated) (defun run-python-internal () commit 48b2b327831d2f71b02f2f16096765e2cad1d4c5 Author: Óscar Fuentes Date: Sun Nov 16 15:06:23 2014 +0100 Add faces for the VC modeline state indicator. Fixes: debbugs:19043 Add faces for the VC modeline state indicator. * lisp/vc/vc-hooks.el: (vc-state-faces, vc-state-base-face vc-up-to-date-state, vc-needs-update-state, vc-locked-state) vc-locally-added-state, vc-conflict-state, vc-removed-state, vc-missing-state, vc-edited-state): New faces. (vc-default-mode-line-string): Use them (bug#19043). diff --git a/lisp/ChangeLog b/lisp/ChangeLog index dbab5c6..0753c40 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,12 @@ +2014-11-13 Oscar Fuentes + + Add faces for the VC modeline state indicator. + * lisp/vc/vc-hooks.el: (vc-state-faces, vc-state-base-face + vc-up-to-date-state, vc-needs-update-state, vc-locked-state) + vc-locally-added-state, vc-conflict-state, vc-removed-state, + vc-missing-state, vc-edited-state): New faces. + (vc-default-mode-line-string): Use them (bug#19043). + 2014-11-16 Fabián Ezequiel Gallina * progmodes/python.el (python-shell-calculate-command): Rename commit 6f167f95dc9dae8fc8533ee4d9a497c4f08021b2 Author: Fabián Ezequiel Gallina Date: Sun Nov 16 10:47:14 2014 -0300 * lisp/progmodes/python.el (python-shell-calculate-command): Rename from python-shell-parse-command. Cleanup. (run-python, run-python-internal): Use it. (python-shell-calculate-pythonpath): Rename from python-new-pythonpath. (python-shell-calculate-process-environment): Use it. (python-shell-calculate-exec-path): Add comment. * test/automated/python-tests.el (python-shell-calculate-process-environment-2): Fix test. (python-shell-calculate-process-environment-1) (python-shell-calculate-process-environment-3): Cleanup. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index cc749c8..dbab5c6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,13 @@ +2014-11-16 Fabián Ezequiel Gallina + + * progmodes/python.el (python-shell-calculate-command): Rename + from python-shell-parse-command. Cleanup. + (run-python, run-python-internal): Use it. + (python-shell-calculate-pythonpath): Rename from + python-new-pythonpath. + (python-shell-calculate-process-environment): Use it. + (python-shell-calculate-exec-path): Add comment. + 2014-11-16 Thierry Banel (tiny change) * calc/calc-arith.el (math-max-list, math-min-list): Fix bug diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 7ed218c..f849025 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2084,19 +2084,22 @@ uniqueness for different types of configurations." (or python-shell-virtualenv-root "") (mapconcat #'identity python-shell-exec-path ""))))) -(defun python-shell-parse-command () ;FIXME: why name it "parse"? +(defun python-shell-calculate-command () "Calculate the string used to execute the inferior Python process." - ;; FIXME: process-environment doesn't seem to be used anywhere within - ;; this let. - (let ((process-environment (python-shell-calculate-process-environment)) - (exec-path (python-shell-calculate-exec-path))) + (let ((exec-path (python-shell-calculate-exec-path))) + ;; `exec-path' gets tweaked so that virtualenv's specific + ;; `python-shell-interpreter' absolute path can be found by + ;; `executable-find'. (format "%s %s" - ;; FIXME: Why executable-find? (executable-find python-shell-interpreter) python-shell-interpreter-args))) -(defun python-new-pythonpath () - "Calculate the new PYTHONPATH value from `python-shell-extra-pythonpaths'." +(define-obsolete-function-alias + 'python-shell-parse-command + #'python-shell-calculate-command "25.1") + +(defun python-shell-calculate-pythonpath () + "Calculate the PYTHONPATH using `python-shell-extra-pythonpaths'." (let ((pythonpath (getenv "PYTHONPATH")) (extra (mapconcat 'identity python-shell-extra-pythonpaths @@ -2114,7 +2117,7 @@ uniqueness for different types of configurations." (directory-file-name python-shell-virtualenv-root) nil))) (when python-shell-extra-pythonpaths - (setenv "PYTHONPATH" (python-new-pythonpath))) + (setenv "PYTHONPATH" (python-shell-calculate-pythonpath))) (if (not virtualenv) process-environment (setenv "PYTHONHOME" nil) @@ -2126,8 +2129,10 @@ uniqueness for different types of configurations." (defun python-shell-calculate-exec-path () "Calculate exec path given `python-shell-virtualenv-root'." - (let ((path (append python-shell-exec-path - exec-path nil))) ;FIXME: Why nil? + (let ((path (append + ;; Use nil as the tail so that the list is a full copy, + ;; this is a paranoid safeguard for side-effects. + python-shell-exec-path exec-path nil))) (if (not python-shell-virtualenv-root) path (cons (expand-file-name "bin" python-shell-virtualenv-root) @@ -2485,10 +2490,10 @@ process buffer for a list of commands.)" (interactive (if current-prefix-arg (list - (read-shell-command "Run Python: " (python-shell-parse-command)) + (read-shell-command "Run Python: " (python-shell-calculate-command)) (y-or-n-p "Make dedicated process? ") (= (prefix-numeric-value current-prefix-arg) 4)) - (list (python-shell-parse-command) nil t))) + (list (python-shell-calculate-command) nil t))) (python-shell-make-comint cmd (python-shell-get-process-name dedicated) show) dedicated) @@ -2512,7 +2517,7 @@ startup." (inferior-python-mode-hook nil)) (get-buffer-process (python-shell-make-comint - (python-shell-parse-command) + (python-shell-calculate-command) (python-shell-internal-get-process-name) nil t)))) (defun python-shell-get-buffer () diff --git a/test/ChangeLog b/test/ChangeLog index a09c6f7..e0e04bc 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,5 +1,12 @@ 2014-11-16 Fabián Ezequiel Gallina + * automated/python-tests.el + (python-shell-calculate-process-environment-2): Fix test. + (python-shell-calculate-process-environment-1) + (python-shell-calculate-process-environment-3): Cleanup. + +2014-11-16 Fabián Ezequiel Gallina + * automated/python-tests.el (python-indent-dedenters-8): New test for Bug#18432. diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el index f368f99..e4ce535 100644 --- a/test/automated/python-tests.el +++ b/test/automated/python-tests.el @@ -1836,8 +1836,7 @@ Using `python-shell-interpreter' and (ert-deftest python-shell-calculate-process-environment-1 () "Test `python-shell-process-environment' modification." - (let* ((original-process-environment process-environment) - (python-shell-process-environment + (let* ((python-shell-process-environment '("TESTVAR1=value1" "TESTVAR2=value2")) (process-environment (python-shell-calculate-process-environment))) @@ -1846,8 +1845,8 @@ Using `python-shell-interpreter' and (ert-deftest python-shell-calculate-process-environment-2 () "Test `python-shell-extra-pythonpaths' modification." - (let* ((original-process-environment process-environment) - (original-pythonpath (getenv "PYTHONPATH")) + (let* ((process-environment process-environment) + (original-pythonpath (setenv "PYTHONPATH" "path3")) (paths '("path1" "path2")) (python-shell-extra-pythonpaths paths) (process-environment @@ -1859,8 +1858,7 @@ Using `python-shell-interpreter' and (ert-deftest python-shell-calculate-process-environment-3 () "Test `python-shell-virtualenv-path' modification." - (let* ((original-process-environment process-environment) - (original-path (or (getenv "PATH") "")) + (let* ((original-path (or (getenv "PATH") "")) (python-shell-virtualenv-path (directory-file-name user-emacs-directory)) (process-environment