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

Last change on this file since 8606 was 8606, checked in by gb, 13 years ago

Rename chapter-level files to not include chapter numbers (so that it'd be
less confusing to change chapter order, remove/introduce chapters, etc.)

Ensure that all chapter-level files have ENTITY definitions in their
DOCTYPE forms.

Define a CCL entity (currently just <literal>CCL</literal>; change all
references to "OpenMCL" to "&CCL;"

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