home *** CD-ROM | disk | FTP | other *** search
/ Danny Amor's Online Library / Danny Amor's Online Library - Volume 1.iso / html / faqs / faq / objective-c / sample < prev   
Encoding:
Text File  |  1995-07-25  |  23.2 KB  |  955 lines

  1. Subject: comp.lang.objective-c FAQ, part 3/3: A Sample Program
  2. Newsgroups: comp.lang.objective-c,comp.answers,news.answers
  3. From: tiggr@es.ele.tue.nl (Tiggr)
  4. Date: 17 Nov 1994 17:00:08 GMT
  5.  
  6. Archive-name: Objective-C/sample
  7. Version: $Id: sample.preamble,v 2.4 1994/06/14 08:05:26 tiggr Exp $
  8.  
  9.  
  10.         A simple sample
  11.         Objective-C program
  12.  
  13.  
  14. This is the third part in a series of three informational postings
  15. concerning comp.lang.objective-c.  This article presents a simple program
  16. written in Objective-C.  The program consist of several files which are
  17. contained in a shar file (see instructions below on how to unpack).  [Note,
  18. from version 2.3 of this file, the sample has been changed in order to
  19. reduce the number of compiler warnings (down to 1, which is in there for
  20. explanatory purposes) and to reflect the use of `+alloc' and `-init' instead
  21. of `+new'.]
  22.  
  23. The early version of this FAQ was compiled by Bill Shirley, with the aid of
  24. many people.  The current version is being maintained by Tiggr, aided by a
  25. lot of people, including Paul Sanchez and Bill Shirley.
  26.  
  27. A World Wide Web hypertext version of this FAQ is maintained by Brian Harvey
  28. (theharv@csld.ucr.edu) and can be found at:
  29.     http://csld.ucr.edu/NeXTSTEP/objc_faq.html
  30.  
  31. Send your suggestions, additions, bug reports, comments and fixes to
  32. `tiggr@es.ele.tue.nl'.
  33.  
  34.  
  35. #---------------------------------- cut here ----------------------------------
  36. # This is a shell archive.  Remove anything before this line,
  37. # then unpack it by saving it in a file and typing "sh file".
  38. #
  39. # Wrapped by Pieter Schoenmakers <tiggr@viper> on Tue Jun 14 10:10:08 1994
  40. #
  41. # This archive contains:
  42. #    objc-sample    
  43. #
  44. # Existing files will not be overwritten.
  45. # Error checking via wc(1) will be performed.
  46.  
  47. LANG=""; export LANG
  48. PATH=/bin:/usr/bin:$PATH; export PATH
  49.  
  50. echo mkdir - objc-sample
  51. mkdir objc-sample
  52.  
  53. if test -f objc-sample/README
  54. then
  55.     echo Ok to overwrite existing file objc-sample/README\?
  56.     read answer
  57.     case "$answer" in
  58.     [yY]*)    echo Proceeding;;
  59.     *)    echo Aborting; exit 1;;
  60.     esac
  61.     rm -f objc-sample/README
  62.     if test -f objc-sample/README
  63.     then
  64.         echo Error: could not remove objc-sample/README, aborting
  65.         exit 1
  66.     fi
  67. fi
  68. echo x - objc-sample/README
  69. cat >objc-sample/README <<'@EOF'
  70. This directory contains the complete code for the "Simple Sample Objective-C
  71. program" described in the comp.lang.objective-c FAQ.  If you have a suitable
  72. compiler, use the supplied Makefile.  Otherwise, program output can be found
  73. in the file "output".
  74.  
  75. You should probably read "main.m" first.  It is very heavily annotated.
  76.  
  77. Also note and read the file COPYRIGHT.
  78. @EOF
  79. set `wc -lwc <objc-sample/README`
  80. if test $1$2$3 != 855366
  81. then
  82.     echo ERROR: wc results of objc-sample/README are $* should be 8 55 366
  83. fi
  84.  
  85. chmod 644 objc-sample/README
  86.  
  87. if test -f objc-sample/Char.h
  88. then
  89.     echo Ok to overwrite existing file objc-sample/Char.h\?
  90.     read answer
  91.     case "$answer" in
  92.     [yY]*)    echo Proceeding;;
  93.     *)    echo Aborting; exit 1;;
  94.     esac
  95.     rm -f objc-sample/Char.h
  96.     if test -f objc-sample/Char.h
  97.     then
  98.         echo Error: could not remove objc-sample/Char.h, aborting
  99.         exit 1
  100.     fi
  101. fi
  102. echo x - objc-sample/Char.h
  103. cat >objc-sample/Char.h <<'@EOF'
  104. #import <objc/Object.h>
  105.  
  106. @interface Char: Object
  107. {
  108.   int value;
  109. }
  110.  
  111. -init: (int) x;
  112. -report;
  113.  
  114. @end
  115. @EOF
  116. set `wc -lwc <objc-sample/Char.h`
  117. if test $1$2$3 != 111498
  118. then
  119.     echo ERROR: wc results of objc-sample/Char.h are $* should be 11 14 98
  120. fi
  121.  
  122. chmod 644 objc-sample/Char.h
  123.  
  124. if test -f objc-sample/Node.h
  125. then
  126.     echo Ok to overwrite existing file objc-sample/Node.h\?
  127.     read answer
  128.     case "$answer" in
  129.     [yY]*)    echo Proceeding;;
  130.     *)    echo Aborting; exit 1;;
  131.     esac
  132.     rm -f objc-sample/Node.h
  133.     if test -f objc-sample/Node.h
  134.     then
  135.         echo Error: could not remove objc-sample/Node.h, aborting
  136.         exit 1
  137.     fi
  138. fi
  139. echo x - objc-sample/Node.h
  140. cat >objc-sample/Node.h <<'@EOF'
  141. #import <objc/Object.h>
  142.  
  143. @interface Node : Object
  144. {
  145.   id next;
  146.   id data;
  147. }
  148.  
  149. -init: anItem;        // create a Node and store anItem in it
  150. -free;            // free a Node and return the item in it
  151. -next;            // report the id of the next node after this one
  152. -setNext: aNode;    // make the next node be aNode
  153.  
  154. @end
  155. @EOF
  156. set `wc -lwc <objc-sample/Node.h`
  157. if test $1$2$3 != 1456295
  158. then
  159.     echo ERROR: wc results of objc-sample/Node.h are $* should be 14 56 295
  160. fi
  161.  
  162. chmod 644 objc-sample/Node.h
  163.  
  164. if test -f objc-sample/Node.m
  165. then
  166.     echo Ok to overwrite existing file objc-sample/Node.m\?
  167.     read answer
  168.     case "$answer" in
  169.     [yY]*)    echo Proceeding;;
  170.     *)    echo Aborting; exit 1;;
  171.     esac
  172.     rm -f objc-sample/Node.m
  173.     if test -f objc-sample/Node.m
  174.     then
  175.         echo Error: could not remove objc-sample/Node.m, aborting
  176.         exit 1
  177.     fi
  178. fi
  179. echo x - objc-sample/Node.m
  180. cat >objc-sample/Node.m <<'@EOF'
  181. #import <objc/Object.h>
  182. #import "Node.h"
  183.  
  184. @implementation    Node: Object
  185.  
  186. -init: anItem
  187. {
  188.   self = [super init];
  189.   next = 0;
  190.   data = anItem;
  191.   return self;
  192. }
  193.  
  194. -free
  195. {
  196.   id tmp = data;
  197.   [super free];
  198.   return tmp;
  199. }
  200.  
  201. -next
  202. {
  203.   return next;
  204. }
  205.  
  206. -setNext: aNode
  207. {
  208.   next = aNode;
  209.   return self;
  210. }
  211.  
  212. @end
  213. @EOF
  214. set `wc -lwc <objc-sample/Node.m`
  215. if test $1$2$3 != 3249299
  216. then
  217.     echo ERROR: wc results of objc-sample/Node.m are $* should be 32 49 299
  218. fi
  219.  
  220. chmod 644 objc-sample/Node.m
  221.  
  222. if test -f objc-sample/Queue.h
  223. then
  224.     echo Ok to overwrite existing file objc-sample/Queue.h\?
  225.     read answer
  226.     case "$answer" in
  227.     [yY]*)    echo Proceeding;;
  228.     *)    echo Aborting; exit 1;;
  229.     esac
  230.     rm -f objc-sample/Queue.h
  231.     if test -f objc-sample/Queue.h
  232.     then
  233.         echo Error: could not remove objc-sample/Queue.h, aborting
  234.         exit 1
  235.     fi
  236. fi
  237. echo x - objc-sample/Queue.h
  238. cat >objc-sample/Queue.h <<'@EOF'
  239. #import <objc/Object.h>
  240. #import "Node.h"
  241.  
  242. @interface Queue: Object
  243. {
  244.   id head;
  245.   id tail;
  246.   unsigned qsize;
  247. }
  248.  
  249. -empty;            // clear out all contents of the Queue
  250. -put: anItem;        // put anItem on the Queue
  251. -get;            // return the item on top of the Queue
  252. -(unsigned int) size;    // tell us the current size of the Queue
  253.  
  254. @end
  255. @EOF
  256. set `wc -lwc <objc-sample/Queue.h`
  257. if test $1$2$3 != 1655319
  258. then
  259.     echo ERROR: wc results of objc-sample/Queue.h are $* should be 16 55 319
  260. fi
  261.  
  262. chmod 644 objc-sample/Queue.h
  263.  
  264. if test -f objc-sample/Queue.m
  265. then
  266.     echo Ok to overwrite existing file objc-sample/Queue.m\?
  267.     read answer
  268.     case "$answer" in
  269.     [yY]*)    echo Proceeding;;
  270.     *)    echo Aborting; exit 1;;
  271.     esac
  272.     rm -f objc-sample/Queue.m
  273.     if test -f objc-sample/Queue.m
  274.     then
  275.         echo Error: could not remove objc-sample/Queue.m, aborting
  276.         exit 1
  277.     fi
  278. fi
  279. echo x - objc-sample/Queue.m
  280. cat >objc-sample/Queue.m <<'@EOF'
  281. #import "Queue.h"
  282.  
  283. @implementation    Queue
  284.  
  285. -empty
  286. {
  287.   while([self size])
  288.     [[self get] free];
  289.   return self;
  290. }
  291.  
  292. -put: anItem
  293. {
  294.   if (tail)
  295.     tail = [[tail setNext : [[Node alloc] init: anItem]] next];
  296.   else
  297.     head = tail = [[Node alloc] init: anItem];
  298.   ++qsize;
  299.   return self;
  300. }
  301.  
  302. -get
  303. {
  304.   id contents;
  305.   id old_head = head;
  306.  
  307.   head = [head next];
  308.   contents = [old_head free];
  309.   if (--qsize == 0)
  310.     tail = head;
  311.   return contents;
  312. }
  313.  
  314. -(unsigned) size
  315. {
  316.   return qsize;
  317. }
  318.  
  319. @end
  320. @EOF
  321. set `wc -lwc <objc-sample/Queue.m`
  322. if test $1$2$3 != 3975486
  323. then
  324.     echo ERROR: wc results of objc-sample/Queue.m are $* should be 39 75 486
  325. fi
  326.  
  327. chmod 644 objc-sample/Queue.m
  328.  
  329. if test -f objc-sample/Stack.h
  330. then
  331.     echo Ok to overwrite existing file objc-sample/Stack.h\?
  332.     read answer
  333.     case "$answer" in
  334.     [yY]*)    echo Proceeding;;
  335.     *)    echo Aborting; exit 1;;
  336.     esac
  337.     rm -f objc-sample/Stack.h
  338.     if test -f objc-sample/Stack.h
  339.     then
  340.         echo Error: could not remove objc-sample/Stack.h, aborting
  341.         exit 1
  342.     fi
  343. fi
  344. echo x - objc-sample/Stack.h
  345. cat >objc-sample/Stack.h <<'@EOF'
  346. #import <objc/Object.h>
  347. #import "Node.h"
  348.  
  349. @interface Stack: Object
  350. {
  351.   id stack;
  352.   unsigned int stack_size;
  353. }
  354.  
  355. -empty;                // clear out all contents of the Stack
  356. -put: anItem;            // put anItem on the Stack
  357. -get;                // return the item on top of the Stack
  358. -(unsigned) size;        // tell us the current size of the Stack
  359.  
  360. @end
  361. @EOF
  362. set `wc -lwc <objc-sample/Stack.h`
  363. if test $1$2$3 != 1553318
  364. then
  365.     echo ERROR: wc results of objc-sample/Stack.h are $* should be 15 53 318
  366. fi
  367.  
  368. chmod 644 objc-sample/Stack.h
  369.  
  370. if test -f objc-sample/Stack.m
  371. then
  372.     echo Ok to overwrite existing file objc-sample/Stack.m\?
  373.     read answer
  374.     case "$answer" in
  375.     [yY]*)    echo Proceeding;;
  376.     *)    echo Aborting; exit 1;;
  377.     esac
  378.     rm -f objc-sample/Stack.m
  379.     if test -f objc-sample/Stack.m
  380.     then
  381.         echo Error: could not remove objc-sample/Stack.m, aborting
  382.         exit 1
  383.     fi
  384. fi
  385. echo x - objc-sample/Stack.m
  386. cat >objc-sample/Stack.m <<'@EOF'
  387. #import "Stack.h"
  388.  
  389. @implementation    Stack
  390.  
  391. -empty
  392. {
  393.   while([self size])
  394.     [[self get] free];
  395.   return self;
  396. }
  397.  
  398. -put: anItem
  399. {
  400.   stack = [[[Node alloc] init: anItem] setNext : stack];
  401.   ++stack_size;
  402.   return self;
  403. }
  404.  
  405. -get
  406. {
  407.   id contents;
  408.   id old_stack = stack;
  409.  
  410.   stack = [stack next];
  411.   contents = [old_stack free];
  412.   --stack_size;
  413.   return contents;
  414. }
  415.  
  416. -(unsigned) size
  417. {
  418.   return stack_size;
  419. }
  420.  
  421. @end
  422. @EOF
  423. set `wc -lwc <objc-sample/Stack.m`
  424. if test $1$2$3 != 3557407
  425. then
  426.     echo ERROR: wc results of objc-sample/Stack.m are $* should be 35 57 407
  427. fi
  428.  
  429. chmod 644 objc-sample/Stack.m
  430.  
  431. if test -f objc-sample/output
  432. then
  433.     echo Ok to overwrite existing file objc-sample/output\?
  434.     read answer
  435.     case "$answer" in
  436.     [yY]*)    echo Proceeding;;
  437.     *)    echo Aborting; exit 1;;
  438.     esac
  439.     rm -f objc-sample/output
  440.     if test -f objc-sample/output
  441.     then
  442.         echo Error: could not remove objc-sample/output, aborting
  443.         exit 1
  444.     fi
  445. fi
  446. echo x - objc-sample/output
  447. cat >objc-sample/output <<'@EOF'
  448. Output from demo, excluding Char class:
  449.  
  450. Include the Char class in the demo? (y/n): n
  451. queue:   5, stack:-5.0
  452. queue: 4.0, stack:  -4
  453. queue:   3, stack:-3.0
  454. queue: 2.0, stack:  -2
  455. queue:   1, stack:-1.0
  456. queue: 0.0, stack:   0
  457. queue:  -1, stack: 1.0
  458. queue:-2.0, stack:   2
  459. queue:  -3, stack: 3.0
  460. queue:-4.0, stack:   4
  461. queue:  -5, stack: 5.0
  462.  
  463. Output from demo, including Char class:
  464.  
  465. Include the Char class in the demo? (y/n): y
  466. queue:   5, stack:   h
  467. queue:   q, stack:-4.0
  468. queue:   3, stack:   j
  469. queue:   o, stack:-2.0
  470. queue:   1, stack:   l
  471. queue:   m, stack: 0.0
  472. queue:  -1, stack:   n
  473. queue:   k, stack: 2.0
  474. queue:  -3, stack:   p
  475. queue:   i, stack: 4.0
  476. queue:  -5, stack:   r
  477. @EOF
  478. set `wc -lwc <objc-sample/output`
  479. if test $1$2$3 != 29111679
  480. then
  481.     echo ERROR: wc results of objc-sample/output are $* should be 29 111 679
  482. fi
  483.  
  484. chmod 644 objc-sample/output
  485.  
  486. if test -f objc-sample/Char.m
  487. then
  488.     echo Ok to overwrite existing file objc-sample/Char.m\?
  489.     read answer
  490.     case "$answer" in
  491.     [yY]*)    echo Proceeding;;
  492.     *)    echo Aborting; exit 1;;
  493.     esac
  494.     rm -f objc-sample/Char.m
  495.     if test -f objc-sample/Char.m
  496.     then
  497.         echo Error: could not remove objc-sample/Char.m, aborting
  498.         exit 1
  499.     fi
  500. fi
  501. echo x - objc-sample/Char.m
  502. cat >objc-sample/Char.m <<'@EOF'
  503. #import <stdio.h>
  504. #import "Char.h"
  505.  
  506. @implementation Char
  507. {
  508.   int value;
  509. }
  510.  
  511. - init: (int) x
  512. {
  513.   [super init];        // In case the parent class is doing
  514.               // something special in its init...
  515.   value = x;
  516.   return self;
  517. }
  518.  
  519. - report
  520. {
  521.   printf("   %c", value);
  522.   return self;
  523. }
  524.  
  525. @end
  526. @EOF
  527. set `wc -lwc <objc-sample/Char.m`
  528. if test $1$2$3 != 2347279
  529. then
  530.     echo ERROR: wc results of objc-sample/Char.m are $* should be 23 47 279
  531. fi
  532.  
  533. chmod 644 objc-sample/Char.m
  534.  
  535. if test -f objc-sample/main.m
  536. then
  537.     echo Ok to overwrite existing file objc-sample/main.m\?
  538.     read answer
  539.     case "$answer" in
  540.     [yY]*)    echo Proceeding;;
  541.     *)    echo Aborting; exit 1;;
  542.     esac
  543.     rm -f objc-sample/main.m
  544.     if test -f objc-sample/main.m
  545.     then
  546.         echo Error: could not remove objc-sample/main.m, aborting
  547.         exit 1
  548.     fi
  549. fi
  550. echo x - objc-sample/main.m
  551. cat >objc-sample/main.m <<'@EOF'
  552. /* main.m - comp.lang.objective-c simple sample Objective-C program.  */
  553.  
  554. // This is a comment, just like the previous line.  Everything to the right
  555. // of a double slash is ignored.
  556.  
  557. /* Classes are the one real extension which Objective-C adds to C.  A class
  558.    is a description of a collection of data, like a C structure, and the
  559.    methods by which that data may be accessed or manipulated.  Instances of
  560.    a class are called objects, and methods are invoked by sending messages
  561.    to either the class itself, to produce objects, or to those objects.  The
  562.    recipient of a message is called a "receiver".  The form of a message is:
  563.  
  564.     [receiver method andMaybeSomeArguments]
  565.  
  566.    the receiver and method components are mandatory, as are the square
  567.    brackets surrounding the message.  Additional arguments may or may not be
  568.    present, depending upon the method definition.  Messages may appear
  569.    anywhere a statement is allowed in C.
  570.  
  571.    The first thing we do is bring in some include files, as in C.  On the
  572.    NeXT, it is customary to use the "import" statement which guarantees that
  573.    the file isn't included more than once.  Using GNU CC this is not all
  574.    that nice sinds it generates a huge warning for every file being
  575.    compiled.  So, since it does not really matter, we'll stick to
  576.    `#include'.  */
  577.  
  578. #import <stdio.h>
  579. #import <objc/Object.h>
  580. #import "Queue.h"
  581. #import "Stack.h"
  582.  
  583. /* That brought in class definitions for Objects, Queues, and Stacks.  The
  584.    Object class is the basis for all other classes, which is why it gets
  585.    brought in first.  It provides basic functional behavior which is
  586.    inherited by all derived classes.  All user created classes normally have
  587.    Object somewhere in their ancestry.
  588.  
  589.    Queue and Stack are classes of our own construction, and provide FIFO and
  590.    LIFO storage capabilities, respectively.  I'm not going to go into
  591.    implementation details here.  It's irrelevant how they work, all that is
  592.    important is that they both respond to 'put:' and 'get'.  If you want to
  593.    inspect them, look into the Queue.m, Stack.m, Queue.h and Stack.h files.
  594.  
  595.    A simple Class definition follows.  It inherits directly from the base
  596.    class "Object".  This gives it lots of nice properties, not the least of
  597.    which is the ability to be referenced by any pointer of the generic
  598.    object type "id".  All objects can be pointed to by any id variable, and
  599.    the default return type from methods is id.  This allows messages to be
  600.    embedded in other messages, either as receivers or arguments.
  601.  
  602.    An Int object allocates space for a single integer.  The "report" message
  603.    causes it to report its value.  Everything between the @implementation
  604.    and the @end is part of the class definition.
  605.  
  606.    Note - It is *highly* unusual to have a class implementation in your main
  607.    program.  Since the object is fully defined before it gets used, no
  608.    interface description is required.  There is nothing illegal about doing
  609.    things this way, but it is so unusual that the compiler will produce a
  610.    warning for this class.  The Int class implementation is here solely for
  611.    expository purposes.  */
  612.  
  613. @implementation Int: Object    // Int is derived from Object
  614. {
  615.     int value;        // This is the data portion.  Like a struct.
  616. }
  617.  
  618. /* The following are the method definitions.  A `+' prefix means it is a
  619.    factory method, i.e., how to manufacture instances of the class.  The
  620.    body of the method is between braces, like a C function.
  621.  
  622.    This class doesn't define any factory methods.  It relies on the +alloc
  623.    method defined in class Object.  For examples of factory methods, look at
  624.    the +new method defined in the Stack or Queue implementations.
  625.  
  626.    Self is a special variable, which refers to the object currently being
  627.    manipulated.  Super refers to the parent class of self.  The following
  628.    method asks the parent class (Object) to hand us a new instance, which
  629.    becomes self.  Then we update the instance variables and return a pointer
  630.    to the new object.
  631.  
  632.    It is standard for methods that do not need to return any special value
  633.    to instead return self.  This allows for a nested syntax of method calls.
  634.  
  635.    The "-" in front of init means that it's an instance method, i.e.,
  636.    something a particular object should respond to.  */
  637.  
  638. -init: (int) i
  639. {
  640.   /* We're overriding the `-init' of our superclass, but we add
  641.      functionality instead of replacing it.  Therefore, first call the
  642.      `-init' of our superclass.  */
  643.   [super init];
  644.   value = i;
  645.   return self;
  646. }
  647.  
  648. -report
  649. {
  650.   printf ("%4d", value);
  651.   return self;
  652. }
  653.  
  654. @end
  655.  
  656. /* We have implemented Float and Char classes more traditionally, using
  657.    separate files for the interface (.h) and implementation (.m).  The Float
  658.    and Char objects are like the Int object, but with the obvious difference
  659.    that they work with floats and characters.  We include the interface
  660.    definitions at this point.  */
  661.  
  662. #import "Float.h"
  663. #import "Char.h"
  664.  
  665. /* If you inspect those files, note polymorphism -- methods have same
  666.    names as in the Int class.  */
  667.  
  668. int main (void)
  669. {
  670.     /* First create instances of "Stack" and "Queue" data structures.  */
  671.     id queue = [[Queue alloc] init];
  672.     id stack = [[Stack alloc] init];
  673.     int i, reply;
  674.     
  675.     fprintf (stderr, "Include the Char class in the demo? (y/n): ");
  676.  
  677.     /* Anything not matching `y.*' means no.  */
  678.     reply = getchar ();
  679.  
  680.     for (i = 5; i > -6; --i)
  681.       {
  682.     /* Depending on which version of the demo we're running, we
  683.        alternately put Ints and Floats onto the queue and stack, or
  684.        Ints, Floats, and Chars.  */
  685.     if (reply == 'y')
  686.       {
  687.         /* If I is odd we put an Int on the queue and a Char on the
  688.            stack.  If I is even we put an Char on the queue and a Float
  689.            on the stack.
  690.  
  691.            Since there is more than one method `-init:' and since
  692.            `+alloc' returns a plain, typeless, `id', the compiler
  693.            doesn't know the type of the object returned by alloc.  An
  694.            explicit cast (i.e. static type indication) ensures that the
  695.            compiler knows which `init:' is invoked---the one accepting a
  696.            char or the other one accepting an int.
  697.  
  698.            Another solution, which avoids the static type indication, is
  699.            to put typing information on the method in the method's name.
  700.            This is done for the Float class.  */
  701.         id my_char = [(Char *) [Char alloc] init: 'm' + i];
  702.  
  703.         if (i & 1)
  704.           {
  705.         [queue put: [(Int *) [Int alloc] init: i]];
  706.         [stack put: my_char];
  707.           }
  708.         else
  709.           {
  710.         [queue put: my_char];
  711.         [stack put: [[Float alloc] initFloatValue: i]];
  712.           }
  713.           }
  714.     else
  715.       {
  716.         /* If I is odd we put an Int on the queue and a Float on the
  717.            stack.  If I is even we put a Float on the queue and an Int
  718.            on the stack.  */
  719.             [queue put: ((i & 1)
  720.              ? [(Int *) [Int alloc] init: i]
  721.              : [[Float alloc] initFloatValue: i])];
  722.             [stack put: ((i & 1)
  723.              ? [[Float alloc] initFloatValue: i]
  724.              : [(Int*) [Int alloc] init: i])];
  725.     }
  726.     }
  727.  
  728.     while ([queue size] && [stack size])
  729.       {
  730.     /* The following illustrates run-time binding.  Will report be
  731.        invoked for a Float object or an Int object?  Did the user elect
  732.        for Char objects at run time?  We don't know ahead of time, but
  733.        with run-time binding and polymorphism it works properly.  The
  734.        burden is on the class implementer rather than the class user.
  735.  
  736.        Note that the following lines remain unchanged, whether we are
  737.        using the Char class or not.  The queue and stack hand us the
  738.        next object, it reports itself regardless of its type, and then
  739.        it frees itself.  */
  740.  
  741.     printf ("queue:");
  742.     [[[queue get] report] free];
  743.     printf (", stack:");
  744.     [[[stack get] report] free];
  745.     putchar('\n');
  746.       }
  747.   return 0;
  748. }
  749. @EOF
  750. set `wc -lwc <objc-sample/main.m`
  751. if test $1$2$3 != 19712617780
  752. then
  753.     echo ERROR: wc results of objc-sample/main.m are $* should be 197 1261 7780
  754. fi
  755.  
  756. chmod 644 objc-sample/main.m
  757.  
  758. if test -f objc-sample/Makefile
  759. then
  760.     echo Ok to overwrite existing file objc-sample/Makefile\?
  761.     read answer
  762.     case "$answer" in
  763.     [yY]*)    echo Proceeding;;
  764.     *)    echo Aborting; exit 1;;
  765.     esac
  766.     rm -f objc-sample/Makefile
  767.     if test -f objc-sample/Makefile
  768.     then
  769.         echo Error: could not remove objc-sample/Makefile, aborting
  770.         exit 1
  771.     fi
  772. fi
  773. echo x - objc-sample/Makefile
  774. cat >objc-sample/Makefile <<'@EOF'
  775. # This Makefile assumes you have GNU gcc 2.3 or better and a suitable
  776. # runtime library with object support.  It also works on a NeXT.
  777. # Don't know about Stepstone.
  778.  
  779. .SUFFIXES: .o .m
  780. .m.o:
  781.     $(CC) -c $(CFLAGS) $<
  782.  
  783. # Use this on a NeXT
  784. #CC=        cc
  785. #LIBS=        
  786. # Use this with GNU CC on a non-NeXT,
  787. # and avoid the GCC moaning on using #import.
  788. CC=        gcc -Wno-import
  789. LIBS=        -lobjc
  790. LDFLAGS=    -L/usr/local/lib -L/usr/gnu/lib
  791.  
  792. CFLAGS=        -Wall -g
  793. OFILES=        main.o Node.o Queue.o Stack.o Float.o Char.o
  794.  
  795. demo: $(OFILES)
  796.     $(CC) $(CFLAGS) $(LDFLAGS) -o demo $(OFILES) $(LIBS)
  797.  
  798. clean:
  799.     rm -f $(OFILES) demo
  800.     
  801. Char.o : Char.m Char.h 
  802.  
  803. Float.o : Float.m Float.h 
  804.  
  805. Node.o : Node.m Node.h 
  806.  
  807. Queue.o : Queue.m Queue.h Node.h 
  808.  
  809. Stack.o : Stack.m Stack.h Node.h 
  810.  
  811. main.o : main.m Queue.h Node.h Stack.h Float.h
  812. @EOF
  813. set `wc -lwc <objc-sample/Makefile`
  814. if test $1$2$3 != 37127783
  815. then
  816.     echo ERROR: wc results of objc-sample/Makefile are $* should be 37 127 783
  817. fi
  818.  
  819. chmod 644 objc-sample/Makefile
  820.  
  821. if test -f objc-sample/Float.m
  822. then
  823.     echo Ok to overwrite existing file objc-sample/Float.m\?
  824.     read answer
  825.     case "$answer" in
  826.     [yY]*)    echo Proceeding;;
  827.     *)    echo Aborting; exit 1;;
  828.     esac
  829.     rm -f objc-sample/Float.m
  830.     if test -f objc-sample/Float.m
  831.     then
  832.         echo Error: could not remove objc-sample/Float.m, aborting
  833.         exit 1
  834.     fi
  835. fi
  836. echo x - objc-sample/Float.m
  837. cat >objc-sample/Float.m <<'@EOF'
  838. #import <stdio.h>
  839. #import "Float.h"
  840.  
  841. @implementation Float
  842. {
  843.   float value;
  844. }
  845.  
  846. -initFloatValue: (float) x
  847. {
  848.   [super init];
  849.   value = x;
  850.   return self;
  851. }
  852.  
  853. -report
  854. {
  855.   printf ("%4.1f", value);
  856.   return self;
  857. }
  858.  
  859. @end
  860. @EOF
  861. set `wc -lwc <objc-sample/Float.m`
  862. if test $1$2$3 != 2231215
  863. then
  864.     echo ERROR: wc results of objc-sample/Float.m are $* should be 22 31 215
  865. fi
  866.  
  867. chmod 644 objc-sample/Float.m
  868.  
  869. if test -f objc-sample/COPYRIGHT
  870. then
  871.     echo Ok to overwrite existing file objc-sample/COPYRIGHT\?
  872.     read answer
  873.     case "$answer" in
  874.     [yY]*)    echo Proceeding;;
  875.     *)    echo Aborting; exit 1;;
  876.     esac
  877.     rm -f objc-sample/COPYRIGHT
  878.     if test -f objc-sample/COPYRIGHT
  879.     then
  880.         echo Error: could not remove objc-sample/COPYRIGHT, aborting
  881.         exit 1
  882.     fi
  883. fi
  884. echo x - objc-sample/COPYRIGHT
  885. cat >objc-sample/COPYRIGHT <<'@EOF'
  886. This copyright notice applies to all source files distributed in the
  887. comp.lang.objective-c FAQ: `A Simple Sample Objective-C program'.
  888.  
  889. Copyright (C) 1993 Paul J. Sanchez and Bill Shirley
  890. Copyright (C) 1994 Pieter J. Schoenmakers
  891.  
  892. The `simple sample Objective-C program' is free software; you can
  893. redistribute it and/or modify it under the terms of the GNU General Public
  894. License as published by the Free Software Foundation; either version 2, or
  895. (at your option) any later version.
  896.  
  897. The `simple sample Objective-C program' is distributed in the hope that it
  898. will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  899. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
  900. Public License for more details.
  901.  
  902. You should have received a copy of the GNU General Public License
  903. along with GNU Emacs; see the file COPYING.  If not, write to
  904. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  905. @EOF
  906. set `wc -lwc <objc-sample/COPYRIGHT`
  907. if test $1$2$3 != 19150944
  908. then
  909.     echo ERROR: wc results of objc-sample/COPYRIGHT are $* should be 19 150 944
  910. fi
  911.  
  912. chmod 644 objc-sample/COPYRIGHT
  913.  
  914. if test -f objc-sample/Float.h
  915. then
  916.     echo Ok to overwrite existing file objc-sample/Float.h\?
  917.     read answer
  918.     case "$answer" in
  919.     [yY]*)    echo Proceeding;;
  920.     *)    echo Aborting; exit 1;;
  921.     esac
  922.     rm -f objc-sample/Float.h
  923.     if test -f objc-sample/Float.h
  924.     then
  925.         echo Error: could not remove objc-sample/Float.h, aborting
  926.         exit 1
  927.     fi
  928. fi
  929. echo x - objc-sample/Float.h
  930. cat >objc-sample/Float.h <<'@EOF'
  931. #import <objc/Object.h>
  932.  
  933. @interface Float: Object
  934. {
  935.   float value;
  936. }
  937.  
  938. -initFloatValue: (float) x;
  939. -report;
  940.  
  941. @end
  942. @EOF
  943. set `wc -lwc <objc-sample/Float.h`
  944. if test $1$2$3 != 1114113
  945. then
  946.     echo ERROR: wc results of objc-sample/Float.h are $* should be 11 14 113
  947. fi
  948.  
  949. chmod 644 objc-sample/Float.h
  950.  
  951. chmod 755 objc-sample
  952.  
  953. exit 0
  954.  
  955.