Annotation of objc/Test/Mark.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.0 (the 'License').  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License."
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: #import <objc/Object.h>
                     26: #import <objc/HashTable.h>
                     27: #import <float.h>
                     28: #import <stdarg.h>
                     29: 
                     30: struct foo 
                     31: {
                     32:        int i;
                     33:        char c;
                     34:        float f;
                     35:        char *s;
                     36: };
                     37: 
                     38: static void foo_display(struct foo *s, int i)
                     39: {
                     40:     printf("arg[%d]->i = %d\n", i, s->i);
                     41:     printf("arg[%d]->c = '%c'\n", i, s->c);
                     42:     printf("arg[%d]->f = %f\n", i, s->f);
                     43:     printf("arg[%d]->s = %s\n", i, s->s);
                     44: };
                     45: 
                     46: struct large
                     47: {
                     48:        int a[50];
                     49: };
                     50: 
                     51: @implementation Tool : Object
                     52: 
                     53: - large:(struct large)l small:(int)i
                     54: {
                     55:        return self;
                     56: }
                     57: 
                     58: - varargs:(int)n, ... 
                     59: {
                     60:        va_list ap;
                     61:        int i;
                     62: 
                     63:        va_start(ap, n); 
                     64:        for (i = 0; i < n; i++)
                     65:                printf("va_arg[%d] = %d ", i, va_arg(ap,int));
                     66:        va_end(ap);
                     67:        printf("\n");
                     68: }
                     69: 
                     70: - double:(double)d char:(char)c float:(float)f double:(double)dd
                     71: {
                     72:        return self;
                     73: }
                     74: - incrementMe:(int)i
                     75: {
                     76:        printf("i = %d\n",i);
                     77:        return self;
                     78: }
                     79: 
                     80: - pointerToStructFoo:(struct foo *)s
                     81: {
                     82:        printf("i = %d c = '%c' f = %f s = %s\n",s->i,s->c,s->f,s->s);
                     83: }
                     84: 
                     85: - structFoo:(struct foo)s
                     86: {
                     87:        printf("i = %d c = '%c' f = %f s = %s\n",s.i,s.c,s.f,s.s);
                     88: }
                     89: 
                     90: - long:(long)l short:(short)a char:(char)c
                     91: {
                     92:        return self;
                     93: }
                     94: 
                     95: - array:(int [7])ary 
                     96: {
                     97:        return self;
                     98: }
                     99: 
                    100: @end
                    101: 
                    102: @implementation Forward : Object
                    103: {
                    104:        id destination;
                    105: }
                    106: 
                    107: - setDestination:dest
                    108: {
                    109:        destination = dest;
                    110: }
                    111: 
                    112: static int getTagLen(char *tag)
                    113: {
                    114:        int len = 0;
                    115: 
                    116:        while (*tag++ != _C_STRUCT_E) len++;
                    117: 
                    118:        return len;
                    119: }
                    120: 
                    121: /*
                    122:    Purpose:    Provide support required when forwarding messages 
                    123:                to remote objects. -performv::, -methodArgSize:,
                    124:                method_getNumberOfArguments(), method_getSizeOfArguments(),
                    125:                and method_getArgumentInfo() provide additional support
                    126:                for understanding the format of the stack. This level of
                    127:                support is currently used exclusively by Workspace and
                    128:                is part of the Unpublished API for Remote Objects.
                    129: 
                    130:    Semantics:  This function is responsible for two things:
                    131:                (1) obtaining the object that does respond to the selector.
                    132:                (2) sending the object the message via "performv::"     
                    133:    Features:   (1) chance to analyze/transform arguments on the stack 
                    134:                    before sending the message.
                    135:                (2) chance to perform a post operation after sending 
                    136:                    the message.
                    137:    Limitations:        (1) cannot forward methods that take a variable number 
                    138:                    of arguments.
                    139:                (2) forwarding methods that return values greater than
                    140:                    `sizeof(id)' are unreliable.
                    141: */
                    142: 
                    143: - forward:(SEL)asel :(marg_list)args
                    144: {
                    145:        void *retval;
                    146:        Method method;
                    147:        int i, nargs;
                    148: 
                    149:        // analyze argument types of an anonymous (un-known) selector...
                    150:        // ...necessary for doing remote objects.
                    151: 
                    152:        method = class_getInstanceMethod([destination class], asel);
                    153:        nargs = method_getNumberOfArguments(method);
                    154: 
                    155:        for (i = 0; i < nargs; i++) {
                    156:                char *type;
                    157:                int offset;
                    158: 
                    159:                method_getArgumentInfo(method, i, &type, &offset);
                    160: 
                    161:                printf ("arg[%d] (offset = %d, type = '%c')",
                    162:                        i, offset, type[0]);
                    163: 
                    164:                switch (type[0]) {
                    165:                   case _C_ID:
                    166:                        {
                    167:                        id obj = marg_getValue(args, offset, id);
                    168:                        printf(" = %s\n", [obj name]);
                    169:                        break;
                    170:                        }
                    171:                   case _C_SEL:
                    172:                        {
                    173:                        SEL sel = marg_getValue(args, offset, SEL);
                    174:                        printf(" = %s\n", sel_getName(sel));
                    175:                        break;
                    176:                        }
                    177:                   case _C_CHARPTR:
                    178:                        {
                    179:                        char *str = marg_getValue(args, offset, char *);
                    180:                        printf(" = %s\n", str);
                    181:                        break;
                    182:                        }
                    183:                   case _C_LNG: case _C_INT:
                    184:                        {
                    185:                        long longVal = marg_getValue(args, offset, long);
                    186:                        printf(" = %d\n", longVal);
                    187: 
                    188:                        if (asel == @selector(incrementMe:))
                    189:                                marg_setValue(args, offset, long, ++longVal);
                    190:                        break;
                    191:                        }
                    192:                   case _C_SHT:
                    193:                        {
                    194:                        short shortVal = marg_getValue(args, offset, short);
                    195:                        printf(" = %d\n", shortVal); 
                    196:                        break;
                    197:                        }
                    198:                   case _C_CHR:
                    199:                        {
                    200:                        char charVal = marg_getValue(args, offset, char);
                    201:                        printf(" = '%c'\n", charVal);
                    202:                        break;
                    203:                        }
                    204:                   case _C_FLT:
                    205:                        {
                    206:                        float floatVal = marg_getValue(args, offset, float);
                    207:                        printf(" = %f\n", floatVal);
                    208:                        break;
                    209:                        }
                    210:                   case _C_DBL:
                    211:                        {
                    212:                        double doubleVal = marg_getValue(args, offset, double);
                    213:                        printf(" = %f\n", doubleVal);
                    214:                        break;
                    215:                        }
                    216:                   case _C_PTR:
                    217:                        {
                    218:                        if (type[1] == _C_STRUCT_B) 
                    219:                          {
                    220:                          if (strncmp(&type[2], "foo", getTagLen(&type[2])) == 0) 
                    221:                            {
                    222:                            struct foo *s = marg_getValue(args, offset, struct foo *);
                    223:                            foo_display(s, i);
                    224:                            }
                    225:                          }
                    226:                        break;
                    227:                        }
                    228:                   case _C_STRUCT_B:
                    229:                        {
                    230:                        if (strncmp(&type[1], "foo", getTagLen(&type[1])) == 0) 
                    231:                          {
                    232:                          struct foo s = marg_getValue(args, offset, struct foo);
                    233:                          foo_display(marg_getRef(args, offset, struct foo), i);
                    234: 
                    235:                          s.i++, s.c++, s.f++, s.s = "transformed string";
                    236:                          marg_setValue(args, offset, struct foo, s);
                    237:                          }
                    238:                        break;
                    239:                        }
                    240:                   case _C_ARY_B:
                    241:                        {
                    242:                        printf("array type not recognized ('%s')\n", type);
                    243:                        }
                    244:                   default:
                    245:                        printf("type not recognized ('%c')\n", type[0]);
                    246:                        break;
                    247:                }
                    248:        }
                    249:        if (asel == @selector(varargs:))
                    250:          {
                    251:           int size = [destination methodArgSize: asel];
                    252:           if (! size) return [self doesNotRecognize: asel];
                    253:           retval = objc_msgSendv (destination, asel, size+12, args); 
                    254:          }
                    255:        else
                    256:          retval = [destination performv:asel :args];
                    257: 
                    258:        return retval;
                    259: }
                    260: 
                    261: @end
                    262: 
                    263: 
                    264: main()
                    265: {
                    266:        id forward = [Forward new];
                    267:        id tool = [Tool new];
                    268: 
                    269:        struct foo afoo = {33, 'y', 9.9, "great"};
                    270:        struct large alarge;
                    271:        int ary[7];
                    272: 
                    273:        [tool varargs:3, 1,2,3];
                    274:        [tool long:77 short:7 char:'z'];
                    275:        [tool incrementMe:100];
                    276:        [tool pointerToStructFoo:&afoo];
                    277:        [tool structFoo:afoo];
                    278:        [tool double:4.4 char:'5' float:3.4 double:8.8];
                    279:        [tool large:alarge small:7007];
                    280:        [tool array:ary];
                    281: 
                    282:        [forward setDestination:tool];
                    283: 
                    284:        [forward varargs:3, 1,2,3];
                    285:        [forward long:77 short:7 char:'z'];
                    286:        [forward incrementMe:100];
                    287:        [forward pointerToStructFoo:&afoo];
                    288:        [forward structFoo:afoo];
                    289:        [forward double:4.4 char:'5' float:3.4 double:8.8];
                    290:        [forward large:alarge small:7007];
                    291:        [forward array:ary];
                    292:        printf("\n");
                    293: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.