Raymond Toy pushed to branch issue-240-set-diff-with-hash-table at cmucl / cmucl
Commits:
-
1fcdbdb2
by Raymond Toy at 2023-06-19T14:17:30-07:00
-
4e433b83
by Raymond Toy at 2023-07-05T06:40:08-07:00
-
da69492b
by Raymond Toy at 2023-07-17T15:07:01+00:00
-
635d07ca
by Raymond Toy at 2023-07-17T15:07:04+00:00
-
0a35575a
by Raymond Toy at 2023-07-17T15:07:47+00:00
-
5d4b0622
by Raymond Toy at 2023-07-17T15:07:49+00:00
-
bdd7294f
by Raymond Toy at 2023-07-21T19:15:10+00:00
-
4bce99fc
by Raymond Toy at 2023-07-21T19:15:11+00:00
-
d37a3150
by Raymond Toy at 2023-07-22T00:19:38+00:00
-
95dfdcf3
by Raymond Toy at 2023-07-22T00:19:39+00:00
-
8c6e050a
by Raymond Toy at 2023-07-21T18:06:08-07:00
-
a85ad7cf
by Raymond Toy at 2023-07-23T12:18:48-07:00
-
d5c23293
by Raymond Toy at 2023-07-23T15:07:27-07:00
-
1b54eed9
by Raymond Toy at 2023-07-23T17:18:18-07:00
-
f44c4b81
by Raymond Toy at 2023-07-24T14:51:30-07:00
15 changed files:
- bin/build.sh
- bin/run-tests.sh
- src/code/alieneval.lisp
- src/code/extfmts.lisp
- src/code/fd-stream-comp.lisp
- src/code/list.lisp
- src/code/pathname.lisp
- src/code/pred.lisp
- src/compiler/x86/c-call.lisp
- src/compiler/x86/insts.lisp
- src/general-info/release-21f.md
- src/i18n/locale/cmucl.pot
- tests/issues.lisp
- tests/pathname.lisp
- + tests/test-return.c
Changes:
| ... | ... | @@ -110,6 +110,8 @@ case `uname -s` in |
| 110 | 110 | esac ;;
|
| 111 | 111 | esac
|
| 112 | 112 | |
| 113 | +export LANG=en_US.UTF-8
|
|
| 114 | + |
|
| 113 | 115 | buildit ()
|
| 114 | 116 | {
|
| 115 | 117 | if echo $INTERACTIVE_BUILD | grep $BUILD > /dev/null; then
|
| ... | ... | @@ -47,6 +47,11 @@ function cleanup { |
| 47 | 47 | |
| 48 | 48 | trap cleanup EXIT
|
| 49 | 49 | |
| 50 | +# Compile up the C file that is used for testing alien funcalls to
|
|
| 51 | +# functions that return integer types of different lengths. We use
|
|
| 52 | +# gcc since clang isn't always available.
|
|
| 53 | +(cd tests; gcc -m32 -O3 -c test-return.c)
|
|
| 54 | + |
|
| 50 | 55 | if [ $# -eq 0 ]; then
|
| 51 | 56 | # No args so run all the tests
|
| 52 | 57 | $LISP -noinit -load tests/run-tests.lisp -eval '(cmucl-test-runner:run-all-tests)'
|
| ... | ... | @@ -170,6 +170,9 @@ |
| 170 | 170 | (alien-rep nil :type (or null function))
|
| 171 | 171 | (extract-gen nil :type (or null function))
|
| 172 | 172 | (deposit-gen nil :type (or null function))
|
| 173 | + ;;
|
|
| 174 | + ;; Method that accepts the alien type and the alien value. The
|
|
| 175 | + ;; method converts the alien value into an appropriate lisp value.
|
|
| 173 | 176 | (naturalize-gen nil :type (or null function))
|
| 174 | 177 | (deport-gen nil :type (or null function))
|
| 175 | 178 | ;; Cast?
|
| ... | ... | @@ -646,8 +649,26 @@ |
| 646 | 649 | |
| 647 | 650 | #-amd64
|
| 648 | 651 | (def-alien-type-method (integer :naturalize-gen) (type alien)
|
| 649 | - (declare (ignore type))
|
|
| 650 | - alien)
|
|
| 652 | + ;; Mask out any unwanted bits. Important if the C code returns
|
|
| 653 | + ;; values in %al, or %ax
|
|
| 654 | + (if (alien-integer-type-signed type)
|
|
| 655 | + (let ((val (gensym "VAL-")))
|
|
| 656 | + (case (alien-integer-type-bits type)
|
|
| 657 | + ;; First, get just the low part of the alien and then
|
|
| 658 | + ;; sign-extend it appropriately.
|
|
| 659 | + (8 `(let ((,val (ldb (byte 8 0) ,alien)))
|
|
| 660 | + (if (> ,val #x7f)
|
|
| 661 | + (- ,val #x100)
|
|
| 662 | + ,val)))
|
|
| 663 | + (16 `(let ((,val (ldb (byte 16 0) ,alien)))
|
|
| 664 | + (if (> ,val #x7fff)
|
|
| 665 | + (- ,val #x10000)
|
|
| 666 | + ,val)))
|
|
| 667 | + (t alien)))
|
|
| 668 | + (case (alien-integer-type-bits type)
|
|
| 669 | + (8 `(ldb (byte 8 0) (truly-the (unsigned-byte 32) ,alien)))
|
|
| 670 | + (16 `(ldb (byte 16 0) (truly-the (unsigned-byte 32) ,alien)))
|
|
| 671 | + (t alien))))
|
|
| 651 | 672 | |
| 652 | 673 | ;; signed numbers <= 32 bits need to be sign extended.
|
| 653 | 674 | ;; I really should use the movsxd instruction, but I don't
|
| ... | ... | @@ -694,8 +715,8 @@ |
| 694 | 715 | |
| 695 | 716 | (def-alien-type-class (boolean :include integer :include-args (signed)))
|
| 696 | 717 | |
| 697 | -(def-alien-type-translator boolean (&optional (bits vm:word-bits))
|
|
| 698 | - (make-alien-boolean-type :bits bits :signed nil))
|
|
| 718 | +(def-alien-type-translator boolean (&optional (bits 8))
|
|
| 719 | + (make-alien-boolean-type :bits bits :signed t))
|
|
| 699 | 720 | |
| 700 | 721 | (def-alien-type-method (boolean :unparse) (type)
|
| 701 | 722 | `(boolean ,(alien-boolean-type-bits type)))
|
| ... | ... | @@ -705,8 +726,10 @@ |
| 705 | 726 | `(member t nil))
|
| 706 | 727 | |
| 707 | 728 | (def-alien-type-method (boolean :naturalize-gen) (type alien)
|
| 708 | - (declare (ignore type))
|
|
| 709 | - `(not (zerop ,alien)))
|
|
| 729 | + ;; Mask out any unwanted bits. Important if the C code returns
|
|
| 730 | + ;; values in %al, or %ax
|
|
| 731 | + `(not (zerop (ldb (byte ,(alien-boolean-type-bits type) 0)
|
|
| 732 | + ,alien))))
|
|
| 710 | 733 | |
| 711 | 734 | (def-alien-type-method (boolean :deport-gen) (type value)
|
| 712 | 735 | (declare (ignore type))
|
| ... | ... | @@ -461,15 +461,18 @@ |
| 461 | 461 | (format t "~&~A~%"
|
| 462 | 462 | (intl:gettext (or (ef-documentation ef) "")))))))))
|
| 463 | 463 | |
| 464 | +(defconstant +builtin-external-formats+ '(:utf-8 :iso8859-1 :ascii)
|
|
| 465 | + "List of external formats that are builtin so that they don't need to
|
|
| 466 | + be loaded on first use.")
|
|
| 467 | + |
|
| 464 | 468 | (defun %find-external-format (name)
|
| 465 | 469 | ;; avoid loading files, etc., early in the boot sequence
|
| 466 | - (when (or (eq name :iso8859-1)
|
|
| 467 | - (and (eq name :default) (eq *default-external-format* :iso8859-1)))
|
|
| 468 | - (return-from %find-external-format
|
|
| 469 | - (gethash :iso8859-1 *external-formats*)))
|
|
| 470 | - (when (eq name :utf-8)
|
|
| 470 | + (when (and (eq name :default)
|
|
| 471 | + (eq *default-external-format* :iso8859-1))
|
|
| 472 | + (setf name :iso8859-1))
|
|
| 473 | + (when (member name +builtin-external-formats+ :test 'eq)
|
|
| 471 | 474 | (return-from %find-external-format
|
| 472 | - (gethash :utf-8 *external-formats*)))
|
|
| 475 | + (gethash name *external-formats*)))
|
|
| 473 | 476 | |
| 474 | 477 | (when (zerop (hash-table-count *external-format-aliases*))
|
| 475 | 478 | (setf (gethash :latin1 *external-format-aliases*) :iso8859-1)
|
| ... | ... | @@ -1188,6 +1191,8 @@ character and illegal outputs are replaced by a question mark.") |
| 1188 | 1191 | ,(subst (ef-name ef) ef
|
| 1189 | 1192 | (function-lambda-expression (aref (ef-cache ef) slot))))))
|
| 1190 | 1193 | |
| 1194 | +;;; Builtin external formats.
|
|
| 1195 | + |
|
| 1191 | 1196 | ;; A safe UTF-8 external format. Any illegal UTF-8 sequences on input
|
| 1192 | 1197 | ;; are replaced with the Unicode REPLACEMENT CHARACTER (U+FFFD), or
|
| 1193 | 1198 | ;; signals an error as appropriate.
|
| ... | ... | @@ -1303,3 +1308,29 @@ replacement character.") |
| 1303 | 1308 | ((< ,code #x10000) (utf8 ,code 2))
|
| 1304 | 1309 | ((< ,code #x110000) (utf8 ,code 3))
|
| 1305 | 1310 | (t (error "How did this happen? Codepoint U+~X is illegal" ,code))))))
|
| 1311 | + |
|
| 1312 | +(define-external-format :ascii (:size 1 :documentation
|
|
| 1313 | +"US ASCII 7-bit encoding. Illegal input sequences are replaced with
|
|
| 1314 | +the Unicode replacment character. Illegal output characters are
|
|
| 1315 | +replaced with a question mark.")
|
|
| 1316 | + ()
|
|
| 1317 | + (octets-to-code (state input unput error c)
|
|
| 1318 | + `(let ((,c ,input))
|
|
| 1319 | + (values (if (< ,c #x80)
|
|
| 1320 | + ,c
|
|
| 1321 | + (if ,error
|
|
| 1322 | + (locally
|
|
| 1323 | + ;; No warnings about fdefinition
|
|
| 1324 | + (declare (optimize (ext:inhibit-warnings 3)))
|
|
| 1325 | + (funcall ,error "Invalid octet #x~4,'0X for ASCII" ,c 1))
|
|
| 1326 | + +replacement-character-code+))
|
|
| 1327 | + 1)))
|
|
| 1328 | + (code-to-octets (code state output error)
|
|
| 1329 | + `(,output (if (> ,code #x7F)
|
|
| 1330 | + (if ,error
|
|
| 1331 | + (locally
|
|
| 1332 | + ;; No warnings about fdefinition
|
|
| 1333 | + (declare (optimize (ext:inhibit-warnings 3)))
|
|
| 1334 | + (funcall ,error "Cannot output codepoint #x~X to ASCII stream" ,code))
|
|
| 1335 | + #x3F)
|
|
| 1336 | + ,code)))) |
| ... | ... | @@ -28,6 +28,7 @@ |
| 28 | 28 | (stream::precompile-ef-slot :iso8859-1 #.stream::+ef-de+)
|
| 29 | 29 | (stream::precompile-ef-slot :iso8859-1 #.stream::+ef-osc+)
|
| 30 | 30 | |
| 31 | +;; :utf-8 is builtin. Important since it's the default now.
|
|
| 31 | 32 | (stream::precompile-ef-slot :utf-8 #.stream::+ef-cin+)
|
| 32 | 33 | (stream::precompile-ef-slot :utf-8 #.stream::+ef-cout+)
|
| 33 | 34 | (stream::precompile-ef-slot :utf-8 #.stream::+ef-sout+)
|
| ... | ... | @@ -36,3 +37,13 @@ |
| 36 | 37 | (stream::precompile-ef-slot :utf-8 #.stream::+ef-en+)
|
| 37 | 38 | (stream::precompile-ef-slot :utf-8 #.stream::+ef-de+)
|
| 38 | 39 | (stream::precompile-ef-slot :utf-8 #.stream::+ef-osc+)
|
| 40 | + |
|
| 41 | +;; :ascii is builtin.
|
|
| 42 | +(stream::precompile-ef-slot :ascii #.stream::+ef-cin+)
|
|
| 43 | +(stream::precompile-ef-slot :ascii #.stream::+ef-cout+)
|
|
| 44 | +(stream::precompile-ef-slot :ascii #.stream::+ef-sout+)
|
|
| 45 | +(stream::precompile-ef-slot :ascii #.stream::+ef-os+)
|
|
| 46 | +(stream::precompile-ef-slot :ascii #.stream::+ef-so+)
|
|
| 47 | +(stream::precompile-ef-slot :ascii #.stream::+ef-en+)
|
|
| 48 | +(stream::precompile-ef-slot :ascii #.stream::+ef-de+)
|
|
| 49 | +(stream::precompile-ef-slot :ascii #.stream::+ef-osc+) |
| ... | ... | @@ -748,64 +748,30 @@ |
| 748 | 748 | (defparameter *min-list-length-for-hashtable*
|
| 749 | 749 | 15)
|
| 750 | 750 | |
| 751 | -(defun init-hashtable-list1 (list1 len &key key test)
|
|
| 752 | - (let ((hashtable (make-hash-table :test test :size len)))
|
|
| 753 | - (dolist (item list1)
|
|
| 754 | - (push item (gethash (apply-key key item) hashtable)))
|
|
| 755 | - (values hashtable list1)))
|
|
| 756 | - |
|
| 757 | -(defun init-hashtable-list2 (list2 len &key key test)
|
|
| 758 | - (let ((hashtable (make-hash-table :test test :size len)))
|
|
| 759 | - (dolist (item list2)
|
|
| 760 | - (setf (gethash (apply-key key item) hashtable) item))
|
|
| 761 | - (values hashtable list2)))
|
|
| 762 | - |
|
| 763 | -;; Convert a list to a hashtable. Given 2 lists, find the shorter of
|
|
| 764 | -;; the two lists and add the shorter list to a hashtable. Returns the
|
|
| 765 | -;; hashtable and the shorter list.
|
|
| 766 | -(defun list-to-hashtable (list1 list2 &key test test-not key)
|
|
| 751 | +;; Convert a list to a hashtable. The hashtable does not handle
|
|
| 752 | +;; duplicated values in the list. Returns the hashtable.
|
|
| 753 | +(defun list-to-hashtable (list &key test test-not key)
|
|
| 767 | 754 | ;; Don't currently support test-not when converting a list to a hashtable
|
| 768 | 755 | (unless test-not
|
| 769 | 756 | (let ((hash-test (let ((test-fn (if (and (symbolp test)
|
| 770 | 757 | (fboundp test))
|
| 771 | 758 | (fdefinition test)
|
| 772 | 759 | test)))
|
| 773 | - (cond ((eql test-fn #'eq) 'eq)
|
|
| 774 | - ((eql test-fn #'eql) 'eql)
|
|
| 775 | - ((eql test-fn #'equal) 'equal)
|
|
| 776 | - ((eql test-fn #'equalp) 'equalp)))))
|
|
| 760 | + (case test-fn
|
|
| 761 | + (#'eq 'eq)
|
|
| 762 | + (#'eql 'eql)
|
|
| 763 | + (#'equal 'equal)
|
|
| 764 | + (#'equalp 'equalp)))))
|
|
| 777 | 765 | (unless hash-test
|
| 778 | - (return-from list-to-hashtable (values nil nil)))
|
|
| 779 | - (multiple-value-bind (len shorter-list)
|
|
| 780 | - ;; Find the list with the shorter length. If they're they
|
|
| 781 | - ;; same, we prefer the second list to the first list since
|
|
| 782 | - ;; the hashtable implementation is slightly simplier.
|
|
| 783 | - (do ((length 0 (1+ length))
|
|
| 784 | - (l1 list1 (cdr l1))
|
|
| 785 | - (l2 list2 (cdr l2)))
|
|
| 786 | - ((cond ((endp l2)
|
|
| 787 | - (return (values length list2)))
|
|
| 788 | - #+nil
|
|
| 789 | - ((endp l1)
|
|
| 790 | - (return (values length list1))))))
|
|
| 791 | - ;; If the list is too short, the hashtable makes things
|
|
| 792 | - ;; slower. We also need to balance memory usage.
|
|
| 793 | - (when (< len *min-list-length-for-hashtable*)
|
|
| 794 | - (return-from list-to-hashtable (values nil nil)))
|
|
| 795 | - (cond ((eq shorter-list list2)
|
|
| 796 | - #+nil
|
|
| 797 | - (let ((hashtable (make-hash-table :test test :size len)))
|
|
| 798 | - (dolist (item list2)
|
|
| 799 | - (setf (gethash (apply-key key item) hashtable) item))
|
|
| 800 | - (values hashtable list2))
|
|
| 801 | - (init-hashtable-list2 list2 len :key key :test test))
|
|
| 802 | - ((eq shorter-list list1)
|
|
| 803 | - #+nil
|
|
| 804 | - (let ((hashtable (make-hash-table :test test :size len)))
|
|
| 805 | - (dolist (item list1)
|
|
| 806 | - (push item (gethash (apply-key key item) hashtable)))
|
|
| 807 | - (values hashtable list1))
|
|
| 808 | - (init-hashtable-list1 list1 len :key key :test test)))))))
|
|
| 766 | + (return-from list-to-hashtable nil))
|
|
| 767 | + ;; If the list is too short, the hashtable makes things
|
|
| 768 | + ;; slower. We also need to balance memory usage.
|
|
| 769 | + (when (< (length list) *min-list-length-for-hashtable*)
|
|
| 770 | + (return-from list-to-hashtable nil))
|
|
| 771 | + (let ((hashtable (make-hash-table :test test :size len)))
|
|
| 772 | + (dolist (item list)
|
|
| 773 | + (setf (gethash (apply-key key item) hashtable) item))
|
|
| 774 | + hashtable))))
|
|
| 809 | 775 | |
| 810 | 776 | ;;; UNION -- Public.
|
| 811 | 777 | ;;;
|
| ... | ... | @@ -874,24 +840,6 @@ |
| 874 | 840 | (setq list1 (Cdr list1))))
|
| 875 | 841 | res))
|
| 876 | 842 | |
| 877 | -(defun set-diff-hash2 (list1 hashtable &key key)
|
|
| 878 | - (let (diff)
|
|
| 879 | - (dolist (item list1)
|
|
| 880 | - (unless (nth-value 1 (gethash (apply-key key item) hashtable))
|
|
| 881 | - (push item diff)))
|
|
| 882 | - diff))
|
|
| 883 | - |
|
| 884 | -(defun set-diff-hash1 (list2 hashtable &key key)
|
|
| 885 | - (dolist (item list2)
|
|
| 886 | - (unless (eq hashtable (gethash (apply-key key item) hashtable hashtable))
|
|
| 887 | - (remhash item hashtable)))
|
|
| 888 | - (let ((result '()))
|
|
| 889 | - (maphash #'(lambda (key value)
|
|
| 890 | - (declare (ignore key))
|
|
| 891 | - (setq result (nconc result value)))
|
|
| 892 | - hashtable)
|
|
| 893 | - result))
|
|
| 894 | - |
|
| 895 | 843 | (defun set-difference (list1 list2 &key key (test #'eql testp) (test-not nil notp))
|
| 896 | 844 | "Returns the elements of list1 which are not in list2."
|
| 897 | 845 | (declare (inline member))
|
| ... | ... | @@ -901,40 +849,23 @@ |
| 901 | 849 | (when (null list2)
|
| 902 | 850 | (return-from set-difference list1))
|
| 903 | 851 | |
| 904 | - (multiple-value-bind (hashtable shorter-list)
|
|
| 905 | - (list-to-hashtable list1 list2 :key key :test test :test-not test-not)
|
|
| 906 | - (cond ((null hashtable)
|
|
| 852 | + (let ((hashtable
|
|
| 853 | + (list-to-hashtable list2 :key key :test test :test-not test-not)))
|
|
| 854 | + (cond (hashtable
|
|
| 855 | + ;; list2 was placed in hash table.
|
|
| 856 | + (let (diff)
|
|
| 857 | + (dolist (item list1)
|
|
| 858 | + (unless (nth-value 1 (gethash (apply-key key item) hashtable))
|
|
| 859 | + (push item diff)))
|
|
| 860 | + diff))
|
|
| 861 | + ((null hashtable)
|
|
| 907 | 862 | ;; Default implementation because we didn't create the hash
|
| 908 | 863 | ;; table.
|
| 909 | 864 | (let ((res nil))
|
| 910 | 865 | (dolist (elt list1)
|
| 911 | 866 | (if (not (with-set-keys (member (apply-key key elt) list2)))
|
| 912 | 867 | (push elt res)))
|
| 913 | - res))
|
|
| 914 | - ((eq shorter-list list2)
|
|
| 915 | - ;; list2 was placed in hash table.
|
|
| 916 | - #+nil
|
|
| 917 | - (let (diff)
|
|
| 918 | - (dolist (item list1)
|
|
| 919 | - (unless (nth-value 1 (gethash (apply-key key item) hashtable))
|
|
| 920 | - (push item diff)))
|
|
| 921 | - diff)
|
|
| 922 | - (set-diff-hash2 list1 hashtable :key key))
|
|
| 923 | - ((eq shorter-list list1)
|
|
| 924 | - ;; list1 was placed in the hash table.
|
|
| 925 | - #+nil
|
|
| 926 | - (dolist (item list2)
|
|
| 927 | - (unless (eq hashtable (gethash (apply-key key item) hashtable hashtable))
|
|
| 928 | - (remhash item hashtable)))
|
|
| 929 | - #+nil
|
|
| 930 | - (let ((result '()))
|
|
| 931 | - (maphash #'(lambda (key value)
|
|
| 932 | - (declare (ignore key))
|
|
| 933 | - (setq result (nconc result value)))
|
|
| 934 | - hashtable)
|
|
| 935 | - result)
|
|
| 936 | - (set-diff-hash1 list2 hashtable :key key)))))
|
|
| 937 | - |
|
| 868 | + res)))))
|
|
| 938 | 869 | |
| 939 | 870 | (defun nset-difference (list1 list2 &key key
|
| 940 | 871 | (test #'eql testp) (test-not nil notp))
|
| ... | ... | @@ -121,58 +121,73 @@ |
| 121 | 121 | (defun %print-pathname (pathname stream depth)
|
| 122 | 122 | (declare (ignore depth))
|
| 123 | 123 | (let* ((host (%pathname-host pathname))
|
| 124 | + (device (%pathname-device pathname))
|
|
| 125 | + (directory (%pathname-directory pathname))
|
|
| 126 | + (name (%pathname-name pathname))
|
|
| 127 | + (type (%pathname-type pathname))
|
|
| 128 | + (version (%pathname-version pathname))
|
|
| 129 | + (unspecific-p (or (eq device :unspecific)
|
|
| 130 | + (eq name :unspecific)
|
|
| 131 | + (eq type :unspecific)
|
|
| 132 | + (eq version :unspecific)))
|
|
| 124 | 133 | (namestring (if host
|
| 125 | 134 | (handler-case (namestring pathname)
|
| 126 | 135 | (error nil))
|
| 127 | 136 | nil)))
|
| 128 | - (cond (namestring
|
|
| 137 | + ;; A pathname with :UNSPECIFIC components has a namestring that
|
|
| 138 | + ;; ignores :UNSPECIFIC (and NIL). Thus the namestring exists, but
|
|
| 139 | + ;; we want to use our special syntax to print the pathname
|
|
| 140 | + ;; readably when :UNSPECIFIC occurs.
|
|
| 141 | + (cond ((and namestring (not unspecific-p))
|
|
| 129 | 142 | (if (or *print-escape* *print-readably*)
|
| 130 | 143 | (format stream "#P~S" namestring)
|
| 131 | 144 | (format stream "~A" namestring)))
|
| 132 | 145 | (t
|
| 133 | - (let ((device (%pathname-device pathname))
|
|
| 134 | - (directory (%pathname-directory pathname))
|
|
| 135 | - (name (%pathname-name pathname))
|
|
| 136 | - (type (%pathname-type pathname))
|
|
| 137 | - (version (%pathname-version pathname)))
|
|
| 138 | - (cond ((every #'(lambda (d)
|
|
| 139 | - (or (stringp d)
|
|
| 140 | - (symbolp d)))
|
|
| 141 | - (cdr directory))
|
|
| 142 | - ;; A CMUCL extension. If we have an unprintable
|
|
| 143 | - ;; pathname, convert it to a form that would be
|
|
| 144 | - ;; suitable as args to MAKE-PATHNAME to recreate
|
|
| 145 | - ;; the pathname.
|
|
| 146 | - ;;
|
|
| 147 | - ;; We don't handle search-lists because we don't
|
|
| 148 | - ;; currently have a readable syntax for
|
|
| 149 | - ;; search-lists.
|
|
| 150 | - (collect ((result))
|
|
| 151 | - (unless (eq host *unix-host*)
|
|
| 152 | - (result :host)
|
|
| 153 | - (result (if host
|
|
| 154 | - (pathname-host pathname)
|
|
| 155 | - nil)))
|
|
| 156 | - (when device
|
|
| 157 | - (result :device)
|
|
| 158 | - (result device))
|
|
| 159 | - (when directory
|
|
| 160 | - (result :directory)
|
|
| 161 | - (result directory))
|
|
| 162 | - (when name
|
|
| 163 | - (result :name)
|
|
| 164 | - (result name))
|
|
| 165 | - (when type
|
|
| 166 | - (result :type)
|
|
| 167 | - (result type))
|
|
| 168 | - (when version
|
|
| 169 | - (result :version)
|
|
| 170 | - (result version))
|
|
| 171 | - (format stream "#P~S" (result))))
|
|
| 172 | - (*print-readably*
|
|
| 173 | - (error 'print-not-readable :object pathname))
|
|
| 174 | - (t
|
|
| 175 | - (funcall (formatter "#<Unprintable pathname,~:_ Host=~S,~:_ Device=~S,~:_ ~
|
|
| 146 | + (cond ((and
|
|
| 147 | + ;; We only use the extension if the pathname does
|
|
| 148 | + ;; not contain a pattern object which doesn't print
|
|
| 149 | + ;; readably. Search-lists, which are part of the
|
|
| 150 | + ;; directory component, are excluded too.
|
|
| 151 | + (not (typep name 'pattern))
|
|
| 152 | + (not (typep type 'pattern))
|
|
| 153 | + (every #'(lambda (d)
|
|
| 154 | + (or (stringp d)
|
|
| 155 | + (symbolp d)))
|
|
| 156 | + (cdr directory)))
|
|
| 157 | + ;; A CMUCL extension. If we have an unprintable
|
|
| 158 | + ;; pathname, convert it to a form that would be
|
|
| 159 | + ;; suitable as args to MAKE-PATHNAME to recreate
|
|
| 160 | + ;; the pathname.
|
|
| 161 | + ;;
|
|
| 162 | + ;; We don't handle search-lists because we don't
|
|
| 163 | + ;; currently have a readable syntax for
|
|
| 164 | + ;; search-lists.
|
|
| 165 | + (collect ((result))
|
|
| 166 | + (unless (eq host *unix-host*)
|
|
| 167 | + (result :host)
|
|
| 168 | + (result (if host
|
|
| 169 | + (pathname-host pathname)
|
|
| 170 | + nil)))
|
|
| 171 | + (when device
|
|
| 172 | + (result :device)
|
|
| 173 | + (result device))
|
|
| 174 | + (when directory
|
|
| 175 | + (result :directory)
|
|
| 176 | + (result directory))
|
|
| 177 | + (when name
|
|
| 178 | + (result :name)
|
|
| 179 | + (result name))
|
|
| 180 | + (when type
|
|
| 181 | + (result :type)
|
|
| 182 | + (result type))
|
|
| 183 | + (when version
|
|
| 184 | + (result :version)
|
|
| 185 | + (result version))
|
|
| 186 | + (format stream "#P~S" (result))))
|
|
| 187 | + (*print-readably*
|
|
| 188 | + (error 'print-not-readable :object pathname))
|
|
| 189 | + (t
|
|
| 190 | + (funcall (formatter "#<Unprintable pathname,~:_ Host=~S,~:_ Device=~S,~:_ ~
|
|
| 176 | 191 | Directory=~S,~:_ Name=~S,~:_ Type=~S,~:_ Version=~S>")
|
| 177 | 192 | stream
|
| 178 | 193 | (%pathname-host pathname)
|
| ... | ... | @@ -387,8 +387,8 @@ |
| 387 | 387 | (defun equal (x y)
|
| 388 | 388 | "Returns T if X and Y are EQL or if they are structured components
|
| 389 | 389 | whose elements are EQUAL. Strings and bit-vectors are EQUAL if they
|
| 390 | - are the same length and have indentical components. Other arrays must be
|
|
| 391 | - EQ to be EQUAL."
|
|
| 390 | + are the same length and have identical components. Other arrays
|
|
| 391 | + must be EQ to be EQUAL."
|
|
| 392 | 392 | (cond ((eql x y) t)
|
| 393 | 393 | ((consp x)
|
| 394 | 394 | (and (consp y)
|
| ... | ... | @@ -141,59 +141,77 @@ |
| 141 | 141 | (alien-function-type-result-type type)
|
| 142 | 142 | (make-result-state))))))
|
| 143 | 143 | |
| 144 | -(deftransform %alien-funcall ((function type &rest args))
|
|
| 145 | - (assert (c::constant-continuation-p type))
|
|
| 144 | +(defun %alien-funcall-aux (function type &rest args)
|
|
| 145 | + (declare (ignorable function type args))
|
|
| 146 | 146 | (let* ((type (c::continuation-value type))
|
| 147 | 147 | (arg-types (alien-function-type-arg-types type))
|
| 148 | 148 | (result-type (alien-function-type-result-type type)))
|
| 149 | 149 | (assert (= (length arg-types) (length args)))
|
| 150 | - (if (or (some #'(lambda (type)
|
|
| 151 | - (and (alien-integer-type-p type)
|
|
| 152 | - (> (alien::alien-integer-type-bits type) 32)))
|
|
| 153 | - arg-types)
|
|
| 154 | - (and (alien-integer-type-p result-type)
|
|
| 155 | - (> (alien::alien-integer-type-bits result-type) 32)))
|
|
| 156 | - (collect ((new-args) (lambda-vars) (new-arg-types))
|
|
| 157 | - (dolist (type arg-types)
|
|
| 158 | - (let ((arg (gensym)))
|
|
| 159 | - (lambda-vars arg)
|
|
| 160 | - (cond ((and (alien-integer-type-p type)
|
|
| 161 | - (> (alien::alien-integer-type-bits type) 32))
|
|
| 162 | - (new-args `(logand ,arg #xffffffff))
|
|
| 163 | - (new-args `(ash ,arg -32))
|
|
| 164 | - (new-arg-types (parse-alien-type '(unsigned 32)))
|
|
| 165 | - (if (alien-integer-type-signed type)
|
|
| 166 | - (new-arg-types (parse-alien-type '(signed 32)))
|
|
| 167 | - (new-arg-types (parse-alien-type '(unsigned 32)))))
|
|
| 168 | - (t
|
|
| 169 | - (new-args arg)
|
|
| 170 | - (new-arg-types type)))))
|
|
| 171 | - (cond ((and (alien-integer-type-p result-type)
|
|
| 172 | - (> (alien::alien-integer-type-bits result-type) 32))
|
|
| 173 | - (let ((new-result-type
|
|
| 174 | - (let ((alien::*values-type-okay* t))
|
|
| 175 | - (parse-alien-type
|
|
| 176 | - (if (alien-integer-type-signed result-type)
|
|
| 177 | - '(values (unsigned 32) (signed 32))
|
|
| 178 | - '(values (unsigned 32) (unsigned 32)))))))
|
|
| 179 | - `(lambda (function type ,@(lambda-vars))
|
|
| 180 | - (declare (ignore type))
|
|
| 181 | - (multiple-value-bind (low high)
|
|
| 182 | - (%alien-funcall function
|
|
| 183 | - ',(make-alien-function-type
|
|
| 184 | - :arg-types (new-arg-types)
|
|
| 185 | - :result-type new-result-type)
|
|
| 186 | - ,@(new-args))
|
|
| 187 | - (logior low (ash high 32))))))
|
|
| 150 | + (unless (or (some #'(lambda (type)
|
|
| 151 | + (and (alien-integer-type-p type)
|
|
| 152 | + (> (alien::alien-integer-type-bits type) 32)))
|
|
| 153 | + arg-types)
|
|
| 154 | + (and (alien-integer-type-p result-type)
|
|
| 155 | + (/= (alien::alien-integer-type-bits result-type) 32)))
|
|
| 156 | + (c::give-up))
|
|
| 157 | + (collect ((new-args) (lambda-vars) (new-arg-types))
|
|
| 158 | + (dolist (type arg-types)
|
|
| 159 | + (let ((arg (gensym)))
|
|
| 160 | + (lambda-vars arg)
|
|
| 161 | + (cond ((and (alien-integer-type-p type)
|
|
| 162 | + (> (alien::alien-integer-type-bits type) 32))
|
|
| 163 | + (new-args `(logand ,arg #xffffffff))
|
|
| 164 | + (new-args `(ash ,arg -32))
|
|
| 165 | + (new-arg-types (parse-alien-type '(unsigned 32)))
|
|
| 166 | + (if (alien-integer-type-signed type)
|
|
| 167 | + (new-arg-types (parse-alien-type '(signed 32)))
|
|
| 168 | + (new-arg-types (parse-alien-type '(unsigned 32)))))
|
|
| 188 | 169 | (t
|
| 189 | - `(lambda (function type ,@(lambda-vars))
|
|
| 190 | - (declare (ignore type))
|
|
| 191 | - (%alien-funcall function
|
|
| 192 | - ',(make-alien-function-type
|
|
| 193 | - :arg-types (new-arg-types)
|
|
| 194 | - :result-type result-type)
|
|
| 195 | - ,@(new-args))))))
|
|
| 196 | - (c::give-up))))
|
|
| 170 | + (new-args arg)
|
|
| 171 | + (new-arg-types type)))))
|
|
| 172 | + (cond ((and (alien-integer-type-p result-type)
|
|
| 173 | + (< (alien::alien-integer-type-bits result-type) 32))
|
|
| 174 | + (let ((new-result-type
|
|
| 175 | + (parse-alien-type
|
|
| 176 | + (if (alien-integer-type-signed result-type)
|
|
| 177 | + '(signed 32)
|
|
| 178 | + '(unsigned 32)))))
|
|
| 179 | + `(lambda (function type ,@(lambda-vars))
|
|
| 180 | + (declare (ignore type))
|
|
| 181 | + (%alien-funcall function
|
|
| 182 | + ',(make-alien-function-type
|
|
| 183 | + :arg-types (new-arg-types)
|
|
| 184 | + :result-type new-result-type)
|
|
| 185 | + ,@(new-args)))))
|
|
| 186 | + ((and (alien-integer-type-p result-type)
|
|
| 187 | + (> (alien::alien-integer-type-bits result-type) 32))
|
|
| 188 | + (let ((new-result-type
|
|
| 189 | + (let ((alien::*values-type-okay* t))
|
|
| 190 | + (parse-alien-type
|
|
| 191 | + (if (alien-integer-type-signed result-type)
|
|
| 192 | + '(values (unsigned 32) (signed 32))
|
|
| 193 | + '(values (unsigned 32) (unsigned 32)))))))
|
|
| 194 | + `(lambda (function type ,@(lambda-vars))
|
|
| 195 | + (declare (ignore type))
|
|
| 196 | + (multiple-value-bind (low high)
|
|
| 197 | + (%alien-funcall function
|
|
| 198 | + ',(make-alien-function-type
|
|
| 199 | + :arg-types (new-arg-types)
|
|
| 200 | + :result-type new-result-type)
|
|
| 201 | + ,@(new-args))
|
|
| 202 | + (logior low (ash high 32))))))
|
|
| 203 | + (t
|
|
| 204 | + `(lambda (function type ,@(lambda-vars))
|
|
| 205 | + (declare (ignore type))
|
|
| 206 | + (%alien-funcall function
|
|
| 207 | + ',(make-alien-function-type
|
|
| 208 | + :arg-types (new-arg-types)
|
|
| 209 | + :result-type result-type)
|
|
| 210 | + ,@(new-args))))))))
|
|
| 211 | + |
|
| 212 | +(deftransform %alien-funcall ((function type &rest args))
|
|
| 213 | + (assert (c::constant-continuation-p type))
|
|
| 214 | + (apply #'%alien-funcall-aux function type args))
|
|
| 197 | 215 | |
| 198 | 216 | (define-vop (foreign-symbol-code-address)
|
| 199 | 217 | (:translate #+linkage-table foreign-symbol-code-address
|
| ... | ... | @@ -744,7 +744,12 @@ |
| 744 | 744 | ;; set by a prefix instruction
|
| 745 | 745 | (or (disassem:dstate-get-prop dstate 'word-width)
|
| 746 | 746 | *default-operand-size*)))
|
| 747 | - (princ (schar (symbol-name word-width) 0) stream)))))
|
|
| 747 | + ;; Make sure the print case is honored when
|
|
| 748 | + ;; printing out the width.
|
|
| 749 | + (princ (ecase word-width
|
|
| 750 | + (:word 'w)
|
|
| 751 | + (:dword 'd))
|
|
| 752 | + stream)))))
|
|
| 748 | 753 | |
| 749 | 754 | |
| 750 | 755 | ;;;; Disassembler instruction formats.
|
| ... | ... | @@ -23,6 +23,9 @@ public domain. |
| 23 | 23 | * Bug fixes:
|
| 24 | 24 | * Gitlab tickets:
|
| 25 | 25 | * ~~#154~~ piglatin translation does not work anymore
|
| 26 | + * ~~#171~~ Readably print `(make-pathname :name :unspecfic)`
|
|
| 27 | + * ~~#242~~ Fix bug in `alien-funcall` with `c-call:char` as result type
|
|
| 28 | + * ~~#248~~ Print MOVS instruction with correct case
|
|
| 26 | 29 | * Other changes:
|
| 27 | 30 | * Improvements to the PCL implementation of CLOS:
|
| 28 | 31 | * Changes to building procedure:
|
| ... | ... | @@ -1593,8 +1593,8 @@ msgstr "" |
| 1593 | 1593 | msgid ""
|
| 1594 | 1594 | "Returns T if X and Y are EQL or if they are structured components\n"
|
| 1595 | 1595 | " whose elements are EQUAL. Strings and bit-vectors are EQUAL if they\n"
|
| 1596 | -" are the same length and have indentical components. Other arrays must be\n"
|
|
| 1597 | -" EQ to be EQUAL."
|
|
| 1596 | +" are the same length and have identical components. Other arrays\n"
|
|
| 1597 | +" must be EQ to be EQUAL."
|
|
| 1598 | 1598 | msgstr ""
|
| 1599 | 1599 | |
| 1600 | 1600 | #: src/code/pred.lisp
|
| ... | ... | @@ -9148,6 +9148,12 @@ msgstr "" |
| 9148 | 9148 | msgid "~&Could not find external format ~S~%"
|
| 9149 | 9149 | msgstr ""
|
| 9150 | 9150 | |
| 9151 | +#: src/code/extfmts.lisp
|
|
| 9152 | +msgid ""
|
|
| 9153 | +"List of external formats that are builtin so that they don't need to\n"
|
|
| 9154 | +" be loaded on first use."
|
|
| 9155 | +msgstr ""
|
|
| 9156 | + |
|
| 9151 | 9157 | #: src/code/extfmts.lisp
|
| 9152 | 9158 | msgid "External-format aliasing depth exceeded."
|
| 9153 | 9159 | msgstr ""
|
| ... | ... | @@ -9288,6 +9294,13 @@ msgid "" |
| 9288 | 9294 | "replacement character."
|
| 9289 | 9295 | msgstr ""
|
| 9290 | 9296 | |
| 9297 | +#: src/code/extfmts.lisp
|
|
| 9298 | +msgid ""
|
|
| 9299 | +"US ASCII 7-bit encoding. Illegal input sequences are replaced with\n"
|
|
| 9300 | +"the Unicode replacment character. Illegal output characters are\n"
|
|
| 9301 | +"replaced with a question mark."
|
|
| 9302 | +msgstr ""
|
|
| 9303 | + |
|
| 9291 | 9304 | #: src/code/fd-stream.lisp
|
| 9292 | 9305 | msgid ""
|
| 9293 | 9306 | "List of available buffers. Each buffer is an sap pointing to\n"
|
| ... | ... | @@ -21325,12 +21338,6 @@ msgstr "" |
| 21325 | 21338 | msgid " Gray Streams Protocol Support"
|
| 21326 | 21339 | msgstr ""
|
| 21327 | 21340 | |
| 21328 | -msgid ""
|
|
| 21329 | -"US ASCII 7-bit encoding. Illegal input sequences are replaced with\n"
|
|
| 21330 | -"the Unicode replacment character. Illegal output characters are\n"
|
|
| 21331 | -"replaced with a question mark."
|
|
| 21332 | -msgstr ""
|
|
| 21333 | - |
|
| 21334 | 21341 | msgid ""
|
| 21335 | 21342 | "MAC-ROMAN is an 8-bit character encoding for Western European\n"
|
| 21336 | 21343 | "languages including English.\n"
|
| ... | ... | @@ -997,3 +997,111 @@ |
| 997 | 997 | ;; This is the condition from the CLHS entry for enough-namestring
|
| 998 | 998 | (assert-equal (merge-pathnames enough defaults)
|
| 999 | 999 | (merge-pathnames (parse-namestring pathname nil defaults) defaults))))))
|
| 1000 | + |
|
| 1001 | +(define-test issue.242-load-foreign
|
|
| 1002 | + ;; load-foreign apparently returns NIL if it succeeds.
|
|
| 1003 | + (assert-true (eql nil (ext:load-foreign (merge-pathnames "test-return.o" *test-path*)))))
|
|
| 1004 | + |
|
| 1005 | +(alien:def-alien-variable "test_arg" c-call:int)
|
|
| 1006 | + |
|
| 1007 | +(define-test issue.242.test-alien-return-signed-char
|
|
| 1008 | + (:tag :issues)
|
|
| 1009 | + (flet ((fun (n)
|
|
| 1010 | + (setf test-arg n)
|
|
| 1011 | + (alien:alien-funcall
|
|
| 1012 | + (alien:extern-alien "int_to_signed_char"
|
|
| 1013 | + (function c-call:char))))
|
|
| 1014 | + (sign-extend (n)
|
|
| 1015 | + (let ((n (ldb (byte 8 0) n)))
|
|
| 1016 | + (if (> n #x7f)
|
|
| 1017 | + (- n #x100)
|
|
| 1018 | + n))))
|
|
| 1019 | + (dolist (x '(99 -99 1023 -1023))
|
|
| 1020 | + (assert-equal (sign-extend x) (fun x) x))))
|
|
| 1021 | + |
|
| 1022 | +(define-test issue.242.test-alien-return-signed-short
|
|
| 1023 | + (:tag :issues)
|
|
| 1024 | + (flet ((fun (n)
|
|
| 1025 | + (setf test-arg n)
|
|
| 1026 | + (alien:alien-funcall
|
|
| 1027 | + (alien:extern-alien "int_to_short"
|
|
| 1028 | + (function c-call:short))))
|
|
| 1029 | + (sign-extend (n)
|
|
| 1030 | + (let ((n (ldb (byte 16 0) n)))
|
|
| 1031 | + (if (> n #x7fff)
|
|
| 1032 | + (- n #x10000)
|
|
| 1033 | + n))))
|
|
| 1034 | + (dolist (x '(1023 -1023 100000 -100000))
|
|
| 1035 | + (assert-equal (sign-extend x) (fun x) x))))
|
|
| 1036 | + |
|
| 1037 | +(define-test issue.242.test-alien-return-signed-int
|
|
| 1038 | + (:tag :issues)
|
|
| 1039 | + (flet ((fun (n)
|
|
| 1040 | + (setf test-arg n)
|
|
| 1041 | + (alien:alien-funcall
|
|
| 1042 | + (alien:extern-alien "int_to_int"
|
|
| 1043 | + (function c-call:int)))))
|
|
| 1044 | + (dolist (x '(1023 -1023 #x7fffffff #x-80000000))
|
|
| 1045 | + (assert-equal x (fun x) x))))
|
|
| 1046 | + |
|
| 1047 | +(define-test issue.242.test-alien-return-unsigned-char
|
|
| 1048 | + (:tag :issues)
|
|
| 1049 | + (flet ((fun (n)
|
|
| 1050 | + (setf test-arg n)
|
|
| 1051 | + (alien:alien-funcall
|
|
| 1052 | + (alien:extern-alien "int_to_unsigned_char"
|
|
| 1053 | + (function c-call:unsigned-char))))
|
|
| 1054 | + (expected (n)
|
|
| 1055 | + (ldb (byte 8 0) n)))
|
|
| 1056 | + (dolist (x '(99 -99 1023 -1023))
|
|
| 1057 | + (assert-equal (expected x) (fun x) x))))
|
|
| 1058 | + |
|
| 1059 | +(define-test issue.242.test-alien-return-unsigned-short
|
|
| 1060 | + (:tag :issues)
|
|
| 1061 | + (flet ((fun (n)
|
|
| 1062 | + (setf test-arg n)
|
|
| 1063 | + (alien:alien-funcall
|
|
| 1064 | + (alien:extern-alien "int_to_unsigned_short"
|
|
| 1065 | + (function c-call:unsigned-short))))
|
|
| 1066 | + (expected (n)
|
|
| 1067 | + (ldb (byte 16 0) n)))
|
|
| 1068 | + (dolist (x '(1023 -1023 100000 -100000))
|
|
| 1069 | + (assert-equal (expected x) (fun x) x))))
|
|
| 1070 | + |
|
| 1071 | +(define-test issue.242.test-alien-return-unsigned-int
|
|
| 1072 | + (:tag :issues)
|
|
| 1073 | + (flet ((fun (n)
|
|
| 1074 | + (setf test-arg n)
|
|
| 1075 | + (alien:alien-funcall
|
|
| 1076 | + (alien:extern-alien "int_to_unsigned_int"
|
|
| 1077 | + (function c-call:unsigned-int))))
|
|
| 1078 | + (expected (n)
|
|
| 1079 | + (ldb (byte 32 0) n)))
|
|
| 1080 | + (dolist (x '(1023 -1023 #x7fffffff #x-80000000))
|
|
| 1081 | + (assert-equal (expected x) (fun x) x))))
|
|
| 1082 | + |
|
| 1083 | +(define-test issue.242.test-alien-return-bool
|
|
| 1084 | + (:tag :issues)
|
|
| 1085 | + (flet ((fun (n)
|
|
| 1086 | + (setf test-arg n)
|
|
| 1087 | + (alien:alien-funcall
|
|
| 1088 | + (alien:extern-alien "int_to_bool"
|
|
| 1089 | + (function c-call:char))))
|
|
| 1090 | + (expected (n)
|
|
| 1091 | + (if (zerop n)
|
|
| 1092 | + 0
|
|
| 1093 | + 1)))
|
|
| 1094 | + (dolist (x '(0 1 1000))
|
|
| 1095 | + (assert-equal (expected x) (fun x) x))))
|
|
| 1096 | + |
|
| 1097 | +(define-test issue.242.test-alien-return-bool.2
|
|
| 1098 | + (:tag :issues)
|
|
| 1099 | + (flet ((fun (n)
|
|
| 1100 | + (setf test-arg n)
|
|
| 1101 | + (alien:alien-funcall
|
|
| 1102 | + (alien:extern-alien "int_to_bool"
|
|
| 1103 | + (function alien:boolean))))
|
|
| 1104 | + (expected (n)
|
|
| 1105 | + (not (zerop n))))
|
|
| 1106 | + (dolist (x '(0 1 1000))
|
|
| 1107 | + (assert-equal (expected x) (fun x) x)))) |
| ... | ... | @@ -83,3 +83,31 @@ |
| 83 | 83 | and type = (pathname-type f)
|
| 84 | 84 | do
|
| 85 | 85 | (assert-true (and (null name) (null type)) f))))
|
| 86 | + |
|
| 87 | + |
|
| 88 | + |
|
| 89 | +;; Test that pathnames with :unspecific components are printed using
|
|
| 90 | +;; our extension to make :unspecific explicit.
|
|
| 91 | +(define-test issue.171.unspecific
|
|
| 92 | + (:tag :issues)
|
|
| 93 | + (flet ((output (path)
|
|
| 94 | + (with-output-to-string (s)
|
|
| 95 | + (write path :stream s))))
|
|
| 96 | + (dolist (test
|
|
| 97 | + (list
|
|
| 98 | + (list (make-pathname :name "foo" :type :unspecific)
|
|
| 99 | + "#P(:NAME \"foo\" :TYPE :UNSPECIFIC)"
|
|
| 100 | + "foo")
|
|
| 101 | + (list (make-pathname :name :unspecific :type "foo")
|
|
| 102 | + "#P(:NAME :UNSPECIFIC :TYPE \"foo\")"
|
|
| 103 | + ".foo")
|
|
| 104 | + (list (make-pathname :name "foo" :type "txt" :version :unspecific)
|
|
| 105 | + "#P(:NAME \"foo\" :TYPE \"txt\" :VERSION :UNSPECIFIC)"
|
|
| 106 | + "foo.txt")
|
|
| 107 | + (list (make-pathname :device :unspecific)
|
|
| 108 | + "#P(:DEVICE :UNSPECIFIC)"
|
|
| 109 | + "")))
|
|
| 110 | + (destructuring-bind (pathname printed-value namestring)
|
|
| 111 | + test
|
|
| 112 | + (assert-equal printed-value (output pathname))
|
|
| 113 | + (assert-equal namestring (namestring pathname)))))) |
| 1 | +#include <stdbool.h>
|
|
| 2 | + |
|
| 3 | +int test_arg;
|
|
| 4 | + |
|
| 5 | +signed char
|
|
| 6 | +int_to_signed_char()
|
|
| 7 | +{
|
|
| 8 | + return (signed char) test_arg;
|
|
| 9 | +}
|
|
| 10 | + |
|
| 11 | +short
|
|
| 12 | +int_to_short()
|
|
| 13 | +{
|
|
| 14 | + return (short) test_arg;
|
|
| 15 | +}
|
|
| 16 | + |
|
| 17 | +int
|
|
| 18 | +int_to_int()
|
|
| 19 | +{
|
|
| 20 | + return (int) test_arg;
|
|
| 21 | +}
|
|
| 22 | + |
|
| 23 | +unsigned char
|
|
| 24 | +int_to_unsigned_char()
|
|
| 25 | +{
|
|
| 26 | + return (unsigned char) test_arg;
|
|
| 27 | +}
|
|
| 28 | + |
|
| 29 | +unsigned short
|
|
| 30 | +int_to_unsigned_short()
|
|
| 31 | +{
|
|
| 32 | + return (unsigned short) test_arg;
|
|
| 33 | +}
|
|
| 34 | + |
|
| 35 | +unsigned int
|
|
| 36 | +int_to_unsigned_int()
|
|
| 37 | +{
|
|
| 38 | + return (unsigned int) test_arg;
|
|
| 39 | +}
|
|
| 40 | + |
|
| 41 | +_Bool int_to_bool()
|
|
| 42 | +{
|
|
| 43 | + return (_Bool) test_arg;
|
|
| 44 | +}
|
|
| 45 | + |