]> code.delx.au - gnu-emacs/blobdiff - lisp/pcvs-parse.el
(gud-pdb-marker-regexp): Allow : and \ in file name.
[gnu-emacs] / lisp / pcvs-parse.el
index b65f8d2eb6012f8325352f1e4e72247bfb76eb5c..4e008877da6daadde29c2052d2149b57ee7bff15 100644 (file)
@@ -1,11 +1,11 @@
-;;; pcvs-parse.el --- The CVS output parser
+;;; pcvs-parse.el --- the CVS output parser
 
-;; Copyright (C) 1991-2000  Free Software Foundation, Inc.
+;; Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2002
+;;              Free Software Foundation, Inc.
 
 ;; Author: Stefan Monnier <monnier@cs.yale.edu>
 ;; Keywords: pcl-cvs
-;; Version: $Name:  $
-;; Revision: $Id: pcl-cvs-parse.el,v 1.41 2000/03/05 21:32:21 monnier Exp $
+;; Revision: $Id: pcvs-parse.el,v 1.12 2002/06/24 22:49:06 monnier Exp $
 
 ;; This file is part of GNU Emacs.
 
 
 ;;; Commentary:
 
+;;; Bugs:
+
+;; - when merging a modified file, if the merge says that the file already
+;;   contained in the changes, it marks the file as `up-to-date' although
+;;   it might still contain further changes.
+;;   Example: merging a zero-change commit.
 
 ;;; Code:
 
@@ -77,11 +83,11 @@ PARSE-SPEC is a function of no argument advancing the point and returning
   either a fileinfo or t (if the matched text should be ignored) or
   nil if it didn't match anything.
 DONT-CHANGE-DISC just indicates whether the command was changing the disc
-  or not (useful to tell the difference btween `cvs-examine' and `cvs-update'
-  ouytput.
+  or not (useful to tell the difference between `cvs-examine' and `cvs-update'
+  output.
 The path names should be interpreted as relative to SUBDIR (defaults
   to the `default-directory').
-Return a list of collected entries, or t if an error occured."
+Return a list of collected entries, or t if an error occurred."
   (goto-char (point-min))
   (let ((fileinfos ())
        (cvs-current-dir "")
@@ -154,7 +160,8 @@ Match RE and if successful, execute MATCHES."
      (and
       (cvs-match ".*$")
       (cvs-create-fileinfo 'MESSAGE cvs-current-dir " "
-                          (concat " Parser Error: '" (cvs-parse-msg) "'")
+                          ;; (concat " Unknown msg: '"
+                          (cvs-parse-msg) ;; "'")
                           :subtype 'ERROR)))))
 
 \f
@@ -185,7 +192,6 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
       (apply 'cvs-create-fileinfo type
             (concat cvs-current-subdir (or dir cvs-current-dir))
             file (cvs-parse-msg) :subtype subtype keys))))
-
 \f
 ;;;; CVS Process Parser Tables:
 ;;;;
@@ -217,19 +223,28 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
       ;; P: The file was patched from the repository.
       ;; ?: Unknown file.
       (let ((code (aref c 0)))
-       (cvs-parsed-fileinfo (case code
-                              (?M 'MODIFIED)
-                              (?A 'ADDED)
-                              (?R 'REMOVED)
-                              (?? 'UNKNOWN)
-                              (?C 'CONFLICT) ;(if dont-change-disc 'NEED-MERGE
-                              (?J 'NEED-MERGE) ;not supported by standard CVS
-                              ((?U ?P)
-                               (if dont-change-disc
-                                   'NEED-UPDATE
-                                 (cons 'UP-TO-DATE
-                                       (if (eq code ?U) 'UPDATED 'PATCHED)))))
-                            path 'trust)))
+       (cvs-parsed-fileinfo
+        (case code
+          (?M 'MODIFIED)
+          (?A 'ADDED)
+          (?R 'REMOVED)
+          (?? 'UNKNOWN)
+          (?C
+           (if (not dont-change-disc) 'CONFLICT
+             ;; This is ambiguous.  We should look for conflict markers in the
+             ;; file to decide between CONFLICT and NEED-MERGE.  With CVS-1.10
+             ;; servers, this should not be necessary, because they return
+             ;; a complete merge output.
+             (with-temp-buffer
+               (insert-file-contents path)
+               (goto-char (point-min))
+               (if (re-search-forward "^<<<<<<< " nil t)
+                   'CONFLICT 'NEED-MERGE))))
+          (?J 'NEED-MERGE)             ;not supported by standard CVS
+          ((?U ?P)
+           (if dont-change-disc 'NEED-UPDATE
+             (cons 'UP-TO-DATE (if (eq code ?U) 'UPDATED 'PATCHED)))))
+        path 'trust)))
 
      (and
       (cvs-match "pcl-cvs: descending directory \\(.*\\)$" (dir 1))
@@ -237,7 +252,8 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
 
      ;; A special cvs message
      (and
-      (cvs-match "cvs[.ex]* [a-z]+: ")
+      (let ((case-fold-search t))
+       (cvs-match "cvs[.a-z]* [a-z]+: "))
       (cvs-or
 
        ;; CVS is descending a subdirectory
@@ -250,7 +266,8 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
        ;; [-n update] A new (or pruned) directory appeared but isn't traversed
        (and
        (cvs-match "New directory `\\(.*\\)' -- ignored$" (dir 1))
-       (cvs-parsed-fileinfo 'MESSAGE " " (file-name-as-directory dir)))
+       ;; (cvs-parsed-fileinfo 'MESSAGE " " (file-name-as-directory dir))
+       (cvs-parsed-fileinfo '(NEED-UPDATE . NEW-DIR) dir))
 
        ;; File removed, since it is removed (by third party) in repository.
        (and
@@ -270,6 +287,9 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
        (and
        (cvs-match "\\(.*\\), version \\(.*\\), resurrected$"
                   (path 1) (base-rev 2))
+       ;; FIXME: resurrection only brings back the original version,
+       ;; not the latest on the branch, so `up-to-date' is not always
+       ;; what we want.
        (cvs-parsed-fileinfo '(UP-TO-DATE . RESURRECTED) path nil
                             :base-rev base-rev))
 
@@ -318,6 +338,10 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
        (and (cvs-match "use `.+ add' to create an entry for \\(.*\\)$" (path 1))
            (cvs-parsed-fileinfo 'UNKNOWN path))
 
+       ;; [commit]
+       (and (cvs-match "Up-to-date check failed for `\\(.+\\)'$" (file 1))
+           (cvs-parsed-fileinfo 'NEED-MERGE file))
+
        ;; We use cvs-execute-multi-dir but cvs can't handle it
        ;; Probably because the cvs-client can but the cvs-server can't
        (and (cvs-match ".* files with '?/'? in their name.*$")
@@ -335,12 +359,15 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
        ;; just a note
        (cvs-match "use '.+ commit' to \\sw+ th\\sw+ files? permanently$")
        ;; [add,status] followed by a more complete status description anyway
-       (cvs-match "nothing known about .*$")
+       (and (cvs-match "nothing known about \\(.*\\)$" (path 1))
+           (cvs-parsed-fileinfo 'DEAD path 'trust))
        ;; [update] problem with patch
        (cvs-match "checksum failure after patch to .*; will refetch$")
        (cvs-match "refetching unpatchable files$")
        ;; [commit]
        (cvs-match "Rebuilding administrative file database$")
+       ;; ???
+       (cvs-match "--> Using per-directory sticky tag `.*'")
      
        ;; CVS is running a *info program.
        (and
@@ -397,6 +424,8 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
                           "\\) already contains the differences between .*$")
                   (path 1) (type '(UP-TO-DATE . MERGED)))
        t)
+       ;; FIXME: PATH might not be set yet.  Sometimes the only path
+       ;; information is in `RCS file: ...' (yuck!!).
        (cvs-parsed-fileinfo (if dont-change-disc 'NEED-MERGE
                              (or type '(MODIFIED . MERGED))) path nil
                            :merge (cons base-rev head-rev))))))
@@ -413,11 +442,13 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
                 (type (if nofile 'MISSING 'NEED-UPDATE)))
       (cvs-match "Up-to-date$"
                 (type (if nofile '(UP-TO-DATE . REMOVED) 'UP-TO-DATE)))
+      (cvs-match "File had conflicts on merge$" (type 'MODIFIED))
       (cvs-match ".*[Cc]onflict.*$"    (type 'CONFLICT))
       (cvs-match "Locally Added$"              (type 'ADDED))
       (cvs-match "Locally Removed$"    (type 'REMOVED))
       (cvs-match "Locally Modified$"   (type 'MODIFIED))
       (cvs-match "Needs Merge$"                (type 'NEED-MERGE))
+      (cvs-match "Entry Invalid"       (type '(NEED-MERGE . REMOVED)))
       (cvs-match "Unknown$"            (type 'UNKNOWN)))
      (cvs-match "$")
      (cvs-or
@@ -462,12 +493,15 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
        (cvs-match "new revision: \\([0-9.]*\\); previous revision: .*$"
                  (subtype 'COMMITTED) (base-rev 1)))
       (cvs-match "done$")
-      ;; it's important here not to rely on the default directory management
-      ;; because `cvs commit' might begin by a series of Examining messages
-      ;; so the processing of the actual checkin messages might begin with
-      ;; a `current-dir' set to something different from ""
-      (cvs-parsed-fileinfo (cons 'UP-TO-DATE subtype) path 'trust
-                          :base-rev base-rev))
+      (progn
+       ;; Try to remove the temp files used by VC.
+       (vc-delete-automatic-version-backups (expand-file-name path))
+       ;; it's important here not to rely on the default directory management
+       ;; because `cvs commit' might begin by a series of Examining messages
+       ;; so the processing of the actual checkin messages might begin with
+       ;; a `current-dir' set to something different from ""
+       (cvs-parsed-fileinfo (cons 'UP-TO-DATE subtype) path 'trust
+                            :base-rev base-rev)))
      
      ;; useless message added before the actual addition: ignored
      (cvs-match "RCS file: .*\ndone$"))))
@@ -475,4 +509,4 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'."
 
 (provide 'pcvs-parse)
 
-;;; pcl-cvs-parse.el ends here
+;;; pcvs-parse.el ends here