emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 5b314731894: Merge remote-tracking branch 'origin/master


From: Po Lu
Subject: feature/android 5b314731894: Merge remote-tracking branch 'origin/master' into feature/android
Date: Tue, 18 Apr 2023 21:15:16 -0400 (EDT)

branch: feature/android
commit 5b314731894f09bb71fd02c76add45263e2d4f77
Merge: 55388c288a0 9a2c723f1bc
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Merge remote-tracking branch 'origin/master' into feature/android
---
 lisp/gnus/gnus-sum.el          |   4 +-
 lisp/progmodes/eglot.el        |  19 ++--
 lisp/progmodes/flymake.el      |  10 +-
 lisp/progmodes/verilog-mode.el |  54 ++++++-----
 lisp/vc/vc-cvs.el              | 215 ++++++++++++++++++++++++++++-------------
 lisp/vc/vc.el                  |   3 +-
 test/lisp/vc/vc-cvs-tests.el   | 107 ++++++++++++++++++++
 7 files changed, 304 insertions(+), 108 deletions(-)

diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 35e867a3508..4effaa981ec 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -9081,8 +9081,8 @@ is non-numeric or nil fetch the number specified by the
              (cl-merge 'list gnus-newsgroup-headers new-headers
                        'gnus-article-sort-by-number)))
       (setq gnus-newsgroup-articles
-            (gnus-sorted-nunion gnus-newsgroup-articles article-ids))
-      (gnus-summary-limit-include-thread id 
gnus-refer-thread-limit-to-thread)))
+            (gnus-sorted-nunion gnus-newsgroup-articles article-ids)))
+    (gnus-summary-limit-include-thread id gnus-refer-thread-limit-to-thread))
   (gnus-summary-show-thread))
 
 (defun gnus-summary-open-group-with-article (message-id)
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 7ad33fa3786..fe0c986d746 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -1935,10 +1935,9 @@ Use `eglot-managed-p' to determine if current buffer is 
managed.")
   "Return logical Eglot server for current buffer, nil if none."
   (setq eglot--cached-server
         (or eglot--cached-server
-            (cl-find major-mode
-                     (gethash (eglot--current-project) 
eglot--servers-by-project)
-                     :key #'eglot--major-modes
-                     :test #'memq)
+            (cl-find-if #'eglot--languageId
+                        (gethash (eglot--current-project)
+                                 eglot--servers-by-project))
             (and eglot-extend-to-xref
                  buffer-file-name
                  (gethash (expand-file-name buffer-file-name)
@@ -2360,12 +2359,20 @@ THINGS are either registrations or unregisterations 
(sic)."
   (append (eglot--TextDocumentIdentifier)
           `(:version ,eglot--versioned-identifier)))
 
+(cl-defun eglot--languageId (&optional (server 
(eglot--current-server-or-lose)))
+  "Compute LSP \\='languageId\\=' string for current buffer.
+Doubles as an predicate telling if SERVER can manage current
+buffer."
+  (cl-loop for (mode . languageid) in
+           (eglot--languages server)
+           when (provided-mode-derived-p major-mode mode)
+           return languageid))
+
 (defun eglot--TextDocumentItem ()
   "Compute TextDocumentItem object for current buffer."
   (append
    (eglot--VersionedTextDocumentIdentifier)
-   (list :languageId
-         (alist-get major-mode (eglot--languages 
(eglot--current-server-or-lose)))
+   (list :languageId (eglot--languageId)
          :text
          (eglot--widening
           (buffer-substring-no-properties (point-min) (point-max))))))
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index b744a717c5c..f03b9ab56a0 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -447,25 +447,25 @@ verify FILTER, a function, and sort them by COMPARE 
(using KEY)."
   :package-version '(Flymake . "1.3.4"))
 
 (defface flymake-end-of-line-diagnostics-face
-  '((t :height 0.7 :box (:line-width 1)))
+  '((t :height 0.85 :box (:line-width -1)))
   "Face used for end-of-line diagnostics.
 See variable `flymake-show-diagnostics-at-end-of-line'."
-  :package-version '("Flymake" . "1.3.5"))
+  :package-version '(Flymake . "1.3.5"))
 
 (defface flymake-error-echo-at-eol
   '((t :inherit (flymake-end-of-line-diagnostics-face compilation-error)))
   "Face like `flymake-error-echo', but for end-of-line overlays."
-  :package-version '("Flymake" . "1.3.5"))
+  :package-version '(Flymake . "1.3.5"))
 
 (defface flymake-warning-echo-at-eol
   '((t :inherit (flymake-end-of-line-diagnostics-face compilation-warning)))
   "Face like `flymake-warning-echo', but for end-of-line overlays."
-  :package-version '("Flymake" . "1.3.5"))
+  :package-version '(Flymake . "1.3.5"))
 
 (defface flymake-note-echo-at-eol
   '((t :inherit (flymake-end-of-line-diagnostics-face flymake-note)))
   "Face like `flymake-note-echo', but for end-of-line overlays."
-  :package-version '("Flymake" . "1.3.5"))
+  :package-version '(Flymake . "1.3.5"))
 
 (defcustom flymake-show-diagnostics-at-end-of-line nil
   "If non-nil, add diagnostic summary messages at end-of-line."
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index ac6fd382a46..9199119b602 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -356,7 +356,9 @@ wherever possible, since it is slow."
 (eval-and-compile
   ;; Both xemacs and emacs
   (condition-case nil
-      (require 'diff)  ; diff-command and diff-switches
+      ;; `diff-command' and `diff-switches',
+      ;; although XEmacs lacks the former.
+      (require 'diff)
     (error nil))
   (condition-case nil
       (require 'compile)  ; compilation-error-regexp-alist-alist
@@ -11883,31 +11885,33 @@ If optional REGEXP, ignore differences matching it."
 This requires the external program `diff-command' to be in your `exec-path',
 and uses `diff-switches' in which you may want to have \"-u\" flag.
 Ignores WHITESPACE if t, and writes output to stdout if SHOW."
-  ;; Similar to `diff-buffer-with-file' but works on XEmacs, and doesn't
-  ;; call `diff' as `diff' has different calling semantics on different
-  ;; versions of Emacs.
+  ;; Similar to `diff-buffer-with-file' but works on Emacs 21, and
+  ;; doesn't call `diff' as `diff' has different calling semantics on
+  ;; different versions of Emacs.
   (if (not (file-exists-p f1))
-      (message "Buffer `%s' has no associated file on disk" (buffer-name b2))
-    (with-temp-buffer "*Verilog-Diff*"
-                      (let ((outbuf (current-buffer))
-                            (f2 (make-temp-file "vm-diff-auto-")))
-                        (unwind-protect
-                            (progn
-                              (with-current-buffer b2
-                                (save-restriction
-                                  (widen)
-                                  (write-region (point-min) (point-max) f2 nil 
'nomessage)))
-                              (call-process diff-command nil outbuf t
-                                            diff-switches  ; User may want -u 
in diff-switches
-                                            (if whitespace "-b" "")
-                                            f1 f2)
-                              ;; Print out results.  Alternatively we could 
have call-processed
-                              ;; ourself, but this way we can reuse diff 
switches
-                              (when show
-                                (with-current-buffer outbuf (message "%s" 
(buffer-string))))))
-                        (sit-for 0)
-                        (when (file-exists-p f2)
-                          (delete-file f2))))))
+      (message "Buffer `%s' has no associated file on disk" b2)
+    (let ((outbuf (get-buffer "*Verilog-Diff*"))
+          (f2 (make-temp-file "vm-diff-auto-")))
+      (unwind-protect
+          ;; User may want -u in `diff-switches'.
+          (let ((args `(,@(if (listp diff-switches)
+                              diff-switches
+                            (list diff-switches))
+                        ,@(and whitespace '("-b"))
+                        ,f1 ,f2)))
+            (with-current-buffer b2
+              (save-restriction
+                (widen)
+                (write-region (point-min) (point-max) f2 nil 'nomessage)))
+            (apply #'call-process diff-command nil outbuf t args)
+            ;; Print out results.  Alternatively we could have call-processed
+            ;; ourself, but this way we can reuse diff switches.
+            (when show
+              (with-current-buffer outbuf (message "%s" (buffer-string)))))
+        (sit-for 0)
+        (condition-case nil
+            (delete-file f2)
+          (error nil))))))
 
 (defun verilog-diff-report (b1 b2 diffpt)
   "Report differences detected with `verilog-diff-auto'.
diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el
index 6e0246ea762..c6056c1e5bd 100644
--- a/lisp/vc/vc-cvs.el
+++ b/lisp/vc/vc-cvs.el
@@ -26,6 +26,7 @@
 
 (require 'vc-rcs)
 (eval-when-compile (require 'vc))
+(eval-when-compile (require 'cl-lib))
 (require 'log-view)
 
 (declare-function vc-checkout "vc" (file &optional rev))
@@ -813,7 +814,10 @@ individually should stay local."
                             'yes 'no))))))))))))
 
 (defun vc-cvs-repository-hostname (dirname)
-  "Hostname of the CVS server associated to workarea DIRNAME."
+  "Hostname of the CVS server associated to workarea DIRNAME.
+
+Returns nil if there is not hostname or the hostname could not be
+determined because the CVS/Root specification is invalid."
   (let ((rootname (expand-file-name "CVS/Root" dirname)))
     (when (file-readable-p rootname)
       (with-temp-buffer
@@ -822,73 +826,143 @@ individually should stay local."
                   default-file-name-coding-system)))
          (vc-insert-file rootname))
        (goto-char (point-min))
-       (nth 2 (vc-cvs-parse-root
-               (buffer-substring (point)
-                                 (line-end-position))))))))
-
-(defun vc-cvs-parse-uhp (path)
-  "Parse user@host/path into (user@host /path)."
-  (if (string-match "\\([^/]+\\)\\(/.*\\)" path)
-      (list (match-string 1 path) (match-string 2 path))
-      (list nil path)))
-
-(defun vc-cvs-parse-root (root)
-  "Split CVS ROOT specification string into a list of fields.
-A CVS root specification of the form
-  [:METHOD:][[USER@]HOSTNAME]:?/path/to/repository
+        (let ((hostname
+              (nth 2 (vc-cvs-parse-root
+                      (buffer-substring (point)
+                                        (line-end-position))))))
+          (unless (string= hostname "")
+            hostname))))))
+
+(cl-defun vc-cvs-parse-root (root)
+  "Split CVS Root specification string into a list of fields.
+
+A CVS Root specification of the form
+  [:METHOD:][[[USER][:PASSWORD]@]HOSTNAME][:[PORT]]/pathname/to/repository
 is converted to a normalized record with the following structure:
-  \(METHOD USER HOSTNAME CVS-ROOT).
+  \(METHOD USER HOSTNAME PATHNAME).
+
 The default METHOD for a CVS root of the form
-  /path/to/repository
-is `local'.
+  /pathname/to/repository
+is \"local\".
 The default METHOD for a CVS root of the form
-  [USER@]HOSTNAME:/path/to/repository
-is `ext'.
-For an empty string, nil is returned (invalid CVS root)."
-  ;; Split CVS root into colon separated fields (0-4).
-  ;; The `x:' makes sure, that leading colons are not lost;
-  ;; `HOST:/PATH' is then different from `:METHOD:/PATH'.
-  (let* ((root-list (cdr (split-string (concat "x:" root) ":")))
-         (len (length root-list))
-         ;; All syntactic varieties will get a proper METHOD.
-         (root-list
-          (cond
-           ((= len 0)
-            ;; Invalid CVS root
-            nil)
-           ((= len 1)
-            (let ((uhp (vc-cvs-parse-uhp (car root-list))))
-              (cons (if (car uhp) "ext" "local") uhp)))
-           ((= len 2)
-            ;; [USER@]HOST:PATH => method `ext'
-            (and (not (equal (car root-list) ""))
-                 (cons "ext" root-list)))
-           ((= len 3)
-            ;; :METHOD:PATH or :METHOD:USER@HOSTNAME/PATH
-            (cons (cadr root-list)
-                  (vc-cvs-parse-uhp (nth 2 root-list))))
-           (t
-            ;; :METHOD:[USER@]HOST:PATH
-            (cdr root-list)))))
-    (if root-list
-        (let ((method (car root-list))
-              (uhost (or (cadr root-list) ""))
-              (root (nth 2 root-list))
-              user host)
-          ;; Split USER@HOST
-          (if (string-match "\\(.*\\)@\\(.*\\)" uhost)
-              (setq user (match-string 1 uhost)
-                    host (match-string 2 uhost))
-            (setq host uhost))
-          ;; Remove empty HOST
-          (and (equal host "")
-               (setq host nil))
-          ;; Fix windows style CVS root `:local:C:\\project\\cvs\\some\\dir'
-          (and host
-               (equal method "local")
-               (setq root (concat host ":" root) host nil))
-          ;; Normalize CVS root record
-          (list method user host root)))))
+  [USER@]HOSTNAME:/pathname/to/repository
+is \"ext\".
+
+If METHOD is explicitly \"local\" or \"fork\", then the pathname
+starts immediately after the method block. This must be used on
+Windows platforms when pathnames start with a drive letter.
+
+Note that, except for METHOD, which is defaulted if not present,
+other optional fields are returned as nil if not syntactically
+present, or as the empty string if delimited but empty.
+
+Returns nil in case of an unparsable CVS root (including the
+empty string) and issues a warning. This function doesn't check
+that an explicit method is valid, or that some fields are empty
+or nil but should not for a given method."
+  (let (method user password hostname port pathname
+               ;; IDX set by `next-delim' as a side-effect
+               idx)
+    (cl-labels
+        ((invalid (reason &rest args)
+           (apply #'lwarn '(vc-cvs) :warning
+                  (concat "vc-cvs-parse-root: Can't parse '%s': " reason)
+                  root args)
+           (cl-return-from vc-cvs-parse-root))
+         (no-pathname ()
+           (invalid "No pathname"))
+         (next-delim (start)
+           ;; Search for a :, @ or /. If none is found, there can be
+           ;; no path at the end, which is an error.
+           (setq idx (string-match-p "[:@/]" root start))
+           (if idx (aref root idx) (no-pathname)))
+         (grab-user (start end)
+           (setq user (substring root start end)))
+         (at-hostname-block (start)
+           (let ((cand (next-delim start)))
+             (cl-ecase cand
+               (?:
+                ;; Could be : before PORT and PATHNAME, or before
+                ;; PASSWORD. We search for a @ to disambiguate.
+                (let ((colon-idx idx)
+                      (cand (next-delim (1+ idx))))
+                  (cl-ecase cand
+                    (?:
+                     (invalid
+                      (eval-when-compile
+                        (concat "Hostname block: Superfluous : at %s "
+                                "or missing @ before"))
+                      idx))
+                    (?@
+                     ;; USER:PASSWORD case
+                     (grab-user start colon-idx)
+                     (delimited-password (1+ colon-idx) idx))
+                    (?/
+                     ;; HOSTNAME[:[PORT]] case
+                     (grab-hostname start colon-idx)
+                     (delimited-port (1+ colon-idx) idx)))))
+               (?@
+                (grab-user start idx)
+                (at-hostname (1+ idx)))
+               (?/
+                (if (/= idx start)
+                    (grab-hostname start idx))
+                (at-pathname idx)))))
+         (delimited-password (start end)
+           (setq password (substring root start end))
+           (at-hostname (1+ end)))
+         (grab-hostname (start end)
+           (setq hostname (substring root start end)))
+         (at-hostname (start)
+           (let ((cand (next-delim start)))
+             (cl-ecase cand
+               (?:
+                (grab-hostname start idx)
+                (at-port (1+ idx)))
+               (?@
+                (invalid "Hostname: Unexpected @ after index %s" start))
+               (?/
+                (grab-hostname start idx)
+                (at-pathname idx)))))
+         (delimited-port (start end)
+           (setq port (substring root start end))
+           (at-pathname end))
+         (at-port (start)
+           (let ((end (string-match-p "/" root start)))
+             (if end (delimited-port start end) (no-pathname))))
+         (at-pathname (start)
+           (setq pathname (substring root start))))
+      (when (string= root "")
+        (invalid "Empty string"))
+      ;; Check for a starting ":"
+      (if (= (aref root 0) ?:)
+          ;; 3 possible cases:
+          ;; - :METHOD: at start. METHOD doesn't have any @.
+          ;; - :PASSWORD@ at start. Must be followed by HOSTNAME.
+          ;; - :[PORT] at start. Must be followed immediately by a "/".
+          ;; So, find the next character equal to ":", "@" or "/".
+          (let ((cand (next-delim 1)))
+            (cl-ecase cand
+              (?:
+               ;; :METHOD: case
+               (setq method (substring root 1 idx))
+               ;; Continue
+               (if (member method '("local" "fork"))
+                   (at-pathname (1+ idx))
+                 (at-hostname-block (1+ idx))))
+              (?@
+               ;; :PASSWORD@HOSTNAME case
+               (delimited-password 1 idx))
+              (?/
+               ;; :[PORT] case.
+               (at-port 1 idx))))
+        ;; No starting ":", there can't be any METHOD.
+        (at-hostname-block 0)))
+    (unless method
+      ;; Default the method if not specified
+      (setq method
+            (if (or user password hostname port) "ext" "local")))
+    (list method user hostname pathname)))
 
 ;; XXX: This does not work correctly for subdirectories.  "cvs status"
 ;; information is context sensitive, it contains lines like:
@@ -955,13 +1029,16 @@ state."
                       (cdr (assoc (char-after) translation)))
                 result)
         (cond
-         ((looking-at "cvs update: warning: \\(.*\\) was lost")
+         ((looking-at "cvs update: warning: .* was lost")
           ;; Format is:
           ;; cvs update: warning: FILENAME was lost
           ;; U FILENAME
-          (push (list (match-string 1) 'missing) result)
-          ;; Skip the "U" line
-          (forward-line 1))
+          ;; with FILENAME in the first line possibly enclosed in
+          ;; quotes (since CVS 1.12.3). To avoid problems, use the U
+          ;; line where name is never quoted.
+          (forward-line 1)
+          (when (looking-at "^U \\(.*\\)$")
+            (push (list (match-string 1) 'missing) result)))
          ((looking-at "cvs update: New directory `\\(.*\\)' -- ignored")
           (push (list (match-string 1) 'unregistered) result))))
       (forward-line 1))
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 32b0d5d7556..91d3f6f70d3 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -3604,7 +3604,8 @@ to provide the `find-revision' operation instead."
           (file-buffer (or (get-file-buffer file) (current-buffer))))
       (message "Checking out %s..." file)
       (let ((failed t)
-            (backup-name (car (find-backup-file-name file))))
+            (backup-name (when (file-exists-p file)
+                           (car (find-backup-file-name file)))))
         (when backup-name
           (copy-file file backup-name 'ok-if-already-exists 'keep-date)
           (unless (file-writable-p file)
diff --git a/test/lisp/vc/vc-cvs-tests.el b/test/lisp/vc/vc-cvs-tests.el
new file mode 100644
index 00000000000..99ac9c8eb96
--- /dev/null
+++ b/test/lisp/vc/vc-cvs-tests.el
@@ -0,0 +1,107 @@
+;;; vc-cvs-tests.el --- tests for vc/vc-cvs.el  -*- lexical-binding:t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; Author: Olivier Certner <olce.emacs@certner.fr>
+;; Maintainer: emacs-devel@gnu.org
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'vc-cvs)
+
+(ert-deftest vc-cvs-test-parse-root--local-no-method ()
+  (vc-cvs-test--check-parse-root
+   "/home/joe/repo"
+   '("local" nil nil "/home/joe/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--local-windows-drive-letter ()
+  (vc-cvs-test--check-parse-root
+   ":local:c:/users/joe/repo"
+   '("local" nil nil "c:/users/joe/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--ext-no-method-host-no-port-colon ()
+  (vc-cvs-test--check-parse-root
+   "host/home/serv/repo"
+   '("ext" nil "host" "/home/serv/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--pserver-host-no-port-colon ()
+  (vc-cvs-test--check-parse-root
+   ":pserver:host/home/serv/repo"
+   '("pserver" nil "host" "/home/serv/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--pserver-host-port-colon ()
+  (vc-cvs-test--check-parse-root
+   ":pserver:host:/home/serv/repo"
+   '("pserver" nil "host" "/home/serv/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--ext-no-method-user-host-no-port-colon ()
+  (vc-cvs-test--check-parse-root
+   "usr@host/home/serv/repo"
+   '("ext" "usr" "host" "/home/serv/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--ext-no-method-user-host-port-colon ()
+  (vc-cvs-test--check-parse-root
+   "usr@host:/home/serv/repo"
+   '("ext" "usr" "host" "/home/serv/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--pserver-user-password-host-no-port-colon 
()
+  (vc-cvs-test--check-parse-root
+   ":pserver:usr:passwd@host/home/serv/repo"
+   '("pserver" "usr" "host" "/home/serv/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--pserver-user-password-host-port-colon ()
+  (vc-cvs-test--check-parse-root
+   ":pserver:usr:passwd@host:/home/serv/repo"
+   '("pserver" "usr" "host" "/home/serv/repo")))
+
+(ert-deftest vc-cvs-test-parse-root--pserver-user-password-host-port ()
+  (vc-cvs-test--check-parse-root
+   ":pserver:usr:passwd@host:28/home/serv/repo"
+   '("pserver" "usr" "host" "/home/serv/repo")))
+
+;; Next 3 tests are just to err on the side of caution. It doesn't
+;; seem that CVS 1.12 can ever produce such lines.
+
+(ert-deftest
+    vc-cvs-test-parse-root--ext-no-method-user-password-host-no-port-colon
+    ()
+  (vc-cvs-test--check-parse-root
+   "usr:passwd@host/home/serv/repo"
+   '("ext" "usr" "host" "/home/serv/repo")))
+
+(ert-deftest
+    vc-cvs-test-parse-root--ext-no-method-user-password-host-port-colon
+    ()
+  (vc-cvs-test--check-parse-root
+   "usr:passwd@host:/home/serv/repo"
+   '("ext" "usr" "host" "/home/serv/repo")))
+
+(ert-deftest
+    vc-cvs-test-parse-root--ext-no-method-user-password-host-port
+    ()
+  (vc-cvs-test--check-parse-root
+   "usr:passwd@host:28/home/serv/repo"
+   '("ext" "usr" "host" "/home/serv/repo")))
+
+
+(defun vc-cvs-test--check-parse-root (input expected-output)
+  (should (equal (vc-cvs-parse-root input) expected-output)))
+
+;;; vc-cvs-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]