Changeset 429


Ignore:
Timestamp:
Jan 30, 2004, 11:48:10 AM (21 years ago)
Author:
Gary Byers
Message:

Parse instance-var type strings differently from arg type strings.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/examples/bridge.lisp

    r187 r429  
    351351   #'(lambda (m c)
    352352       (declare (ignore c))
    353        (#+gnu-objc progn #+apple-objc ignore-errors
     353       (#+gnu-objc progn #+apple-objc progn
    354354         ;; Some libraries seem to have methods with bogus-looking
    355355         ;; type signatures
     
    386386        (error "Improperly formatted structure typestring: ~S" typestring))
    387387      (escape-foreign-name
    388        (subseq typestring (if (eql (schar typestring 1) #\_) 2 1) =pos)))))
    389 
    390 
    391 ;;; Return the foreign type spec corresponding to the ObjC type string STR
    392        
     388       (subseq typestring 1 =pos)))))
     389
     390(defun parse-foreign-struct-or-union-spec (typestring startpos record-class)
     391  (flet ((extract-record-name (startpos delimpos)
     392           (unless (and (= delimpos (1+ startpos))
     393                        (eq (schar typestring startpos) #\?))
     394             (escape-foreign-name (subseq typestring startpos delimpos)))))
     395    (let ((=pos (position #\= typestring :start startpos))
     396          (end-char (if (eq record-class :struct) #\} #\))))
     397      (if (null =pos)
     398        ;; It's optional: everything between the delimiters is the record
     399        ;; name, and no fields are specified.
     400        (let* ((end-pos (position end-char typestring :start startpos)))
     401          (if (null end-pos)
     402            (error "Improperly formatted structure/union typestring: ~S"
     403                   typestring)
     404            (values `(,record-class ,(extract-record-name startpos end-pos))
     405                    (1+ end-pos))))
     406        (let* ((record-name (extract-record-name startpos =pos))
     407               (string-stream-start (1+ =pos))
     408               (string-stream
     409                (make-string-input-stream typestring string-stream-start)))
     410          (collect ((fields))
     411            (do* ()
     412                 ((eql (peek-char nil string-stream) end-char)
     413                  (values
     414                   (if (and record-name (load-record record-name))
     415                     `(,record-class ,record-name)
     416                     `(,record-class ,record-name ,@(fields)))
     417                   (1+ (string-input-stream-index string-stream))))
     418              (let* ((field-name-string (read string-stream)))
     419                (if (eql (peek-char nil string-stream) #\")
     420                  (setq field-name-string (read string-stream)))
     421                (unless (typep field-name-string 'string)
     422                  (error "Bad field name in ~s: expected a quoted string, got ~s"
     423                         typestring field-name-string))
     424                (multiple-value-bind (typespec endpos)
     425                    (objc-foreign-type-for-ivar
     426                     typestring
     427                     (string-input-stream-index string-stream)
     428                     nil)
     429                  (fields `(,(escape-foreign-name field-name-string)
     430                            ,typespec))
     431                  (setf (string-input-stream-index string-stream) endpos))))))))))
     432               
     433
     434
     435;;; Return the foreign type spec corresponding to the ObjC type string STR.
     436;;; Things are encoded differently for instance variables than for method
     437;;; arguments.
     438
    393439(defun objc-foreign-arg-type (str)
    394440    (case (schar str 0)
     
    413459      (#\b (error "ObjC BITFIELD not yet supported"))
    414460      (#\[ (error "OjbC ARRAY not yet supported"))
    415       (#\{ (extract-foreign-struct-name str))
     461      (#\{ `(:struct ,(extract-foreign-struct-name str)))
    416462      (#\( (error "ObjC UNION type not yet supported"))
    417463      (#\? t)
    418464      ((#\r #\R #\o #\O #\n #\N #\V) (objc-foreign-arg-type (subseq str 1)))
    419465      (t (error "Unrecognized ObjC type string: ~S" str))))
     466
     467;;; Parse the ivar's type string and return a FOREIGN-TYPE object.
     468(defun objc-foreign-type-for-ivar
     469    (str &optional (startpos 0) (allow-id-name t))
     470  (let* ((endpos (1+ startpos))
     471         (startchar (schar str startpos))
     472         (spec
     473          (case startchar
     474            (#\c :char)
     475            (#\C :unsigned-byte)
     476            (#\s :signed-halfword)
     477            (#\S :unsigned-halfword)
     478            (#\i :signed-fullword)
     479            (#\I :unsigned-fullword)
     480            (#\l :signed-fullword)
     481            (#\L :unsigned-fullword)
     482            (#\q :signed-doubleword)
     483            (#\Q :unsigned-doubleword)
     484            (#\f :single-float)
     485            (#\d :double-float)
     486            (#\v :void)
     487            (#\@ (when allow-id-name
     488                   (let* ((nextpos (1+ startpos)))
     489                   (if (and (< nextpos (length str))
     490                            (eq (schar str nextpos) #\"))
     491                     (let* ((end (position #\" str :start (1+ nextpos))))
     492                       (unless end
     493                         (error "Missing double-quote in ~s" str))
     494                       (setq endpos (1+ end))))))
     495                 :id)
     496            (#\: :<sel>)
     497            (#\# '(:* (:struct :objc_class)))
     498            (#\* '(:* :char))
     499            (#\^ (multiple-value-bind (type end)
     500                     (objc-foreign-type-for-ivar str (1+ startpos) t)
     501                   (setq endpos end)
     502                   `(:* ,type)))
     503            (#\b (multiple-value-bind (n end)
     504                     (parse-integer str :start (1+ startpos) :junk-allowed t )
     505                   (setq endpos end)
     506                   `(:bitfield ,n)))
     507            (#\[ (multiple-value-bind (size size-end)
     508                     (parse-integer str :start (1+ startpos) :junk-allowed t)
     509                   (multiple-value-bind (element-type end)
     510                       (objc-foreign-type-for-ivar str size-end t)
     511                     (unless (eq (schar str end) #\])
     512                       (error "No closing ] in array typespec: ~s" str))
     513                     (setq endpos (1+ end))
     514                     `(:array ,element-type ,size))))
     515            ((#\{ #\()
     516             (multiple-value-bind (type end)
     517                 (parse-foreign-struct-or-union-spec
     518                  str (1+ startpos) (if (eq startchar #\{)
     519                                      :struct
     520                                      :union))
     521               (setq endpos end)
     522               type))
     523            (#\? t)
     524            ((#\r #\R #\o #\O #\n #\N #\V)
     525             (return-from objc-foreign-type-for-ivar
     526               (objc-foreign-type-for-ivar str (1+ startpos) allow-id-name)))
     527            (t (error "Unrecognized ObjC type string: ~S/~d" str startpos)))))
     528    (values spec endpos)))
     529         
    420530
    421531
Note: See TracChangeset for help on using the changeset viewer.