1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
;;;; Objective-CL, an Objective-C bridge for Common Lisp.
;;;; Copyright (C) 2007 Matthias Andreas Benkard.
;;;;
;;;; This program is free software: you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public License
;;;; as published by the Free Software Foundation, either version 3 of
;;;; the License, or (at your option) any later version.
;;;;
;;;; This program 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
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with this program. If not, see
;;;; <http://www.gnu.org/licenses/>.
(in-package #:mulk.objective-cl)
(defun define-returns-boolean-exception (selector-designator)
"Define an exception to the rule that `char` means `BOOL` as a method return type.
## Arguments and Values:
*selector-designator* --- a *selector designator*.
## Description:
Normally, Objective-C treats method return values that are nominally of
type `char` as booleans and converts them to either __t__ or __nil__
depending on whether they are __zerop__.
__define-returns-boolean-exception__ directs Objective-CL to treat
`char` values returned by methods named by *selector-designator* as
numbers instead.
__undefine-returns-boolean-exception__ restores the default behaviour.
## Examples:
(define-returns-boolean-exception \"charValue\")
(define-returns-boolean-exception \"characterAtIndex:\")
## Rationale:
The Objective-C runtime offers no way of distinguishing booleans from
chars, even though Foundation defines a `BOOL` type. In the vast
majority of cases, `char` therefore actually means `BOOL`, but the
`NSString` class, for one, wouldn't always agree with that sentiment, so
the only sane way of handling both booleans and actual `char` values is
to determine the intentional type by method selector.
## See also:
__undefine-returns-boolean-exception__"
(let ((key (typecase selector-designator
(string selector-designator)
(t (selector-name (selector selector-designator))))))
(setf (gethash key *boolean-return-exceptions*) t)))
(defun undefine-returns-boolean-exception (selector-designator)
"Revert the effect of __define-returns-boolean-exception__ for a given selector.
## Arguments and Values:
*selector-designator* --- a *selector designator*.
## Description:
Normally, Objective-C treats method return values that are nominally of
type `char` as booleans and converts them to either __t__ or __nil__
depending on whether they are __zerop__.
__define-returns-boolean-exception__ directs Objective-CL to treat
`char` values returned by methods named by *selector-designator* as
numbers instead.
__undefine-returns-boolean-exception__ restores the default behaviour.
## Examples:
(undefine-returns-boolean-exception \"boolValue\")
(undefine-returns-boolean-exception \"isEqual:\")
## Rationale:
The Objective-C runtime offers no way of distinguishing booleans from
chars, even though Foundation defines a `BOOL` type. In the vast
majority of cases, `char` therefore actually means `BOOL`, but the
`NSString` class, for one, wouldn't always agree with that sentiment, so
the only sane way of handling both booleans and actual `char` values is
to determine the intentional type by method selector.
## See also:
__define-returns-boolean-exception__"
(let ((key (typecase selector-designator
(string selector-designator)
(t (selector-name (selector selector-designator))))))
(remhash key *boolean-return-exceptions*)))
(define-returns-boolean-exception "charValue")
(define-returns-boolean-exception "characterAtIndex:")
(defun returned-char-is-bool-p (receiver selector)
(declare (ignore receiver))
(gethash (selector-name selector) *boolean-return-exceptions* nil))
(defun objc-char->lisp-value (objc-char char-is-bool-p)
(if char-is-bool-p
objc-char
(not (zerop objc-char))))
|