/[cmucl]/src/code/fd-stream.lisp
ViewVC logotype

Diff of /src/code/fd-stream.lisp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.65 by toy, Thu Jun 5 14:34:22 2003 UTC revision 1.66 by toy, Fri Jun 6 16:23:45 2003 UTC
# Line 31  Line 31 
31    
32  (in-package "LISP")  (in-package "LISP")
33    
34  (export '(file-stream file-string-length stream-external-format))  (export '(file-stream file-string-length))
35    
36    
37  ;;;; Buffer manipulation routines.  ;;;; Buffer manipulation routines.
# Line 925  Line 925 
925                          input-type                          input-type
926                          output-type))))))                          output-type))))))
927    
928    ;;; REVERT-FILE -- internal
929    ;;;
930    ;;;   Revert a file, if possible; otherwise just delete it.  Used during
931    ;;; CLOSE when the abort flag is set.
932    ;;;
933    (defun revert-file (filename original)
934      (declare (type simple-base-string filename)
935               (type (or simple-base-string null) original))
936      (if original
937          (multiple-value-bind (okay err) (unix:unix-rename original filename)
938            (unless okay
939              (cerror "Go on as if nothing bad happened."
940                      "Could not restore ~S to it's original contents: ~A"
941                      filename (unix:get-unix-error-msg err))))
942          (multiple-value-bind (okay err) (unix:unix-unlink filename)
943            (unless okay
944              (cerror "Go on as if nothing bad happened."
945                      "Could not remove ~S: ~A"
946                      filename (unix:get-unix-error-msg err))))))
947    
948    ;;; DELETE-ORIGINAL -- internal
949    ;;;
950    ;;;   Delete a backup file.  Used during CLOSE.
951    ;;;
952    (defun delete-original (filename original)
953      (declare (type simple-base-string filename)
954               (type (or simple-base-string null) original))
955      (when original
956        (multiple-value-bind (okay err) (unix:unix-unlink original)
957          (unless okay
958            (cerror "Go on as if nothing bad happened."
959                    "Could not delete ~S during close of ~S: ~A"
960                    original stream (unix:get-unix-error-msg err))))))
961    
962  ;;; FD-STREAM-MISC-ROUTINE -- input  ;;; FD-STREAM-MISC-ROUTINE -- input
963  ;;;  ;;;
964  ;;;   Handle the various misc operations on fd-stream.  ;;;   Handle the various misc operations on fd-stream.
# Line 953  Line 987 
987              (when (fd-stream-handler stream)              (when (fd-stream-handler stream)
988                    (system:remove-fd-handler (fd-stream-handler stream))                    (system:remove-fd-handler (fd-stream-handler stream))
989                    (setf (fd-stream-handler stream) nil))                    (setf (fd-stream-handler stream) nil))
990              (when (and (fd-stream-file stream)              (when (and (fd-stream-file stream) (fd-stream-obuf-sap stream))
991                         (fd-stream-obuf-sap stream))                (revert-file (fd-stream-file stream)
992                ;; Can't do anything unless we know what file were dealing with,                             (fd-stream-original stream))))
               ;; and we don't want to do anything strange unless we were  
               ;; writing to the file.  
               (if (fd-stream-original stream)  
                   ;; Have an handle on the original, just revert.  
                   (multiple-value-bind  
                       (okay err)  
                       (unix:unix-rename (fd-stream-original stream)  
                                         (fd-stream-file stream))  
                     (unless okay  
                       (cerror "Go on as if nothing bad happened."  
                         "Could not restore ~S to it's original contents: ~A"  
                               (fd-stream-file stream)  
                               (unix:get-unix-error-msg err))))  
                   ;; Can't restore the orignal, so nuke that puppy.  
                   (multiple-value-bind  
                       (okay err)  
                       (unix:unix-unlink (fd-stream-file stream))  
                     (unless okay  
                       (cerror "Go on as if nothing bad happened."  
                               "Could not remove ~S: ~A"  
                               (fd-stream-file stream)  
                               (unix:get-unix-error-msg err)))))))  
993             (t             (t
994              (fd-stream-misc-routine stream :finish-output)              (fd-stream-misc-routine stream :finish-output)
995              (when (and (fd-stream-original stream)              (when (fd-stream-delete-original stream)
996                         (fd-stream-delete-original stream))                (delete-original (fd-stream-file stream)
997                (multiple-value-bind                                 (fd-stream-original stream)))))
                   (okay err)  
                   (unix:unix-unlink (fd-stream-original stream))  
                 (unless okay  
                   (cerror "Go on as if nothing bad happened."  
                           "Could not delete ~S during close of ~S: ~A"  
                           (fd-stream-original stream)  
                           stream  
                           (unix:get-unix-error-msg err)))))))  
998       (when (fboundp 'cancel-finalization)       (when (fboundp 'cancel-finalization)
999         (cancel-finalization stream))         (cancel-finalization stream))
1000       (unix:unix-close (fd-stream-fd stream))       (unix:unix-close (fd-stream-fd stream))
# Line 1199  Line 1203 
1203      stream))      stream))
1204    
1205    
1206  ;;; PICK-PACKUP-NAME -- internal  ;;; PICK-BACKUP-NAME -- internal
1207  ;;;  ;;;
1208  ;;; Pick a name to use for the backup file.  ;;; Pick a name to use for the backup file.
1209  ;;;  ;;;
# Line 1288  Line 1292 
1292                     (unix:get-unix-error-msg err))                     (unix:get-unix-error-msg err))
1293             nil))))             nil))))
1294    
1295  ;;; RETURN-STREAM -- internal  ;;; FD-OPEN  --  Internal
1296  ;;;  ;;;
1297  ;;; (this is just to save having to reindent the code in OPEN...move it there)  ;;;    Open a file.
1298  ;;;  ;;;
1299  (defmacro return-stream (class &body body)  (defun fd-open (pathname direction if-exists if-exists-given
1300    (let ((stream (gensym)))                            if-does-not-exist if-does-not-exist-given)
1301      `(let ((,stream (progn ,@body)))    (declare (type pathname pathname)
1302         (return (if ,class             (type (member :input :output :io :probe) direction)
1303                    (make-instance ,class :lisp-stream ,stream)             (type (member :error :new-version :rename :rename-and-delete
1304                    ,stream)))))                           :overwrite :append :supersede nil) if-exists)
1305               (type (member :error :create nil) if-does-not-exist))
1306      (multiple-value-bind (input output mask)
1307          (ecase direction
1308            (:input (values t nil unix:o_rdonly))
1309            (:output (values nil t unix:o_wronly))
1310            (:io (values t t unix:o_rdwr))
1311            (:probe (values t nil unix:o_rdonly)))
1312        (declare (type index mask))
1313        (let ((name (cond ((unix-namestring pathname input))
1314                          ((and input (eq if-does-not-exist :create))
1315                           (unix-namestring pathname nil)))))
1316          ;; Process if-exists argument if we are doing any output.
1317          (cond (output
1318                 (unless if-exists-given
1319                   (setf if-exists
1320                         (if (eq (pathname-version pathname) :newest)
1321                             :new-version
1322                             :error)))
1323                 (case if-exists
1324                   ((:error nil)
1325                    (setf mask (logior mask unix:o_excl)))
1326                   ((:new-version :rename :rename-and-delete)
1327                    (setf mask (logior mask unix:o_creat)))
1328                   (:supersede
1329                    (setf mask (logior mask unix:o_trunc)))
1330                   (:append
1331                    (setf mask (logior mask unix:o_append)))))
1332                (t
1333                 (setf if-exists nil)))     ; :ignore-this-arg
1334    
1335          (unless if-does-not-exist-given
1336            (setf if-does-not-exist
1337                  (cond ((eq direction :input) :error)
1338                        ((and output
1339                              (member if-exists '(:overwrite :append)))
1340                         :error)
1341                        ((eq direction :probe)
1342                         nil)
1343                        (t
1344                         :create))))
1345          (if (eq if-does-not-exist :create)
1346              (setf mask (logior mask unix:o_creat)))
1347    
1348          (let ((original (cond ((eq if-exists :new-version)
1349                                 (next-version name))
1350                                ((member if-exists '(:rename :rename-and-delete))
1351                                 (pick-backup-name name))))
1352                (delete-original (eq if-exists :rename-and-delete))
1353                (mode #o666))
1354            (when original
1355              ;; We are doing a :rename or :rename-and-delete.
1356              ;; Determine if the file already exists, make sure the original
1357              ;; file is not a directory and keep the mode
1358              (let ((exists
1359                     (and name
1360                          (multiple-value-bind
1361                                (okay err/dev inode orig-mode)
1362                              (unix:unix-stat name)
1363                            (declare (ignore inode)
1364                                     (type (or index null) orig-mode))
1365                            (cond
1366                              (okay
1367                               (when (and output (= (logand orig-mode #o170000)
1368                                                    #o40000))
1369                                 (error 'simple-file-error
1370                                     :pathname pathname
1371                                     :format-control
1372                                     "Cannot open ~S for output: Is a directory."
1373                                     :format-arguments (list name)))
1374                               (setf mode (logand orig-mode #o777))
1375                               t)
1376                              ((eql err/dev unix:enoent)
1377                               nil)
1378                              (t
1379                               (error 'simple-file-error
1380                                      :pathname pathname
1381                                      :format-control "Cannot find ~S: ~A"
1382                                      :format-arguments
1383                                        (list name
1384                                          (unix:get-unix-error-msg err/dev)))))))))
1385                (unless (and exists
1386                             (do-old-rename name original))
1387                  (setf original nil)
1388                  (setf delete-original nil)
1389                  ;; In order to use SUPERSEDE instead, we have
1390                  ;; to make sure unix:o_creat corresponds to
1391                  ;; if-does-not-exist.  unix:o_creat was set
1392                  ;; before because of if-exists being :rename.
1393                  (unless (eq if-does-not-exist :create)
1394                    (setf mask (logior (logandc2 mask unix:o_creat)
1395                                       unix:o_trunc)))
1396                  (setf if-exists :supersede))))
1397    
1398            ;; Okay, now we can try the actual open.
1399            (loop
1400              (multiple-value-bind (fd errno)
1401                  (if name
1402                      (unix:unix-open name mask mode)
1403                      (values nil unix:enoent))
1404                (cond ((fixnump fd)
1405                       (return (values fd name original delete-original)))
1406                      ((eql errno unix:enoent)
1407                       (case if-does-not-exist
1408                         (:error
1409                           (cerror "Return NIL."
1410                                   'simple-file-error
1411                                   :pathname pathname
1412                                   :format-control "Error opening ~S, ~A."
1413                                   :format-arguments
1414                                       (list pathname
1415                                             (unix:get-unix-error-msg errno))))
1416                         (:create
1417                           (cerror "Return NIL."
1418                                   'simple-file-error
1419                                   :pathname pathname
1420                                   :format-control
1421                                       "Error creating ~S, path does not exist."
1422                                   :format-arguments (list pathname))))
1423                       (return nil))
1424                      ((eql errno unix:eexist)
1425                       (unless (eq nil if-exists)
1426                         (cerror "Return NIL."
1427                                 'simple-file-error
1428                                 :pathname pathname
1429                                 :format-control "Error opening ~S, ~A."
1430                                 :format-arguments
1431                                     (list pathname
1432                                           (unix:get-unix-error-msg errno))))
1433                       (return nil))
1434                      ((eql errno unix:eacces)
1435                       (cerror "Try again."
1436                               'simple-file-error
1437                               :pathname pathname
1438                               :format-control "Error opening ~S, ~A."
1439                               :format-arguments
1440                                   (list pathname
1441                                         (unix:get-unix-error-msg errno))))
1442                      (t
1443                       (cerror "Return NIL."
1444                               'simple-file-error
1445                               :pathname pathname
1446                               :format-control "Error opening ~S, ~A."
1447                               :format-arguments
1448                                   (list pathname
1449                                         (unix:get-unix-error-msg errno)))
1450                       (return nil)))))))))
1451    
1452    ;;; OPEN-FD-STREAM  --  Internal
1453    ;;;
1454    ;;;    Open an fd-stream connected to a file.
1455    ;;;
1456    (defun open-fd-stream (pathname &key (direction :input)
1457                                    (element-type 'base-char)
1458                                    (if-exists nil if-exists-given)
1459                                    (if-does-not-exist nil if-does-not-exist-given)
1460                                    (external-format :default))
1461      (declare (type pathname pathname)
1462               (type (member :input :output :io :probe) direction)
1463               (type (member :error :new-version :rename :rename-and-delete
1464                             :overwrite :append :supersede nil) if-exists)
1465               (type (member :error :create nil) if-does-not-exist)
1466               (ignore external-format))
1467      (multiple-value-bind (fd namestring original delete-original)
1468          (fd-open pathname direction if-exists if-exists-given
1469                   if-does-not-exist if-does-not-exist-given)
1470        (when fd
1471          (case direction
1472            ((:input :output :io)
1473             (make-fd-stream fd
1474                             :input (member direction '(:input :io))
1475                             :output (member direction '(:output :io))
1476                             :element-type element-type
1477                             :file namestring
1478                             :original original
1479                             :delete-original delete-original
1480                             :pathname pathname
1481                             :input-buffer-p t
1482                             :auto-close t))
1483            (:probe
1484             (let ((stream (%make-fd-stream :name namestring :fd fd
1485                                            :pathname pathname
1486                                            :element-type element-type)))
1487               (close stream)
1488               stream))))))
1489    
1490  ;;; OPEN -- public  ;;; OPEN -- public
1491  ;;;  ;;;
1492  ;;;   Open the given file.  ;;;   Open the given file.
1493  ;;;  ;;;
1494  (defun open (filename  (defun open (filename &rest options
1495               &key                        &key (direction :input)
1496               (direction :input)                             (element-type 'base-char element-type-given)
1497               (element-type 'base-char)                             (if-exists nil if-exists-given)
1498               (if-exists nil if-exists-given)                             (if-does-not-exist nil if-does-not-exist-given)
1499               (if-does-not-exist nil if-does-not-exist-given)                             (external-format :default)
1500               (external-format :default)                             class mapped input-handle output-handle
1501               class                        &allow-other-keys
1502               &aux ; Squelch assignment warning.                        &aux ; Squelch assignment warning.
1503               (direction direction)                        (direction direction)
1504               (if-does-not-exist if-does-not-exist)                        (if-does-not-exist if-does-not-exist)
1505               (if-exists if-exists))                        (if-exists if-exists))
1506    "Return a stream which reads from or writes to Filename.    "Return a stream which reads from or writes to Filename.
1507    Defined keywords:    Defined keywords:
1508     :direction - one of :input, :output, :io, or :probe     :direction - one of :input, :output, :io, or :probe
# Line 1322  Line 1510 
1510     :if-exists - one of :error, :new-version, :rename, :rename-and-delete,     :if-exists - one of :error, :new-version, :rename, :rename-and-delete,
1511                         :overwrite, :append, :supersede or nil                         :overwrite, :append, :supersede or nil
1512     :if-does-not-exist - one of :error, :create or nil     :if-does-not-exist - one of :error, :create or nil
1513       :external-format - :default
1514    See the manual for details."    See the manual for details."
1515    (declare (ignore external-format))    (declare (ignore external-format input-handle output-handle))
1516    
1517    ;; First, make sure that DIRECTION is valid. Allow it to be changed if not.    ;; First, make sure that DIRECTION is valid. Allow it to be changed if not.
1518    (setf direction    (setf direction
# Line 1331  Line 1520 
1520                         '(:input :output :io :probe)                         '(:input :output :io :probe)
1521                         :direction))                         :direction))
1522    
1523    ;; Calculate useful stuff.    (when (and if-exists-given (member direction '(:output :io)))
1524    (multiple-value-bind      (setq if-exists
1525        (input output mask)            (assure-one-of if-exists
1526        (case direction                           '(:error :new-version :rename
1527          (:input (values t nil unix:o_rdonly))                             :rename-and-delete :overwrite
1528          (:output (values nil t unix:o_wronly))                             :append :supersede nil)
1529          (:io (values t t unix:o_rdwr))                           :if-exists))
1530          (:probe (values t nil unix:o_rdonly)))      (setf (getf options :if-exists) if-exists))
1531      (declare (type index mask))  
1532      (let* ((pathname (pathname filename))    (when if-does-not-exist-given
1533             (namestring      (setq if-does-not-exist
1534              (cond ((unix-namestring pathname input))            (assure-one-of if-does-not-exist
1535                    ((and input (eq if-does-not-exist :create))                           '(:error :create nil)
1536                     (unix-namestring pathname nil)))))                           :if-does-not-exist))
1537        ;; Process if-exists argument if we are doing any output.      (setf (getf options :if-does-not-exist) if-does-not-exist))
1538        (cond (output  
1539               (unless if-exists-given    (let ((class (or class 'fd-stream))
1540                 (setf if-exists          (options (copy-list options))
1541                       (if (eq (pathname-version pathname) :newest)          (filespec (pathname filename)))
1542                           :new-version      (cond ((eq class 'fd-stream)
1543                           :error)))             (remf options :class)
1544               (setf if-exists             (remf options :mapped)
1545                     (assure-one-of if-exists             (remf options :input-handle)
1546                                    '(:error :new-version :rename             (remf options :output-handle)
1547                                      :rename-and-delete :overwrite             (apply #'open-fd-stream filespec options))
1548                                      :append :supersede nil)            ((subtypep class 'stream:simple-stream)
1549                                    :if-exists))             (when element-type-given
1550               (case if-exists               (error "Can't create simple-streams with an element-type."))
1551                 ((:error nil)             (when (and (eq class 'file-simple-stream) mapped)
1552                  (setf mask (logior mask unix:o_excl)))               (setq class 'mapped-file-simple-stream)
1553                 ((:new-version :rename :rename-and-delete)               (setf (getf options :class) 'mapped-file-simple-stream))
1554                  (setf mask (logior mask unix:o_creat)))             (when (subtypep class 'file-simple-stream)
1555                 ((:supersede)               (when (eq direction :probe)
1556                  (setf mask (logior mask unix:o_trunc)))                 (setq class 'probe-simple-stream)))
1557                 (:append             (apply #'make-instance class :filename filespec options))
1558                  (setf mask (logior mask unix:o_append)))))            ((subtypep class 'ext:fundamental-stream)
1559              (t             (remf options :class)
1560               (setf if-exists :ignore-this-arg)))             (remf options :mapped)
1561               (remf options :input-handle)
1562        (unless if-does-not-exist-given             (remf options :output-handle)
1563          (setf if-does-not-exist             (let ((stream (apply #'open-fd-stream filespec options)))
1564                (cond ((eq direction :input) :error)               (when stream
1565                      ((and output                 (make-instance class :lisp-stream stream))))
1566                            (member if-exists '(:overwrite :append)))            (t
1567                       :error)             (error "Unable to open streams of class ~S." class)))))
                     ((eq direction :probe)  
                      nil)  
                     (t  
                      :create))))  
       (setf if-does-not-exist  
             (assure-one-of if-does-not-exist  
                            '(:error :create nil)  
                            :if-does-not-exist))  
       (if (eq if-does-not-exist :create)  
         (setf mask (logior mask unix:o_creat)))  
   
       (let ((original (cond ((eq if-exists :new-version)  
                              (next-version namestring))  
                             ((member if-exists '(:rename :rename-and-delete))  
                              (pick-backup-name namestring))))  
             (delete-original (eq if-exists :rename-and-delete))  
             (mode #o666))  
         (when original  
           ;; We are doing a :rename or :rename-and-delete.  
           ;; Determine if the file already exists, make sure the original  
           ;; file is not a directory and keep the mode  
           (let ((exists  
                  (and namestring  
                       (multiple-value-bind  
                           (okay err/dev inode orig-mode)  
                           (unix:unix-stat namestring)  
                         (declare (ignore inode)  
                                  (type (or index null) orig-mode))  
                         (cond  
                          (okay  
                           (when (and output (= (logand orig-mode #o170000)  
                                                #o40000))  
                             (error 'simple-file-error  
                                    :format-control "Cannot open ~S for output: Is a directory."  
                                    :format-arguments (list namestring)))  
                           (setf mode (logand orig-mode #o777))  
                           t)  
                          ((eql err/dev unix:enoent)  
                           nil)  
                          (t  
                           (error 'simple-file-error  
                                  :format-control "Cannot find ~S: ~A"  
                                  :format-arguments  
                                  (list namestring (unix:get-unix-error-msg err/dev)))))))))  
             (unless (and exists  
                          (do-old-rename namestring original))  
               (setf original nil)  
               (setf delete-original nil)  
               ;; In order to use SUPERSEDE instead, we have  
               ;; to make sure unix:o_creat corresponds to  
               ;; if-does-not-exist.  unix:o_creat was set  
               ;; before because of if-exists being :rename.  
               (unless (eq if-does-not-exist :create)  
                 (setf mask (logior (logandc2 mask unix:o_creat) unix:o_trunc)))  
               (setf if-exists :supersede))))  
   
         ;; Okay, now we can try the actual open.  
         (loop  
           (multiple-value-bind  
               (fd errno)  
               (if namestring  
                   (unix:unix-open namestring mask mode)  
                   (values nil unix:enoent))  
             (cond ((numberp fd)  
                    (return-stream class  
                     (case direction  
                       ((:input :output :io)  
                        (make-fd-stream fd  
                                        :input input  
                                        :output output  
                                        :element-type element-type  
                                        :file namestring  
                                        :original original  
                                        :delete-original delete-original  
                                        :pathname pathname  
                                        :input-buffer-p t  
                                        :auto-close t))  
                       (:probe  
                        (let ((stream  
                               (%make-fd-stream :name namestring :fd fd  
                                                :pathname pathname  
                                                :element-type element-type)))  
                          (close stream)  
                          stream)))))  
                   ((eql errno unix:enoent)  
                    (case if-does-not-exist  
                      (:error  
                       (cerror "Return NIL."  
                               'simple-file-error  
                               :pathname pathname  
                               :format-control "Error opening ~S, ~A."  
                               :format-arguments  
                               (list pathname (unix:get-unix-error-msg errno))))  
                      (:create  
                       (cerror "Return NIL."  
                               "Error creating ~S, path does not exist."  
                               pathname)))  
                    (return nil))  
                   ((eql errno unix:eexist)  
                    (unless (eq nil if-exists)  
                      (cerror "Return NIL."  
                              'simple-file-error  
                              :pathname pathname  
                              :format-control "Error opening ~S, ~A."  
                              :format-arguments  
                              (list pathname (unix:get-unix-error-msg errno))))  
                    (return nil))  
                   ((eql errno unix:eacces)  
                    (cerror "Try again."  
                           "Error opening ~S, ~A."  
                           pathname  
                           (unix:get-unix-error-msg errno)))  
                   (t  
                    (cerror "Return NIL."  
                            "Error opening ~S, ~A."  
                            pathname  
                            (unix:get-unix-error-msg errno))  
                    (return nil)))))))))  
1568    
1569  ;;;; Initialization.  ;;;; Initialization.
1570    
# Line 1564  Line 1635 
1635  ;;; stuff to get and set the file name.  ;;; stuff to get and set the file name.
1636  ;;;  ;;;
1637  (defun file-name (stream &optional new-name)  (defun file-name (stream &optional new-name)
1638    (when (typep stream 'fd-stream)    (typecase stream
1639        (cond (new-name      (stream:simple-stream
1640               (setf (fd-stream-pathname stream) new-name)       (if new-name
1641               (setf (fd-stream-file stream)           (stream::%file-rename stream new-name)
1642                     (unix-namestring new-name nil))           (stream::%file-name stream)))
1643               t)      (fd-stream
1644              (t       (cond (new-name
1645               (fd-stream-pathname stream)))))              (setf (fd-stream-pathname stream) new-name)
1646                (setf (fd-stream-file stream)
1647                      (unix-namestring new-name nil))
1648                t)
1649               (t
1650                (fd-stream-pathname stream))))))
1651    
1652    
1653  ;;;; Degenerate international character support:  ;;;; Degenerate international character support:
1654    
1655  (defun file-string-length (stream object)  (defun file-string-length (stream object)
1656    (declare (type (or string character) object) (type file-stream stream))    (declare (type (or string character) object)
1657               (type (or file-stream stream:simple-stream) stream))
1658    "Return the delta in Stream's FILE-POSITION that would be caused by writing    "Return the delta in Stream's FILE-POSITION that would be caused by writing
1659     Object to Stream.  Non-trivial only in implementations that support     Object to Stream.  Non-trivial only in implementations that support
1660     international character sets."     international character sets."
1661    (declare (ignore stream))    (typecase stream
1662    (etypecase object      (stream:simple-stream (stream::%file-string-length stream object))
1663      (character 1)      (t
1664      (string (length object))))       (etypecase object
1665           (character 1)
1666  (defun stream-external-format (stream)         (string (length object))))))
   (declare (type file-stream stream) (ignore stream))  
   "Returns :DEFAULT."  
   :default)  

Legend:
Removed from v.1.65  
changed lines
  Added in v.1.66

  ViewVC Help
Powered by ViewVC 1.1.5