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

Last change on this file since 8567 was 8567, checked in by rme, 13 years ago

Break up monolithic openmcl-documentation.xml file into chapters. Add file
top.xml, which includes all the chapters via xi:xinclude.

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