Changeset 429
- Timestamp:
- Jan 30, 2004, 11:48:10 AM (21 years ago)
- File:
-
- 1 edited
-
trunk/ccl/examples/bridge.lisp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/examples/bridge.lisp
r187 r429 351 351 #'(lambda (m c) 352 352 (declare (ignore c)) 353 (#+gnu-objc progn #+apple-objc ignore-errors353 (#+gnu-objc progn #+apple-objc progn 354 354 ;; Some libraries seem to have methods with bogus-looking 355 355 ;; type signatures … … 386 386 (error "Improperly formatted structure typestring: ~S" typestring)) 387 387 (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 393 439 (defun objc-foreign-arg-type (str) 394 440 (case (schar str 0) … … 413 459 (#\b (error "ObjC BITFIELD not yet supported")) 414 460 (#\[ (error "OjbC ARRAY not yet supported")) 415 (#\{ (extract-foreign-struct-name str))461 (#\{ `(:struct ,(extract-foreign-struct-name str))) 416 462 (#\( (error "ObjC UNION type not yet supported")) 417 463 (#\? t) 418 464 ((#\r #\R #\o #\O #\n #\N #\V) (objc-foreign-arg-type (subseq str 1))) 419 465 (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 420 530 421 531
Note:
See TracChangeset
for help on using the changeset viewer.
