; time-stamp: rename some internal functions to include "--"

* lisp/time-stamp.el (time-stamp--zformat-from-parsed-options)
(time-stamp--string-internal) (time-stamp--do-letter-case)
(time-stamp--do-number) (time-stamp--filtered-buffer-file-name)
(time-stamp--conv-warn) (time-stamp--once-internal): New names.
* test/lisp/time-stamp-tests.el (define-formatz-tests)
(formatz-find-test-def-function):
Give generated test names "time-stamp-" prefix.
This commit is contained in:
Stephen Gildea
2026-04-07 09:27:06 -07:00
parent f5a2357a89
commit 5d9b6c8262
2 changed files with 81 additions and 82 deletions

View File

@@ -399,7 +399,7 @@ template, and where in the file it can occur."
(setq ts-count 1)
(time-stamp--message "time-stamp-count is not an integer"))
((< ts-count 1)
;; We need to call time-stamp-once at least once
;; We need to call time-stamp--once-internal at least once
;; to output any warnings about time-stamp not being active.
(setq ts-count 1)))
;; Figure out what lines the end should be on.
@@ -429,14 +429,14 @@ template, and where in the file it can occur."
(while (and start
(< start search-limit)
(> ts-count 0))
(setq start (time-stamp-once start search-limit ts-start ts-end
ts-format format-lines end-lines))
(setq start (time-stamp--once-internal start search-limit ts-start ts-end
ts-format format-lines end-lines))
(setq ts-count (1- ts-count)))
(set-marker search-limit nil))))
nil)
(defun time-stamp-once (start search-limit ts-start ts-end
ts-format format-lines end-lines)
(defun time-stamp--once-internal (start search-limit ts-start ts-end
ts-format format-lines end-lines)
"Update one time stamp. Internal routine called by `time-stamp'.
Returns the end point, which is where `time-stamp' begins the next search."
(let ((case-fold-search nil)
@@ -515,7 +515,7 @@ ARG is positive, otherwise nil."
(defun time-stamp--format (format time)
"FORMAT a TIME in zone `time-stamp-time-zone'.
Internal helper used by `time-stamp-string-preprocess'."
Helper used by `time-stamp--string-internal'."
(format-time-string format time time-stamp-time-zone))
(defun time-stamp-string (&optional ts-format time)
@@ -529,7 +529,7 @@ documentation of `time-stamp-format' for details.
Optional second argument TIME is only for testing; normally the current
time is used. The time zone is determined by `time-stamp-time-zone'."
(if (stringp (or ts-format (setq ts-format time-stamp-format)))
(time-stamp-string-preprocess ts-format time)))
(time-stamp--string-internal ts-format time)))
(defconst time-stamp-no-file "(no file)"
@@ -544,7 +544,7 @@ time is used. The time zone is determined by `time-stamp-time-zone'."
;;; The : modifier is a temporary conversion feature used to resolve
;;; ambiguous formats--formats that are changing (over time) incompatibly.
(defun time-stamp-string-preprocess (format &optional time)
(defun time-stamp--string-internal (format &optional time)
"Use FORMAT to format date, time, and user information.
Optional second argument TIME is only for testing.
This is an internal routine implementing extensions to `format-time-string'
@@ -626,7 +626,7 @@ and all `time-stamp-format' compatibility."
((eq cur-char ?%)
"%")
((eq cur-char ?a) ;day of week
(time-stamp-do-letter-case
(time-stamp--do-letter-case
nil upcase title-case change-case
(if (> colon-cnt 0)
(if (string-equal field-width "")
@@ -639,21 +639,22 @@ and all `time-stamp-format' compatibility."
(<= (string-to-number field-width) 3)
(not flag-minimize)
(not flag-pad-with-spaces))
(time-stamp-conv-warn "%3A" "%#a")
(time-stamp--conv-warn "%3A" "%#a")
(time-stamp--format "%#a" time))
((or (> colon-cnt 0)
change-case upcase title-case
flag-minimize flag-pad-with-spaces
(string-equal field-width ""))
(time-stamp-do-letter-case
(time-stamp--do-letter-case
nil upcase title-case change-case
(time-stamp--format "%A" time)))
(t (time-stamp-conv-warn (format "%%%sA" field-width)
(format "%%#%sA" field-width)
(format "%%:%sA" field-width))
(t (time-stamp--conv-warn (format "%%%sA" field-width)
(format "%%#%sA" field-width)
(format "%%:%sA" field-width))
(time-stamp--format "%#A" time))))
((eq cur-char ?b) ;month name
(time-stamp-do-letter-case
(time-stamp--do-letter-case
nil upcase title-case change-case
(if (> colon-cnt 0)
(if (string-equal field-width "")
@@ -666,41 +667,41 @@ and all `time-stamp-format' compatibility."
(<= (string-to-number field-width) 3)
(not flag-minimize)
(not flag-pad-with-spaces))
(time-stamp-conv-warn "%3B" "%#b")
(time-stamp--conv-warn "%3B" "%#b")
(time-stamp--format "%#b" time))
((or (> colon-cnt 0)
change-case upcase title-case
flag-minimize flag-pad-with-spaces
(string-equal field-width ""))
(time-stamp-do-letter-case
(time-stamp--do-letter-case
nil upcase title-case change-case
(time-stamp--format "%B" time)))
(t (time-stamp-conv-warn (format "%%%sB" field-width)
(format "%%#%sB" field-width)
(format "%%:%sB" field-width))
(t (time-stamp--conv-warn (format "%%%sB" field-width)
(format "%%#%sB" field-width)
(format "%%:%sB" field-width))
(time-stamp--format "%#B" time))))
((eq cur-char ?d) ;day of month, 1-31
(time-stamp-do-number cur-char colon-cnt field-width time))
(time-stamp--do-number cur-char colon-cnt field-width time))
((eq cur-char ?H) ;hour, 0-23
(time-stamp-do-number cur-char colon-cnt field-width time))
(time-stamp--do-number cur-char colon-cnt field-width time))
((eq cur-char ?I) ;hour, 1-12
(time-stamp-do-number cur-char colon-cnt field-width time))
(time-stamp--do-number cur-char colon-cnt field-width time))
((eq cur-char ?m) ;month number, 1-12
(time-stamp-do-number cur-char colon-cnt field-width time))
(time-stamp--do-number cur-char colon-cnt field-width time))
((eq cur-char ?M) ;minute, 0-59
(time-stamp-do-number cur-char colon-cnt field-width time))
(time-stamp--do-number cur-char colon-cnt field-width time))
((eq cur-char ?p) ;AM or PM
(time-stamp-do-letter-case
(time-stamp--do-letter-case
t upcase title-case change-case
(time-stamp--format "%p" time)))
((eq cur-char ?P) ;AM or PM
(if (and upcase (not change-case))
"" ;discourage inconsistent "%^P"
(time-stamp-do-letter-case
(time-stamp--do-letter-case
t upcase title-case change-case
(time-stamp--format "%p" time))))
((eq cur-char ?S) ;seconds, 00-60
(time-stamp-do-number cur-char colon-cnt field-width time))
(time-stamp--do-number cur-char colon-cnt field-width time))
((eq cur-char ?w) ;weekday number, Sunday is 0
(time-stamp--format "%w" time))
((eq cur-char ?y) ;year
@@ -708,10 +709,10 @@ and all `time-stamp-format' compatibility."
(if (or (string-equal field-width "")
(<= (string-to-number field-width) 2))
(string-to-number (time-stamp--format "%y" time))
(time-stamp-conv-warn
(time-stamp--conv-warn
(format "%%%sy" field-width) "%Y")
(string-to-number (time-stamp--format "%Y" time)))
(time-stamp-conv-warn "%:y" "%Y")
(time-stamp--conv-warn "%:y" "%Y")
(string-to-number (time-stamp--format "%Y" time))))
((eq cur-char ?Y) ;4-digit year
(string-to-number (time-stamp--format "%Y" time)))
@@ -738,9 +739,9 @@ and all `time-stamp-format' compatibility."
(not flag-pad-with-spaces)
(not flag-pad-with-zeros)
(= field-width-num 0))
(time-stamp-conv-warn "%z" "%#Z" "%5z")
(time-stamp--conv-warn "%z" "%#Z" "%5z")
(time-stamp--format "%#Z" time))
(t (time-stamp-formatz-from-parsed-options
(t (time-stamp--zformat-from-parsed-options
flag-minimize
flag-pad-with-spaces
flag-pad-with-zeros
@@ -748,25 +749,25 @@ and all `time-stamp-format' compatibility."
field-width-num
offset-secs)))))
((eq cur-char ?Z) ;time zone name
(time-stamp-do-letter-case
(time-stamp--do-letter-case
t upcase title-case change-case
(time-stamp--format "%Z" time)))
((eq cur-char ?f) ;buffer-file-name, base name only
(if buffer-file-name
(time-stamp-filtered-buffer-file-name :nondirectory)
(time-stamp--filtered-buffer-file-name :nondirectory)
time-stamp-no-file))
((eq cur-char ?F) ;buffer-file-name, absolute name
(if buffer-file-name
(time-stamp-filtered-buffer-file-name :absolute)
(time-stamp--filtered-buffer-file-name :absolute)
time-stamp-no-file))
((eq cur-char ?s) ;system name, legacy
(time-stamp-conv-warn "%s" "%Q")
(time-stamp--conv-warn "%s" "%Q")
(time-stamp--system-name :full))
((eq cur-char ?u) ;user name, legacy
(time-stamp-conv-warn "%u" "%l")
(time-stamp--conv-warn "%u" "%l")
(user-login-name))
((eq cur-char ?U) ;user full name, legacy
(time-stamp-conv-warn "%U" "%L")
(time-stamp--conv-warn "%U" "%L")
(user-full-name))
((eq cur-char ?l) ;login name
(user-login-name))
@@ -808,15 +809,15 @@ and all `time-stamp-format' compatibility."
(setq ind (1+ ind)))
(apply #'concat (nreverse result))))
(defun time-stamp-do-letter-case (change-is-downcase
upcase title-case change-case text)
(defun time-stamp--do-letter-case (change-is-downcase
upcase title-case change-case text)
"Apply upper- and lower-case conversions to TEXT per the flags.
CHANGE-IS-DOWNCASE non-nil indicates that modifier CHANGE-CASE
requests lowercase, otherwise the modifier requests uppercase.
UPCASE is non-nil if the \"^\" modifier is active.
TITLE-CASE is non-nil if the \"*\" modifier is active.
CHANGE-CASE is non-nil if the \"#\" modifier is active.
This is an internal helper for `time-stamp-string-preprocess'."
This is a helper for `time-stamp--string-internal'."
(cond ((and upcase change-case)
(downcase text))
((and title-case change-case)
@@ -830,18 +831,18 @@ This is an internal helper for `time-stamp-string-preprocess'."
(t
text)))
(defun time-stamp-do-number (format-char colon-count field-width time)
(defun time-stamp--do-number (format-char colon-count field-width time)
"Handle a FORMAT-CHAR mostly compatible with `format-time-string'.
The default width/padding may be different from `format-time-string'.
COLON-COUNT is non-0 if \":\" was specified. FIELD-WIDTH is the string
width specification or \"\". TIME is the time to convert.
This is an internal helper for `time-stamp-string-preprocess'."
This is a helper for `time-stamp--string-internal'."
(let ((format-string (concat "%" (char-to-string format-char))))
(if (and (> colon-count 0) (not (string-equal field-width "")))
"" ;discourage "%:2d" and the like
(string-to-number (time-stamp--format format-string time)))))
(defun time-stamp-filtered-buffer-file-name (type)
(defun time-stamp--filtered-buffer-file-name (type)
"Return a printable string representing the buffer file name.
Non-graphic characters are replaced by ?. TYPE is :absolute
for the full name or :nondirectory for base name only."
@@ -864,7 +865,6 @@ for the full name or :nondirectory for base name only."
(defun time-stamp--count-newlines (str)
"Return the number of newlines in STR."
(declare (pure t))
(let ((nl-count 0)
(nl-start 0))
(while (setq nl-start (string-match-p "\n" str nl-start))
@@ -884,7 +884,6 @@ TYPE is :short for the unqualified name, :full for the full name."
(defun time-stamp--system-name-1 (sysname type)
"Return SYSNAME, shortened if TYPE is :short."
(declare (pure t))
(let (first-dot)
(if (and (eq type :short)
(setq first-dot (string-match-p "\\." sysname)))
@@ -909,7 +908,7 @@ to change in the future to be compatible with `format-time-string'.
The new formats being recommended now will continue to work then.")
(defun time-stamp-conv-warn (old-format new-format &optional standard-format)
(defun time-stamp--conv-warn (old-format new-format &optional standard-format)
"Display a warning about a soon-to-be-obsolete format.
Suggests replacing OLD-FORMAT with NEW-FORMAT (same effect, but stable)
or (if provided) STANDARD-FORMAT (the effect the user may have expected
@@ -1031,12 +1030,12 @@ This is an internal function called by `time-stamp'."
;; bighours = 1*digit digitpair
;; padding = *" "
(defun time-stamp-formatz-from-parsed-options (flag-minimize
flag-pad-spaces-only
flag-pad-zeros-first
colon-count
field-width
offset-secs)
(defun time-stamp--zformat-from-parsed-options (flag-minimize
flag-pad-spaces-only
flag-pad-zeros-first
colon-count
field-width
offset-secs)
"Format a time offset according to a %z variation.
Format parts FLAG-MINIMIZE, FLAG-PAD-SPACES-ONLY,
@@ -1047,7 +1046,7 @@ This is an internal function used by `time-stamp'."
;; Callers of this function need to have already parsed the %z
;; format string; this function accepts just the parts of the format.
;; `time-stamp-string-preprocess' is the full-fledged parser normally
;; `time-stamp--string-internal' is the full-fledged parser normally
;; used. The unit test (in time-stamp-tests.el) defines the simpler
;; parser `format-time-offset'.

View File

@@ -37,7 +37,7 @@
(time-stamp-active t) ;default, but user may have changed it
(time-stamp-warn-inactive t) ;default, but user may have changed it
(time-stamp-time-zone t)) ;use UTC
(cl-letf (((symbol-function 'time-stamp-conv-warn)
(cl-letf (((symbol-function 'time-stamp--conv-warn)
(lambda (old-format _new &optional _newer)
(ert-fail
(format "Unexpected format warning for '%s'" old-format))))
@@ -85,7 +85,7 @@
"Similar to `should' and also verify that FORM generates a format warning."
(declare (debug t))
`(time-stamp-test--count-function-calls
time-stamp-conv-warn (format "format: %S" ',form)
time-stamp--conv-warn (format "format: %S" ',form)
(should ,form)))
(defmacro time-stamp-should-message (variable &rest body)
@@ -112,20 +112,19 @@
(iter-defun time-stamp-test-pattern-sequential ()
"Iterate through each possibility for a part of `time-stamp-pattern'."
(let ((pattern-value-parts
'(("4/" "10/" "-9/" "0/" "") ;0: line limit
'(("3/" "10/" "-9/" "0/" "") ;0: line limit
("stamp:" "") ;1: start
("%-d" "%_H" "%^a" "%#Z" "%:A" "%019z" "%%" "") ;2: format part 1
(" " "x" ":" "\n" "") ;3: format part 2
("%-d" "%_H" "%^a" "%#Z" "%:A" "%019z" "%%") ;4: format part 3
("end" "")))) ;5: end
("fin" "")))) ;5: end
(dotimes (cur (length pattern-value-parts))
(dotimes (cur-index (length (nth cur pattern-value-parts)))
(cl-flet ((extract-part
(lambda (desired-part)
(let ((part-list (nth desired-part pattern-value-parts)))
(if (= desired-part cur)
(nth cur-index part-list)
(nth 0 part-list))))))
(cl-flet ((extract-part (desired-part)
(let ((part-list (nth desired-part pattern-value-parts)))
(if (= desired-part cur)
(nth cur-index part-list)
(nth 0 part-list)))))
;; Don't repeat the default pattern.
(when (or (= cur 0) (> cur-index 0))
;; The whole format must start with %, so not all
@@ -213,7 +212,7 @@
(cl-destructuring-bind
(line-limit1 start1 whole-format end1) pattern-parts
(cl-letf
(((symbol-function 'time-stamp-once)
(((symbol-function 'time-stamp--once-internal)
(lambda (start search-limit ts-start ts-end
ts-format _format-lines _end-lines)
(incf actual-calls)
@@ -245,7 +244,7 @@
(setq time-stamp-pattern
(concat line-limit1 start1 whole-format end1))
(incf expected-calls)
;; Call time-stamp, which should call time-stamp-once,
;; Call time-stamp, which should call time-stamp--once-internal,
;; triggering the tests above.
(time-stamp)
)))
@@ -875,10 +874,10 @@ This function is called by 99% of the `time-stamp' \"%z\" unit tests."
(defun format-time-offset (format offset-secs)
"Use FORMAT to format the time zone represented by OFFSET-SECS.
FORMAT must be time format \"%z\" or some variation thereof.
This function is a wrapper around `time-stamp-formatz-from-parsed-options'
This function is a wrapper around `time-stamp--zformat-from-parsed-options'
and is called by some low-level `time-stamp' \"%z\" unit tests."
;; This wrapper adds a simple regexp-based parser that handles only
;; %z and variants. In normal use, time-stamp-formatz-from-parsed-options
;; %z and variants. In normal use, time-stamp--zformat-from-parsed-options
;; is called from a parser that handles all time string formats.
(string-match
"\\`\\([^%]*\\)%\\([-_]?\\)\\(0?\\)\\([1-9][0-9]*\\)?\\([EO]?\\)\\(:*\\)\\([^a-zA-Z]+\\)?z\\(.*\\)"
@@ -896,12 +895,12 @@ and is called by some low-level `time-stamp' \"%z\" unit tests."
(concat leading-string
(if garbage
""
(time-stamp-formatz-from-parsed-options flag-minimize
flag-pad-with-spaces
flag-pad-with-zeros
colon-count
field-width
offset-secs))
(time-stamp--zformat-from-parsed-options flag-minimize
flag-pad-with-spaces
flag-pad-with-zeros
colon-count
field-width
offset-secs))
trailing-string)))
(defun fz-make+zone (h &optional m s)
@@ -1067,11 +1066,11 @@ the other expected results for hours greater than 99 with non-zero seconds."
" the macro `define-formatz-tests'.")))
(dolist (form-string form-strings ert-test-list)
(let ((test-name-hhmm
(intern (concat "formatz-" form-string "-hhmm")))
(intern (concat "time-stamp-zformat-" form-string "-hhmm")))
(test-name-seconds
(intern (concat "formatz-" form-string "-seconds")))
(intern (concat "time-stamp-zformat-" form-string "-seconds")))
(test-name-threedigit
(intern (concat "formatz-" form-string "-threedigit"))))
(intern (concat "time-stamp-zformat-" form-string "-threedigit"))))
(nconc
ert-test-list
(list
@@ -1113,9 +1112,10 @@ the other expected results for hours greater than 99 with non-zero seconds."
(defun formatz-find-test-def-function (test-name)
"Search for the `define-formatz-tests' call defining test TEST-NAME.
Return non-nil if the definition is found."
(let* ((z-format (replace-regexp-in-string "\\`formatz-\\([^z]+z\\)-.*\\'"
"\\1"
(symbol-name test-name)))
(let* ((z-format (replace-regexp-in-string
"\\`time-stamp-zformat-\\([^z]+z\\)-.*\\'"
"\\1"
(symbol-name test-name)))
(regexp (concat "^(define-formatz-tests ("
"\\(?:[^)]\\|;.*\n\\)*"
"\"" (regexp-quote z-format) "\"")))
@@ -1153,7 +1153,7 @@ Return non-nil if the definition is found."
;; it here, to verify the implementation we will eventually use.
;; The legacy exception for %z in time-stamp will need to remain
;; through at least 2024 and Emacs 28.
(ert-deftest formatz-%z-spotcheck ()
(ert-deftest time-stamp-zformat-%z-spotcheck ()
"Spot-check internal implementation of `time-stamp' format %z."
(should (equal (format-time-offset "%z" (fz-make+zone 0)) "+0000"))
(should (equal (format-time-offset "%z" (fz-make+zone 0 30)) "+0030"))
@@ -1277,7 +1277,7 @@ Return non-nil if the definition is found."
;;; Test illegal %z formats.
(ert-deftest formatz-illegal-options ()
(ert-deftest time-stamp-zformat-illegal-options ()
"Test that illegal/nonsensical/ambiguous %z formats don't produce output."
;; multiple options
(should (equal "" (formatz "%_-z" 0)))