Previous Section Next Chapter Table of Contents Glossary Index

Chapter 15. Platform-specific notes

15.6. Operating-System Dictionary

[Function]

getenv name => value

Arguments and Values:

name---a string which is the name of an existing environment variable; case-sensitive

value---if there is an environment variable named name, its value, as a string; if there is not, NIL

Description:

Looks up the value of the environment variable named by name, in the OS environment.

[Function]

setenv name value => errno

Arguments and Values:

name---a string which is the name of a new or existing environment variable; case-sensitive

value---a string, to be the new value of the environment variable named by name

errno---zero if the function call completes successfully; otherwise, a platform-dependent integer which describes the problem

Description:

Sets the value of the environment variable named by name, in the OS environment. If there is no such environment variable, creates it.

[Function]

current-directory-name => path

Values:

path---a string, an absolute pathname in Posix format - with directory components separated by slashes

Description:

Looks up the current working directory of the Clozure CL process; unless it has been changed, this is the directory Clozure CL was started in.

[Function]

getuid => uid

Values:

uid---a non-negative integer, identifying a specific user account as defined in the OS user database

Description:

Returns the ("real") user ID of the current user.

[Function]

setuid uid => errno

Arguments and Values:

uid---a non-negative integer, identifying a specific user account as defined in the OS user database

errno---zero if the function call completes successfully; otherwise, a platform-dependent integer which describes the problem

Description:

Attempts to change the current user ID (both "real" and "effective"); fails unless the Clozure CL process has super-user privileges or the ID given is that of the current user.

[Function]

setgid gid => errno

Arguments and Values:

gid---a non-negative integer, identifying a specific group as defined in the OS user database

errno---zero if the function call completes successfully; otherwise, a platform-dependent integer which describes the problem

Description:

Attempts to change the current group ID (both "real" and "effective"); fails unless the Clozure CL process has super-user privileges or the ID given is that of a group to which the current user belongs.

[Function]

getpid => pid

Values:

pid---a non-negative integer, identifying an OS process

Description:

Returns the ID of the Clozure CL OS process.

[Function]

get-user-home-dir uid => path

Values:

uid---a non-negative integer, identifying a specific user account as defined in the OS user database

path---a string, an absolute pathname in Posix format - with directory components separated by slashes; or NIL

Description:

Looks up and returns the defined home directory of the user identified by uid. This value comes from the OS user database, not from the $HOME environment variable. Returns NIL if there is no user with the ID uid.

[Function]

os-command command-line => exit-code

Values:

command-line---a string, obeying all the whitespace and escaping conventions required by the user's default system shell

exit-code---a non-negative integer, returned as the exit code of a subprocess; zero indicates success

Description:

Invokes the Posix function system(), which invokes the user's default system shell (such as sh or tcsh) as a new process, and has that shell execute command-line.

If the shell was able to find the command specified in command-line, then exit-code is the exit code of that command. If not, it is the exit code of the shell itself.

Notes:

By convention, an exit code of 0 indicates success. There are also other conventions; unfortunately, they are OS-specific, and the portable macros to decode their meaning are implemented by the system headers as C preprocessor macros. This means that there is no good, automated way to make them available to Lisp.

[Macro]

@class class-name

Arguments and Values:

class-name---a string which denotes an existing class name, or a symbol which can be mapped to such a string via the standard name-mapping conventions for class names

Description:

Used to refer to a known ObjC class by name. (Via the use LOAD-TIME-VALUE, the results of a class-name -> class lookup are cached.)

@class is obsolete as of late 2004, because find-class now works on ObjC classes. It is described here only because some old code still uses it.

[Macro]

@selector string

Arguments and Values:

string---a string constant, used to canonically refer to an ObjC method selector

Description:

Used to refer to an ObjC method selector (method name). Uses LOAD-TIME-VALUE to cache the result of a string -> selector lookup.

[Macro]

objc:defmethod name-and-result-type ((receiver-arg-and-class) &rest other-args) &body body

Arguments and Values:

name-and-result-type---either an Objective-C message name, for methods that return a value of type :ID, or a list containing an Objective-C message name and a foreign type specifier for methods with a different foreign result type.

receiver-arg-and-class---a two-element list whose first element is a variable name and whose second element is the Lisp name of an Objective-C class or metaclass. The receiver variable name can be any bindable lisp variable name, but SELF might be a reasonable choice. The receiver variable is declared to be "unsettable"; i.e., it is an error to try to change the value of the receiver in the body of the method definition.

other-args---either variable names (denoting parameters of type :ID) or 2-element lists whose first element is a variable name and whose second element is a foreign type specifier.

Description:

Defines an Objective-C-callable method which implements the specified message selector for instances of the existing named Objective-C class.

For a detailed description of the features and restrictions of the OBJC:DEFMETHOD macro, see the section Using objc:defmethod.

[Macro]

define-objc-method (selector class-name) &body body

Arguments and Values:

selector---either a string which represents the name of the selector or a list which describes the method's return type, selector components, and argument types (see below.) If the first form is used, then the first form in the body must be a list which describes the selector's argument types and return value type, as per DEFCALLBACK.

class-name---either a string which names an existing ObjC class name or a list symbol which can map to such a string via the standard name-mapping conventions for class names. (Note that the "canonical" lisp class name is such a symbol)

Description:

Defines an ObjC-callable method which implements the specified message selector for instances of the existing ObjC class class-name.

[Macro]

define-objc-class-method (selector class-name) &body body

Arguments and Values:

As per DEFINE-OBJC-METHOD

Description:

Like DEFINE-OBJC-METHOD, only used to define methods on the class named by class-name and on its subclasses.

For both DEFINE-OBJC-METHOD and DEFINE-OBJC-CLASS-METHOD, the "selector" argument can be a list whose first element is a foreign type specifier for the method's return value type and whose subsequent elements are either:

  • a non-keyword symbol, which can be mapped to a selector string for a parameterless method according to the standard name-mapping conventions for method selectors.

  • a list of alternating keywords and variable/type specifiers, where the set of keywords can be mapped to a selector string for a parameterized method according to the standard name-mapping conventions for method selectors and each variable/type-specifier is either a variable name (denoting a value of type :ID) or a list whose CAR is a variable name and whose CADR is the corresponding argument's foreign type specifier.

[Variable]

CCL:*ALTERNATE-LINE-TERMINATOR*

Description:

This variable is currently only used by the standard reader macro function for #\; (single-line comments); that function reads successive characters until EOF, a #\NewLine is read, or a character EQL to the value of *alternate-line-terminator* is read. In Clozure CL for Darwin, the value of this variable is initially #\Return ; in Clozure CL for other OSes, it's initially NIL.

Their default treatment by the #\; reader macro is the primary way in which #\Return and #\Linefeed differ syntactically; by extending the #\; reader macro to (conditionally) treat #\Return as a comment-terminator, that distinction is eliminated. This seems to make LOAD and COMPILE-FILE insensitive to line-termination issues in many cases. It could fail in the (hopefully rare) case where a LF-terminated (Unix) text file contains embedded #\Return characters, and this mechanism isn't adequate to handle cases where newlines are embedded in string constants or other tokens (and presumably should be translated from an external convention to the external one) : it doesn't change what READ-CHAR or READ-LINE "see", and that may be necessary to handle some more complicated cases.

[Class]

CCL::NS-LISP-STRING

Superclasses:

NS:NS-STRING

Initargs:

:string--- a Lisp string which is to be the content of the newly-created ns-lisp-string.

Description:

This class implements the interface of an NSString, which means that it can be passed to any Cocoa or Core Foundation function which expects one.

The string itself is stored on the Lisp heap, which means that its memory management is automatic. However, the ns-lisp-string object itself is a foreign object (that is, it has an objc metaclass), and resides on the foreign heap. Therefore, it is necessary to explicitly free it, by sending a dealloc message.

Examples:

You can create an ns-lisp-string with make-instance, just like any normal Lisp class:

? (defvar *the-string*
     (make-instance 'ccl::ns-lisp-string
                    :string "Hello, Cocoa."))

When you are done with the string, you must explicitly deallocate it:

? (ccl::send *the-string* 'dealloc)

You may wish to use an unwind-protect form to ensure that this happens:

(let (*the-string*)
  (unwind-protect (progn (setq *the-string*
                               (make-instance 'ccl::ns-lisp-string
                                              :string "Hello, Cocoa."))
                         (format t "~&The string is ~D characters long.~%"
                                 (ccl::send *the-string* 'length)))
    (when *the-string*
      (ccl::send *the-string* 'dealloc))))
Notes:

Currently, ns-lisp-string is defined in the file ccl/examples/cocoa-backtrace.lisp, which is a rather awkward place. It was probably not originally meant as a public utility at all. It would be good if it were moved someplace else. Use at your own risk.


Previous Section Next Chapter Table of Contents Glossary Index