source: trunk/source/doc/src/platform-notes.xml @ 8981

Last change on this file since 8981 was 8981, checked in by mikel, 11 years ago

additions to ObjC and ffi docs; many mechanical edits; some standardization of XML elements and formatting

File size: 47.3 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
3          <!ENTITY rest "<varname>&amp;rest</varname>">
4          <!ENTITY key "<varname>&amp;key</varname>">
5          <!ENTITY optional "<varname>&amp;optional</varname>">
6          <!ENTITY body "<varname>&amp;body</varname>">
7          <!ENTITY aux "<varname>&amp;aux</varname>">
8          <!ENTITY allow-other-keys "<varname>&amp;allow-other-keys</varname>">
9          <!ENTITY CCL "Clozure CL">
10          ]>
11
12<chapter id="Platform-specific-notes">
13  <title>Platform-specific notes</title>
14 
15
16  <sect1 id="Platform-specific-overview">
17    <title>Overview</title>
18    <para> The documentation and whatever experience you may have in
19      using &CCL; under Linux should also apply to using it under
20      Darwin/MacOS X and FreeBSD. There are some differences between
21      the platforms, and these differences are sometimes exposed in
22      the implementation.</para>
23
24    <sect2 id="differences-between-32-bit-and-64-bit-implementations">
25          <title>Differences Between 32-bit and 64-bit implementations</title>
26
27          <para>Fixnums on 32-bit systems use 30 bits and are in the
28            range XXX through YYY.  Fixnums on 64-bit systems use 61-bits
29            and are in the range XXX through YYY. (see <xref
30                                                          linkend="Tagging-scheme"/>)</para>
31
32          <para>Since we have much larger fixnums on 64-bit systems,
33            <varname>INTERNAL-TIME-UNITS-PER-SECOND</varname> is 1000000
34            on 64-bit systems but remains 1000 on 32-bit systems.  This
35            enables much finer grained timing on 64-bit systems.</para>
36    </sect2>
37
38    <sect2 id="File-system-case">
39          <title>File-system case</title>
40
41          <para>Darwin and MacOS X use HFS+ file systems by default;
42            HFS+ file systems are usually case-insensitive. Most of
43            &CCL;'s filesystem and pathname code assumes that the
44            underlying filesystem is case-sensitive; this assumption
45            extends to functions like EQUAL, which assumes that #p"FOO"
46            and #p"foo" denote different, un-EQUAL filenames. Since
47            Darwin/MacOS X can also use UFS and NFS filesystems, the
48            opposite assumption would be no more correct than the one
49            that's currently made.</para>
50      <para>Whatever the best solution to this problem turns out to
51        be, there are some practical considerations. Doing:</para>
52      <programlisting>
53? (save-application "DPPCCL")
54          </programlisting>
55      <para>on 32-bit DarwinPPC has the unfortunate side-effect of
56        trying to overwrite the Darwin &CCL; kernel, "dppccl", on a
57        case-insensitive filesystem.</para>
58      <para>To work around this, the Darwin &CCL; kernel expects
59        the default heap image file name to be the kernel's own
60        filename with the string ".image" appended, so the idiom would
61        be:</para>
62      <programlisting>
63? (save-application "dppccl.image")
64          </programlisting>
65    </sect2>
66
67    <sect2 id="Line-Termination-Characters">
68          <title>Line Termination Characters</title>
69      <para>MacOSX effectively supports two distinct line-termination
70            conventions. Programs in its Darwin substrate follow the Unix
71            convention of recognizing #\LineFeed as a line terminator; traditional
72            MacOS programs use #\Return for this purpose.  Many modern
73            GUI programs try to support several different line-termination
74            conventions (on the theory that the user shouldn't be too concerned
75            about what conventions are used an that it probably doesn't matter.
76            Sometimes this is true, other times ... not so much.
77          </para>
78      <para>&CCL; follows the Unix convention on both Darwin and
79        LinuxPPC, but offers some support for reading and writing
80        files that use other conventions (including traditional MacOS
81        conventions) as well.</para> 
82          <para>This support (and anything like it) is by nature
83            heuristic: it can successfully hide the distinction between
84            newline conventions much of the time, but could mistakenly
85            change the meaning of otherwise correct programs (typically
86            when files contain both #\Return and #\Linefeed characters or
87            when files contain mixtures of text and binary data.) Because
88            of this concern, the default settings of some of the variables
89            that control newline translation and interpretation are
90            somewhat conservative.</para>
91          <para>Although the issue of multiple newline conventions
92            primarily affects MacOSX users, the functionality described
93            here is available under LinuxPPC as well (and may occasionally
94            be useful there.)</para> <para>None of this addresses issues
95            related to the third newline convention ("CRLF") in widespread
96            use (since that convention isn't native to any platform on
97            which &CCL; currently runs). If &CCL; is ever ported to
98            such a platform, that issue might be revisited.</para>
99          <para>Note that some MacOS programs (including some versions
100            of commercial MCL) may use HFS file type information to
101            recognize TEXT and other file types and so may fail to
102            recognize files created with &CCL; or other Darwin
103            applications (regardless of line termination issues.)</para>
104          <para>Unless otherwise noted, the symbols mentioned in this
105            documentation are exported from the CCL package.</para>
106    </sect2>
107
108    <sect2 id="Single-precision-trig---transcendental-functions">
109          <title>Single-precision trig &amp; transcendental functions</title>
110      <para>
111            Despite what Darwin's man pages say, early versions of its math library
112            (up to and including at least OSX 10.2 (Jaguar) don't implement
113            single-precision variants of the transcendental and trig functions
114            (#_sinf, #_atanf, etc.) &CCL; worked around this by coercing
115            single-precision args to double-precision, calling the
116            double-precision version of the math library function, and coercing
117            the result back to a SINGLE-FLOAT. These steps can introduce rounding
118            errors (and potentially overflow conditions) that might not be present
119            or as severe if true 32-bit variants were available.</para>
120    </sect2>
121
122    <sect2 id="Shared-libraries">
123          <title>Shared libraries</title>
124      <para>Darwin/MacOS X distinguishes between "shared libraries"
125        and "bundles" or "extensions"; Linux and FreeBSD don't. In
126        Darwin, "shared libraries" have the file type "dylib" : the
127        expectation is that this class of file is linked against when
128        executable files are created and loaded by the OS when the
129        executable is launched. The latter class -
130        "bundles/extensions" - are expected to be loaded into and
131        unloaded from a running application, via a mechanism like the
132        one used by &CCL;'s OPEN-SHARED-LIBRARY function.</para>
133    </sect2>
134  </sect1>
135
136  <sect1 id="Unix-Posix-Darwin-Features">
137    <title>Unix/Posix/Darwin Features</title>
138    <para>&CCL; has several convenience functions which allow you
139      to make Posix (portable Unix) calls without having to use the
140      foreign-function interface.  Each of these corresponds directly
141      to a single Posix function call, as it might be made in C.
142      There is no attempt to make these calls correspond to Lisp
143      idioms, such as <literal>setf</literal>.  This means that their
144      behavior is simple and predictable.</para>
145    <para>For working with environment variables, there are
146      CCL::GETENV and CCL::SETENV.</para>
147    <para>For working with user and group IDs, there are
148      CCL::GETUID, CCL::SETUID, and CCL::SETGID.  To find the home
149      directory of an arbitrary user, as set in the user database
150      (/etc/passwd), there is CCL::GET-USER-HOME-DIR.</para>
151    <para>For process IDs, there is CCL::GETPID.</para>
152    <para>For the <literal>system()</literal> function, there is
153      CCL::OS-COMMAND.  Ordinarily, it is better - both more efficient
154      and more predictable - to use the features described in <xref
155                                                                 linkend="Running-Other-Programs-as-Subprocesses"/>.  However,
156      sometimes you may want to specifically ask the shell to invoke a
157      command for you.</para>
158  </sect1>
159
160  <sect1 id="Cocoa-Programming-in-CCL">
161    <title>Cocoa Programming in &CCL;</title>
162    <para>Cocoa is one of Apple's APIs for GUI programming; for most
163      purposes, development is considerably faster with Cocoa than
164      with the alternatives.  You should have a little familiarity
165      with it, to better understand this section.</para>
166    <para>A small sample Cocoa program can be invoked by evaluating
167      (REQUIRE 'TINY) and then (CCL::TINY-SETUP). This program
168      provides a simple example of using several of the bridge's
169      capabilities.</para>
170    <para>The Tiny demo creates Cocoa objects dynamically, at
171      runtime, which is always an option.  However, for large
172      applications, it is usually more convenient to create your
173      objects with Apple Interface Builder, and store them in .nib
174      files to be loaded when needed.  Both approaches can be freely
175      mixed in a single program.</para>
176
177    <sect2 id="The-Command-Line-and-the-Window-System">
178          <title>The Command Line and the Window System</title>
179      <para>&CCL; is ordinarily a command-line application (it
180        doesn't have a connection to the OSX Window server, doesn't
181        have its own menubar or dock icon, etc.) By opening some
182        libraries and jumping through some hoops, it's able to sort of
183        transform itself into a full-fledged GUI application (while
184        retaining its original TTY-based listener.) The general idea
185        is that this hybrid environment can be used to test and
186        protoype UI ideas and the resulting application can eventually
187        be fully transformed into a bundled, double-clickable
188        application. This is to some degree possible, but there needs
189        to be a bit more infrastructure in place before many people
190        would find it easy.</para>
191      <para>Cocoa applications use the NSLog function to write
192        informational/warning/error messages to the application's
193        standard output stream. When launched by the Finder, a GUI
194        application's standard output is diverted to a logging
195        facility that can be monitored with the Console application
196        (found in /Applications/Utilities/Console.app).  In the hybrid
197        environment, the application's standard output stream is
198        usually the initial listener's standard output stream. With
199        two different buffered stream mechanisms trying to write to
200        the same underlying Unix file descriptor, it's not uncommon to
201        see NSLog output mixed with lisp output on the initial
202        listener.</para>
203    </sect2>
204
205    <sect2 id="Writing--and-reading--Cocoa-code">
206          <title>Writing (and reading) Cocoa code</title> <para>The
207            syntax of the constructs used to define Cocoa classes and
208            methods has changed a bit (it was never documented outside of
209            the source code and never too well documented at all), largely
210            as the result of functionality offered by Randall Beer's
211            bridge; the &ldquo;standard name-mapping conventions&rdquo;
212            referenced below are described in his CocoaBridgeDoc.txt file,
213            as are the constructs used to invoke (&ldquo;send messages
214            to&rdquo;) Cocoa methods.</para>
215      <para>All of the symbols described below are currently internal to
216        the CCL package.</para>
217          <simplelist type="vert" columns="1">
218            <member><xref linkend="m_class"/></member>
219            <member><xref linkend="m_selector"/></member>
220            <member><xref linkend="m_define-objc-method"/></member>
221            <member><xref linkend="m_define-objc-class-method"/></member>
222          </simplelist>
223    </sect2>
224
225    <sect2 id="The-Application-Kit-and-Multiple-Threads">
226          <title>The Application Kit and Multiple Threads</title>
227      <para>The Cocoa API is broken into several pieces.  The
228        Application Kit, affectionately called AppKit, is the one
229        which deals with window management, drawing, and handling
230        events.  AppKit really wants all these things to be done by a
231        "distinguished thread".  creation, and drawing to take place
232        on a distinguished thread.</para>
233      <para>Apple has published some guidelines which discuss these
234        issues in some detail; see the Apple Multithreading
235        Documentation, and in particular the guidelines on Using the
236        Application Kit from Multiple Threads.  The upshot is that
237        there can sometimes be unexpected behavior when objects are
238        created in threads other than the distinguished event thread;
239        eg, the event thread sometimes starts performing operations on
240        objects that haven't been fully initialized.</para> <para>It's
241        certainly more convenient to do certain types of exploratory
242        programming by typing things into a listener or evaluating a
243        &ldquo;defun&rdquo; in an Emacs buffer; it may sometimes be
244        necessary to be aware of this issue while doing so.</para>
245      <para>Each thread in the Cocoa runtime system is expected to
246        maintain a current &ldquo;autorelease pool&rdquo; (an instance
247        of the NSAutoreleasePool class); newly created objects are
248        often added to the current autorelease pool (via the
249        -autorelease method), and periodically the current autorelease
250        pool is sent a &ldquo;-release&rdquo; message, which causes it
251        to send &ldquo;-release&rdquo; messages to all of the objects
252        that have been added to it.</para>
253      <para>If the current thread doesn't have a current autorelease
254        pool, the attempt to autorelease any object will result in a
255        severe-looking warning being written via NSLog. The event
256        thread maintains an autorelease pool (it releases the current
257        pool after each event is processed and creates a new one for
258        the next event), so code that only runs in that thread should
259        never provoke any of these severe-looking NSLog
260        messages.</para> <para>To try to suppress these messages (and
261        still participate in the Cocoa memory management scheme), each
262        listener thread (the initial listener and any created via the
263        &ldquo;New Listener&rdquo; command in the IDE) is given a
264        default autorelease pool; there are REPL colon-commands for
265        manipulating the current listener's &ldquo;toplevel
266        autorelease pool&rdquo;.</para>
267      <para>In the current scheme, every time that Cocoa calls lisp
268        code, a lisp error handler is established which maps any lisp
269        conditions to ObjC exceptions and arranges that this exception
270        is raised when the callback to lisp returns. Whenever lisp
271        code invokes a Cocoa method, it does so with an ObjC exception
272        handler in place; this handler maps ObjC exceptions to lisp
273        conditions and signals those conditions.</para> <para>Any
274        unhandled lisp error or ObjC exception that occurs during the
275        execution of the distinguished event thread's event loop
276        causes a message to be NSLog'ed and the event loop to (try to)
277        continue execution. Any error that occurs in other threads is
278        handled at the point of the outermost Cocoa method
279        invocation. (Note that the error is not necessarily
280        &ldquo;handled&rdquo; in the dynamic context in which it
281        occurs.)</para>
282      <para>Both of these behaviors could possibly be improved; both of them
283        seem to be substantial improvements over previous behaviors (where,
284        for instance, a misspelled message name typically terminated the
285        application.)</para>
286    </sect2>
287
288    <sect2 id="Acknowledgement--2-">
289          <title>Acknowledgement</title>
290      <para>The Cocoa bridge was originally developed, and
291        generously contributed by, Randall Beer.</para>
292    </sect2>
293  </sect1>
294
295  <sect1 id="Building-an-Application-Bundle">
296    <title>Building an Application Bundle</title>
297    <para>You may have noticed that (require "COCOA") takes a long
298      time to load.  It is possible to avoid this by saving a Lisp
299      heap image which has everything already loaded.  There is an
300      example file which allows you to do this,
301      "ccl/examples/cocoa-application.lisp", by producing a
302      double-clickable application which runs your program.  First,
303      load your own program.  Then, do:</para>
304    <programlisting>
305? (require "COCOA-APPLICATION")
306    </programlisting>
307    <para>When it finishes, you should be able to double-click the &CCL; icon
308      in the ccl directory, to quickly start your program.</para>
309    <para>The OS may have already decided that &CCL;.app isn't a valid
310      executable bundle, and therefore won't let you double-click it.
311      If this happens to you, to force it to reconsider, just update the
312      last-modified time of the bundle.  In Terminal:</para>
313    <programlisting>> touch &CCL;.app
314    </programlisting>
315    <para>There is one important caveat.</para>
316    <para>Because of the way that the ObjC bridge currently works, a saved
317      image is dependent upon the <emphasis>exact</emphasis> versions of
318      the Cocoa libraries which were present when it was saved.
319      Specifically, the interface database is.  So, for example, an
320      application produced under OS X 10.3.5 will not work under
321      OS X 10.3.6.  This is inconvenient when you wish to distribute an
322      application you have built this way.</para>
323    <para>When an image which had contained ObjC classes (which are also
324      CLOS classes) is re-launched, those classes are "revived": all
325      preexisting classes have their addresses updated destructively, so that
326      existing subclass/superclass/metaclass relationships are maintained.
327      It's not possible (and may never be) to preserve foreign
328      instances across SAVE-APPLICATION. (It may be the case that NSArchiver
329      and NSCoder and related classes offer some approximation of that.)</para>
330  </sect1>
331
332  <sect1 id="Recommended-Reading">
333    <title>Recommended Reading></title>
334    <variablelist>
335          <varlistentry>
336            <term>
337              <ulink url="http://developer.apple.com/documentation/Cocoa/">Cocoa Documentation</ulink>
338            </term>
339
340            <listitem>
341              <para>
342                This is the top page for all of Apple's documentation on
343                Cocoa.  If you are unfamiliar with Cocoa, it is a good
344                place to start.
345              </para>
346            </listitem>
347          </varlistentry>
348          <varlistentry>
349            <term>
350              <ulink url="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/index.html">Foundation Reference for Objective-C</ulink>
351            </term>
352
353            <listitem>
354              <para>
355                This is one of the two most important Cocoa references; it
356                covers all of the basics, except for GUI programming.  This is
357                a reference, not a tutorial.
358              </para>
359            </listitem>
360          </varlistentry>
361
362          <varlistentry>
363            <term>
364              <ulink url="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/index.html">Application Kit Reference for Objective-C</ulink>
365            </term>
366
367            <listitem>
368              <para>
369                This is the other; it covers GUI programming with Cocoa
370                in considerable depth.  This is a reference, not a tutorial.
371              </para>
372            </listitem>
373          </varlistentry>
374
375          <varlistentry>
376            <term>
377              <ulink url="http://developer.apple.com/documentation/index.html">Apple Developer Documentation</ulink>
378            </term>
379
380            <listitem>
381              <para>
382                This is the site which the above two documents are found on;
383                go here to find the documentation on any other Apple API.
384                Also go here if you need general guidance about OS X, Carbon,
385                Cocoa, Core Foundation, or Objective C.
386              </para>
387            </listitem>
388          </varlistentry>
389    </variablelist>
390
391  </sect1>
392
393  <sect1 id="Operating-System-Dictionary">
394    <title>Operating-System Dictionary</title>
395
396    <refentry id="f_getenv">
397          <indexterm zone="f_getenv">
398            <primary>getenv</primary>
399          </indexterm>
400
401          <refnamediv>
402            <refname>CCL::GETENV</refname>
403            <refpurpose></refpurpose>
404            <refclass>Function</refclass>
405          </refnamediv>
406
407          <refsynopsisdiv>
408            <synopsis><function>getenv</function> name => value</synopsis>
409          </refsynopsisdiv>
410
411          <refsect1>
412            <title>Arguments and Values</title>
413
414            <variablelist>
415              <varlistentry>
416                <term>name</term>
417
418                <listitem>
419                      <para>a string which is the name of an existing
420                        environment variable;
421                        case-sensitive</para>
422                </listitem>
423              </varlistentry>
424
425              <varlistentry>
426                <term>value</term>
427
428                <listitem>
429                      <para>if there is an environment variable named
430                        <varname>name</varname>, its value, as a string; if there
431                        is not, NIL</para>
432                </listitem>
433              </varlistentry>
434            </variablelist>
435          </refsect1>
436
437          <refsect1>
438            <title>Description</title>
439
440            <para>
441              Looks up the value of the environment variable named by
442              <varname>name</varname>, in the OS environment.
443            </para>
444          </refsect1>
445    </refentry>
446
447    <refentry id="f_setenv">
448          <indexterm zone="f_setenv">
449            <primary>setenv</primary>
450          </indexterm>
451
452          <refnamediv>
453            <refname>CCL::SETENV</refname>
454            <refpurpose></refpurpose>
455            <refclass>Function</refclass>
456          </refnamediv>
457
458          <refsynopsisdiv>
459            <synopsis><function>setenv</function> name value => errno</synopsis>
460          </refsynopsisdiv>
461
462          <refsect1>
463            <title>Arguments and Values</title>
464
465            <variablelist>
466              <varlistentry>
467                <term>name</term>
468
469                <listitem>
470                      <para>a string which is the name of a new or existing
471                        environment variable;
472                        case-sensitive</para>
473                </listitem>
474              </varlistentry>
475
476              <varlistentry>
477                <term>value</term>
478
479                <listitem>
480                      <para>a string, to be the new value of the
481                        environment variable
482                        named by <varname>name</varname></para>
483                </listitem>
484              </varlistentry>
485
486              <varlistentry>
487                <term>errno</term>
488
489                <listitem>
490                      <para>zero if the function call completes successfully;
491                        otherwise, a platform-dependent integer which describes
492                        the problem</para>
493                </listitem>
494              </varlistentry>
495            </variablelist>
496          </refsect1>
497
498          <refsect1>
499            <title>Description</title>
500
501            <para>
502              Sets the value of the environment variable named by
503              <varname>name</varname>, in the OS environment.  If there is
504              no such environment
505              variable, creates it.
506            </para>
507          </refsect1>
508    </refentry>
509
510    <refentry id="f_current-directory-name">
511          <indexterm zone="f_current-directory-name">
512            <primary>current-directory-name</primary>
513          </indexterm>
514
515          <refnamediv>
516            <refname>CCL::CURRENT-DIRECTORY-NAME</refname>
517            <refpurpose></refpurpose>
518            <refclass>Function</refclass>
519          </refnamediv>
520
521          <refsynopsisdiv>
522            <synopsis><function>current-directory-name</function>
523              => path</synopsis>
524          </refsynopsisdiv>
525
526          <refsect1>
527            <title>Values</title>
528
529            <variablelist>
530              <varlistentry>
531                <term>path</term>
532
533                <listitem>
534                      <para>a string, an absolute pathname in Posix format - with
535                        directory components separated by slashes</para>
536                </listitem>
537              </varlistentry>
538            </variablelist>
539          </refsect1>
540
541          <refsect1>
542            <title>Description</title>
543
544            <para>
545              Looks up the current working directory of the &CCL; process;
546              unless it has been changed, this is the directory &CCL; was
547              started in.
548            </para>
549          </refsect1>
550    </refentry>
551
552    <refentry id="f_getuid">
553          <indexterm zone="f_getuid">
554            <primary>getuid</primary>
555          </indexterm>
556
557          <refnamediv>
558            <refname>CCL::GETUID</refname>
559            <refpurpose></refpurpose>
560            <refclass>Function</refclass>
561          </refnamediv>
562
563          <refsynopsisdiv>
564            <synopsis><function>getuid</function> => uid</synopsis>
565          </refsynopsisdiv>
566
567          <refsect1>
568            <title>Values</title>
569
570            <variablelist>
571              <varlistentry>
572                <term>uid</term>
573
574                <listitem>
575                      <para>a non-negative integer, identifying a specific user
576                        account as defined in the OS user database</para>
577                </listitem>
578              </varlistentry>
579            </variablelist>
580          </refsect1>
581
582          <refsect1>
583            <title>Description</title>
584
585            <para>
586              Returns the ("real") user ID of the current user.
587            </para>
588          </refsect1>
589    </refentry>
590
591    <refentry id="f_setuid">
592          <indexterm zone="f_setuid">
593            <primary>setuid</primary>
594          </indexterm>
595
596          <refnamediv>
597            <refname>CCL::SETUID</refname>
598            <refpurpose></refpurpose>
599            <refclass>Function</refclass>
600          </refnamediv>
601
602          <refsynopsisdiv>
603            <synopsis><function>setuid</function> uid => errno</synopsis>
604          </refsynopsisdiv>
605
606          <refsect1>
607            <title>Arguments and Values</title>
608
609            <variablelist>
610              <varlistentry>
611                <term>uid</term>
612
613                <listitem>
614                      <para>a non-negative integer, identifying a specific user
615                        account as defined in the OS user database</para>
616                </listitem>
617              </varlistentry>
618
619              <varlistentry>
620                <term>errno</term>
621
622                <listitem>
623                      <para>zero if the function call completes successfully;
624                        otherwise, a platform-dependent integer which describes
625                        the problem</para>
626                </listitem>
627              </varlistentry>
628            </variablelist>
629          </refsect1>
630
631          <refsect1>
632            <title>Description</title>
633
634            <para>
635              Attempts to change the current user ID (both "real" and
636              "effective"); fails unless
637              the &CCL; process has super-user privileges or the ID
638              given is that of the current user.
639            </para>
640          </refsect1>
641    </refentry>
642
643    <refentry id="f_setgid">
644          <indexterm zone="f_setgid">
645            <primary>setgid</primary>
646          </indexterm>
647
648          <refnamediv>
649            <refname>CCL::SETGID</refname>
650            <refpurpose></refpurpose>
651            <refclass>Function</refclass>
652          </refnamediv>
653
654          <refsynopsisdiv>
655            <synopsis><function>setgid</function> gid => errno</synopsis>
656          </refsynopsisdiv>
657
658          <refsect1>
659            <title>Arguments and Values</title>
660
661            <variablelist>
662              <varlistentry>
663                <term>gid</term>
664
665                <listitem>
666                      <para>a non-negative integer, identifying a specific
667                        group as defined in the OS user database</para>
668                </listitem>
669              </varlistentry>
670
671              <varlistentry>
672                <term>errno</term>
673
674                <listitem>
675                      <para>zero if the function call completes successfully;
676                        otherwise, a platform-dependent integer which describes
677                        the problem</para>
678                </listitem>
679              </varlistentry>
680            </variablelist>
681          </refsect1>
682
683          <refsect1>
684            <title>Description</title>
685
686            <para>
687              Attempts to change the current group ID (both "real" and
688              "effective"); fails unless
689              the &CCL; process has super-user privileges or the ID
690              given is that of a group to which the current user belongs.
691            </para>
692          </refsect1>
693    </refentry>
694
695    <refentry id="f_getpid">
696          <indexterm zone="f_getpid">
697            <primary>getpid</primary>
698          </indexterm>
699
700          <refnamediv>
701            <refname>CCL::GETPID</refname>
702            <refpurpose></refpurpose>
703            <refclass>Function</refclass>
704          </refnamediv>
705
706          <refsynopsisdiv>
707            <synopsis><function>getpid</function> => pid</synopsis>
708          </refsynopsisdiv>
709
710          <refsect1>
711            <title>Values</title>
712
713            <variablelist>
714              <varlistentry>
715                <term>pid</term>
716
717                <listitem>
718                      <para>a non-negative integer, identifying an OS process</para>
719                </listitem>
720              </varlistentry>
721            </variablelist>
722          </refsect1>
723
724          <refsect1>
725            <title>Description</title>
726
727            <para>
728              Returns the ID of the &CCL; OS process.
729            </para>
730          </refsect1>
731    </refentry>
732
733    <refentry id="f_get-user-home-dir">
734          <indexterm zone="f_get-user-home-dir">
735            <primary>get-user-home-dir</primary>
736          </indexterm>
737
738          <refnamediv>
739            <refname>CCL::GET-USER-HOME-DIR</refname>
740            <refpurpose></refpurpose>
741            <refclass>Function</refclass>
742          </refnamediv>
743
744          <refsynopsisdiv>
745            <synopsis><function>get-user-home-dir</function> 
746              uid => path</synopsis>
747          </refsynopsisdiv>
748
749          <refsect1>
750            <title>Values</title>
751
752            <variablelist>
753              <varlistentry>
754                <term>uid</term>
755
756                <listitem>
757                      <para>a non-negative integer, identifying a specific user
758                        account as defined in the OS user database</para>
759                </listitem>
760              </varlistentry>
761              <varlistentry>
762                <term>path</term>
763
764                <listitem>
765                      <para>a string, an absolute pathname in Posix format - with
766                        directory components separated by slashes; or NIL</para>
767                </listitem>
768              </varlistentry>
769            </variablelist>
770          </refsect1>
771
772          <refsect1>
773            <title>Description</title>
774
775            <para>
776              Looks up and returns the defined home directory of the user
777              identified by <varname>uid</varname>.  This value comes from the
778              OS user database, not from the <varname>$HOME</varname>
779              environment variable.  Returns NIL if there is no user with
780              the ID <varname>uid</varname>.
781            </para>
782          </refsect1>
783    </refentry>
784
785    <refentry id="f_os-command">
786          <indexterm zone="f_os-command">
787            <primary>os-command</primary>
788          </indexterm>
789
790          <refnamediv>
791            <refname>CCL::OS-COMMAND</refname>
792            <refpurpose></refpurpose>
793            <refclass>Function</refclass>
794          </refnamediv>
795
796          <refsynopsisdiv>
797            <synopsis><function>os-command</function> command-line
798              => exit-code</synopsis>
799          </refsynopsisdiv>
800
801          <refsect1>
802            <title>Values</title>
803
804            <variablelist>
805              <varlistentry>
806                <term>command-line</term>
807
808                <listitem><para>a string, obeying all the whitespace and
809                    escaping
810                    conventions required by the user's default system shell</para>
811                </listitem>
812              </varlistentry>
813            </variablelist>
814            <variablelist>
815              <varlistentry>
816                <term>exit-code</term>
817
818                <listitem><para>a non-negative integer, returned as the exit
819                    code of a subprocess; zero indicates success</para></listitem>
820              </varlistentry>
821            </variablelist>
822          </refsect1>
823
824          <refsect1>
825            <title>Description</title>
826
827            <para>
828              Invokes the Posix function <function>system()</function>, which
829              invokes the user's default system shell (such as
830              sh or tcsh) as a new process, and has that shell execute
831              <varname>command-line</varname>.
832            </para>
833           
834            <para>
835              If the shell was able to find the command specified in
836              <varname>command-line</varname>, then <varname>exit-code</varname>
837              is the exit code of that command.  If not, it is the exit
838              code of the shell itself.
839            </para>
840          </refsect1>
841
842          <refsect1>
843            <title>Notes</title>
844
845            <para>
846              By convention, an exit code of 0 indicates success.  There are
847              also other conventions; unfortunately, they are OS-specific, and
848              the portable macros to decode their meaning are implemented
849              by the system headers as C preprocessor macros.  This means
850              that there is no good, automated way to make them available
851              to Lisp.
852            </para>
853          </refsect1>
854    </refentry>
855
856    <refentry id="m_class">
857          <indexterm zone="m_class">
858            <primary>@class</primary>
859          </indexterm>
860         
861          <refnamediv>
862            <refname>CCL::@CLASS</refname>
863            <refpurpose></refpurpose>
864            <refclass>Macro</refclass>
865          </refnamediv>
866
867          <refsynopsisdiv>
868            <synopsis><function>@class</function> class-name</synopsis>
869          </refsynopsisdiv>
870
871          <refsect1>
872            <title>Arguments and Values</title>
873
874            <variablelist>
875              <varlistentry>
876                <term>class-name</term>
877
878                <listitem>
879                      <para>a string which denotes an existing class name, or a
880                        symbol which can be mapped to such a string via the standard
881                        name-mapping conventions for class names</para>
882                </listitem>
883              </varlistentry>
884            </variablelist>
885          </refsect1>
886
887          <refsect1>
888            <title>Description</title>
889
890            <para>Used to refer to a known ObjC class by name. (Via the use
891              LOAD-TIME-VALUE, the results of a class-name -&#62; class lookup
892              are cached.)</para>
893
894            <para>
895              <function>@class</function> is obsolete as of late 2004, because
896              find-class now works on ObjC classes.  It is described here
897              only because some old code still uses it.
898            </para>
899          </refsect1>
900        </refentry>
901
902        <refentry id="m_selector">
903          <indexterm zone="m_selector">
904            <primary>@selector</primary>
905          </indexterm>
906
907          <refnamediv>
908            <refname>CCL::@SELECTOR</refname>
909            <refpurpose></refpurpose>
910            <refclass>Macro</refclass>
911          </refnamediv>
912
913          <refsynopsisdiv>
914            <synopsis><function>@selector</function> string</synopsis>
915          </refsynopsisdiv>
916
917          <refsect1>
918            <title>Arguments and Values</title>
919
920            <variablelist>
921              <varlistentry>
922                    <term>string</term>
923
924                    <listitem>
925                      <para>a string constant, used to canonically refer to an
926                        ObjC method selector</para>
927                    </listitem>
928              </varlistentry>
929            </variablelist>
930          </refsect1>
931
932          <refsect1>
933            <title>Description</title>
934
935            <para>Used to refer to an ObjC method selector (method name). Uses
936              LOAD-TIME-VALUE to cache the result of a string -&#62; selector
937              lookup.</para>
938          </refsect1>
939        </refentry>
940
941        <refentry id="m_objc-defmethod">
942          <indexterm zone="m_objc-defmethod">
943            <primary>objc:defmethod</primary>
944          </indexterm>
945
946          <refnamediv>
947            <refname>objc:defmethod</refname>
948            <refpurpose></refpurpose>
949            <refclass>Macro</refclass>
950          </refnamediv>
951
952          <refsynopsisdiv>
953            <synopsis><function>objc:defmethod</function>
954              name-and-result-type ((receiver-arg-and-class) &rest;
955              other-args) &body; body</synopsis>
956          </refsynopsisdiv>
957
958          <refsect1>
959            <title>Arguments and Values</title>
960
961            <variablelist>
962
963              <varlistentry>
964                    <term>name-and-result-type</term>
965           
966                    <listitem>
967                      <para>either an Objective-C message name, for methods
968                that return a value of type <literal>:ID</literal>, or
969                a list containing an Objective-C message name and a
970                foreign type specifier for methods with a different
971                foreign result type.</para>
972                    </listitem>
973              </varlistentry>
974         
975              <varlistentry>
976                    <term>receiver-arg-and-class</term>
977           
978                    <listitem>
979                      <para>a two-element list whose first element is a
980                variable name and whose second element is the Lisp
981                name of an Objective-C class or metaclass.  The
982                receiver variable name can be any bindable lisp
983                variable name, but <literal>SELF</literal> might be a
984                reasonable choice.  The receiver variable is declared
985                to be "unsettable"; i.e., it is an error to try to
986                change the value of the receiver in the body of the
987                method definition.</para>
988                    </listitem>
989              </varlistentry>
990         
991              <varlistentry>
992                    <term>other-args</term>
993           
994                    <listitem>
995                      <para>either variable names (denoting parameters of
996            type <literal>:ID</literal>) or 2-element lists whose
997            first element is a variable name and whose second element
998            is a foreign type specifier.</para>
999                    </listitem>
1000              </varlistentry>
1001         
1002              </variablelist>
1003            </refsect1>
1004       
1005            <refsect1>
1006              <title>Description</title>
1007         
1008              <para>Defines an Objective-C-callable method which implements
1009                the specified message selector for instances of the existing
1010                named Objective-C class.</para>
1011
1012          <para>For a detailed description of the features and
1013          restrictions of the <literal>OBJC:DEFMETHOD</literal> macro,
1014          see the
1015          section <link linkend="anchor_Using-objc-defmethod">Using <literal>objc:defmethod</literal></link>.</para>
1016            </refsect1>
1017          </refentry>
1018     
1019          <refentry id="m_define-objc-method">
1020            <indexterm zone="m_define-objc-method">
1021              <primary>define-objc-method</primary>
1022            </indexterm>
1023
1024            <refnamediv>
1025              <refname>CCL::DEFINE-OBJC-METHOD</refname>
1026              <refpurpose></refpurpose>
1027              <refclass>Macro</refclass>
1028            </refnamediv>
1029
1030            <refsynopsisdiv>
1031              <synopsis><function>define-objc-method</function>
1032                (selector class-name) &body; body</synopsis>
1033            </refsynopsisdiv>
1034
1035            <refsect1>
1036              <title>Arguments and Values</title>
1037
1038              <variablelist>
1039                <varlistentry>
1040                      <term>selector</term>
1041
1042                      <listitem>
1043                        <para>either a string which represents the name of the
1044                          selector or a list which describes the method's return
1045                          type, selector components, and argument types (see below.)
1046                          If the first form is used, then the first form in the body
1047                          must be a list which describes the selector's argument
1048                          types and return value type, as per DEFCALLBACK.</para>
1049                      </listitem>
1050                </varlistentry>
1051
1052                <varlistentry>
1053                      <term>class-name</term>
1054
1055                      <listitem>
1056                        <para>either a string which names an existing ObjC class
1057                          name or a list symbol which can map to such a string via the
1058                          standard name-mapping conventions for class names. (Note
1059                          that the "canonical" lisp class name is such a
1060                          symbol)</para>
1061                      </listitem>
1062                </varlistentry>
1063              </variablelist>
1064            </refsect1>
1065
1066            <refsect1>
1067              <title>Description</title>
1068
1069              <para>Defines an ObjC-callable method which implements the
1070                specified message selector for instances of the existing ObjC
1071                class class-name.</para>
1072            </refsect1>
1073          </refentry>
1074
1075          <refentry id="m_define-objc-class-method">
1076            <indexterm zone="m_define-objc-class-method">
1077              <primary>define-objc-class-method</primary>
1078            </indexterm>
1079
1080            <refnamediv>
1081              <refname>CCL::DEFINE-OBJC-CLASS-METHOD</refname>
1082              <refpurpose></refpurpose>
1083              <refclass>Macro</refclass>
1084            </refnamediv>
1085
1086            <refsynopsisdiv>
1087              <synopsis><function>define-objc-class-method</function>
1088                (selector class-name) &body; body</synopsis>
1089            </refsynopsisdiv>
1090
1091            <refsect1>
1092              <title>Arguments and Values</title>
1093
1094              <para>As per DEFINE-OBJC-METHOD</para>
1095            </refsect1>
1096
1097            <refsect1>
1098              <title>Description</title>
1099
1100              <para>Like DEFINE-OBJC-METHOD, only used to define methods on the
1101                <emphasis>class</emphasis> named by class-name and on its
1102                subclasses.</para>
1103
1104              <para>For both DEFINE-OBJC-METHOD and DEFINE-OBJC-CLASS-METHOD, the
1105                "selector" argument can be a list whose first element is a
1106                foreign type specifier for the method's return value type and whose
1107                subsequent elements are either:</para>
1108
1109              <itemizedlist>
1110                <listitem>
1111                      <para>a non-keyword symbol, which can be mapped to a selector string
1112                        for a parameterless method according to the standard name-mapping
1113                        conventions for method selectors.</para>
1114                </listitem>
1115               
1116                <listitem>
1117                      <para>a list of alternating keywords and variable/type specifiers,
1118                        where the set of keywords can be mapped to a selector string for a
1119                        parameterized method according to the standard name-mapping
1120                        conventions for method selectors and each variable/type-specifier is
1121                        either a variable name (denoting a value of type :ID) or a list whose
1122                        CAR is a variable name and whose CADR is the corresponding
1123                        argument's foreign type specifier.</para>
1124                </listitem>
1125              </itemizedlist>
1126            </refsect1>
1127          </refentry>
1128
1129          <refentry id="v_alternate-line-terminator">
1130            <indexterm zone="v_alternate-line-terminator">
1131              <primary>*alternate-line-terminator*</primary>
1132            </indexterm>
1133
1134            <refnamediv>
1135              <refname>CCL:*ALTERNATE-LINE-TERMINATOR*</refname>
1136              <refpurpose></refpurpose>
1137              <refclass>Variable</refclass>
1138            </refnamediv>
1139
1140            <refsect1>
1141              <title>Description</title>
1142
1143              <para>This variable is currently only used by the standard reader macro
1144                function for #\; (single-line comments); that function reads successive
1145                characters until EOF, a #\NewLine is read, or a character EQL to the
1146                value of *alternate-line-terminator* is read. In &CCL; for Darwin, the
1147                value of this variable is initially #\Return ; in &CCL; for LinuxPPC,
1148                it&#39;s initially NIL.</para>
1149             
1150              <para>Their default treatment by the #\; reader macro is the primary way
1151                in which #\Return and #\Linefeed differ syntactically; by extending the
1152                #\; reader macro to (conditionally) treat #\Return as a
1153                comment-terminator, that distinction is eliminated. This seems to make
1154                LOAD and COMPILE-FILE insensitive to line-termination issues in many
1155                cases. It could fail in the (hopefully rare) case where a LF-terminated
1156                (Unix) text file contains embedded #\Return characters, and this
1157                mechanism isn&#39;t adequate to handle cases where newlines are embedded
1158                in string constants or other tokens (and presumably should be translated
1159                from an external convention to the external one) : it doesn&#39;t change
1160                what READ-CHAR or READ-LINE &#34;see&#34;, and that may be necessary to
1161                handle some more complicated cases.</para>
1162            </refsect1>
1163          </refentry>
1164
1165          <refentry id="k_external-format">
1166            <indexterm zone="k_external-format">
1167              <primary>:external-format</primary>
1168            </indexterm>
1169
1170            <refnamediv>
1171              <refname>:EXTERNAL-FORMAT</refname>
1172              <refpurpose></refpurpose>
1173              <refclass>Keyword Argument</refclass>
1174            </refnamediv>
1175
1176            <refsect1>
1177              <title>Description</title>
1178
1179              <para>Per ANSI CL, &CCL; supports the :EXTERNAL-FORMAT keyword
1180                argument to the functions OPEN, LOAD, and COMPILE-FILE. This argument is
1181                intended to provide a standard way of providing implementation-dependent
1182                information about the format of files opened with an element-type of
1183                CHARACTER. This argument can meaningfully take on the values :DEFAULT
1184                (the default), :MACOS, :UNIX, or :INFERRED in &CCL;.</para>
1185             
1186              <para>When defaulted to or specified as :DEFAULT, the format of the file
1187                stream is determined by the value of the variable
1188                CCL:*DEFAULT-EXTERNAL-FORMAT*. See below.</para>
1189             
1190              <para>When specified as :UNIX, all characters are read from and written
1191                to files verbatim.</para>
1192             
1193              <para>When specified as :MACOS, all #\Return characters read from the
1194                file are immediately translated to #\Linefeed (#\Newline); all #\Newline
1195                (#\Linefeed) characters are written externally as #\Return characters.</para>
1196             
1197              <para>When specified as :INFERRED and the file is open for input, the
1198                first buffer-full of input data is examined; if a #\Return character
1199                appears in the buffer before the first #\Linefeed, the file stream&#39;s
1200                external-format is set to :MACOS; otherwise, it is set to :UNIX.</para>
1201             
1202              <para>All other values of :EXTERNAL-FORMAT - and any combinations that
1203                don&#39;t make sense, such as trying to infer the format of a
1204                newly-created output file stream - are treated as if :UNIX was
1205                specified. As mentioned above, the :EXTERNAL-FORMAT argument doesn&#39;t
1206                apply to binary file streams.</para>
1207             
1208              <para>The translation performed when :MACOS is specified or inferred has
1209                a somewhat greater chance of doing the right thing than the
1210                *alternate-line-terminator* mechanism does; it probably has a somewhat
1211                greater chance of doing the wrong thing, as well.</para>
1212            </refsect1>
1213          </refentry>
1214
1215          <refentry id="v_default-external-format">
1216            <indexterm zone="v_default-external-format">
1217              <primary>*default-external-format*</primary>
1218            </indexterm>
1219           
1220            <refnamediv>
1221              <refname>CCL:*DEFAULT-EXTERNAL-FORMAT*</refname>
1222              <refpurpose></refpurpose>
1223              <refclass>Variable</refclass>
1224            </refnamediv>
1225
1226            <refsect1>
1227              <title>Description</title>
1228
1229              <para>The value of this variable is used when :EXTERNAL-FORMAT is
1230                unspecified or specified as :DEFAULT. It can meaningfully be given any
1231                of the values :UNIX, :MACOS, or :INFERRED, each of which is interpreted
1232                as described above.</para>
1233             
1234              <para>Because there&#39;s some risk that unsolicited newline translation
1235                could have undesirable consequences, the initial value of this variable
1236                in &CCL; is :UNIX.</para>
1237            </refsect1>
1238          </refentry>
1239
1240          <refentry id="c_ns-lisp-string">
1241            <indexterm zone="c_ns-lisp-string">
1242              <primary>ns-lisp-string</primary>
1243            </indexterm>
1244
1245            <refnamediv>
1246              <refname>CCL::NS-LISP-STRING</refname>
1247              <refpurpose></refpurpose>
1248              <refclass>Class</refclass>
1249            </refnamediv>
1250
1251            <refsect1>
1252              <title>Superclasses</title>
1253
1254              <para>NS:NS-STRING</para>
1255            </refsect1>
1256
1257            <refsect1>
1258              <title>Initargs</title>
1259             
1260              <variablelist>
1261                <varlistentry>
1262                      <term>:string</term>
1263                     
1264                      <listitem>
1265                        <para>
1266                          a Lisp string which is to be the content of
1267                          the newly-created ns-lisp-string.
1268                        </para>
1269                      </listitem>
1270                </varlistentry>
1271              </variablelist>
1272            </refsect1>
1273
1274            <refsect1>
1275              <title>Description</title>
1276
1277              <para>
1278                This class
1279                implements the interface of an NSString, which means that it can
1280                be passed to any Cocoa or Core Foundation function which expects
1281                one.
1282              </para>
1283
1284              <para>
1285                The string itself is stored on the Lisp heap, which
1286                means that its memory management is automatic.  However, the
1287                ns-lisp-string object itself is a foreign
1288                object (that is, it has an objc metaclass), and resides on the
1289                foreign heap.  Therefore, it is necessary to explicitly free
1290                it, by sending a dealloc message.
1291              </para>
1292            </refsect1>
1293
1294            <refsect1>
1295              <title>Examples</title>
1296
1297              <para>
1298                You can create an ns-lisp-string with
1299                <function>make-instance</function>, just like
1300                any normal Lisp class:
1301              </para>
1302
1303              <programlisting format="linespecific"
1304>? (defvar *the-string*
1305     (make-instance 'ccl::ns-lisp-string
1306                    :string "Hello, Cocoa."))
1307</programlisting>
1308             
1309              <para>
1310                When you are done with the string, you must explicitly
1311                deallocate it:
1312              </para>
1313
1314              <programlisting format="linespecific">? (ccl::send *the-string* 'dealloc)</programlisting>
1315
1316              <para>
1317                You may wish to use an <function>unwind-protect</function>
1318                form to ensure that this happens:
1319              </para>
1320
1321              <programlisting format="linespecific"
1322>(let (*the-string*)
1323  (unwind-protect (progn (setq *the-string*
1324                               (make-instance 'ccl::ns-lisp-string
1325                                              :string "Hello, Cocoa."))
1326                         (format t "~&amp;The string is ~D characters long.~%"
1327                                 (ccl::send *the-string* 'length)))
1328    (when *the-string*
1329      (ccl::send *the-string* 'dealloc))))
1330</programlisting>
1331
1332            </refsect1>
1333
1334            <refsect1>
1335              <title>Notes</title>
1336
1337              <para>
1338                Currently, ns-lisp-string is defined in
1339                the file ccl/examples/cocoa-backtrace.lisp, which is a
1340                rather awkward place.  It was probably not originally meant
1341                as a public utility at all.  It would be good if it were
1342                moved someplace else.  Use at your own risk.
1343              </para>
1344            </refsect1>
1345          </refentry>
1346    </sect1>
1347  </chapter>
Note: See TracBrowser for help on using the repository browser.