Annotation of objc/Test/msgTest/rettest.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: // Test all possible Objective-C method return types
                     25: // This test exercises both _msg and _msgSuper to make sure that
                     26: // all possible return types and handled correctly.  There are
                     27: // two classes used: MsgTest and SuperTest.
                     28: //
                     29: // Class MsgTest defines one method for each possible return type.
                     30: // Each method takes a single argument which is a pointer to a
                     31: // location to put a copy of the return value.  Each method stores
                     32: // its return value in that location, then returns it.  The caller
                     33: // verifies that the return value and the stored copy match.
                     34: //
                     35: // Class SuperTest does the same, and simply passes the message and
                     36: // argument on to the superclass via a message to "super".
                     37: //
                     38: // Usage:
                     39: //     rettest [ msgFlag ]
                     40: //
                     41: // If invoked with an argument, the message trace flag is enabled.
                     42: //
                     43: // Diagnostics:
                     44: //     ERROR: return value mismatch while testing '%s' in class %s
                     45: //
                     46: // A return value does not match what was expected.
                     47: //
                     48: // The first '%s' says which type is currently under test; the second
                     49: // names either "MsgTest" or "SuperTest" to indicate which message
                     50: // routine may be faulty.  Note that because SuperTest simply passes
                     51: // the message on, if there is a problem in the _msg function, it will
                     52: // show up on both tests.
                     53: //
                     54: // This diagnostic will also be accompanied by "%V:%V", where "%V"
                     55: // indicates some representation of a value.  The first is the value
                     56: // actually returned; the second is what was expected.
                     57: //
                     58: // Also printed is the filename and line number containing the test
                     59: // which failed.
                     60: //
                     61: // For example, if a method returning a double didn't match the expected
                     62: // value, you would see an error like:
                     63: //
                     64: //             return value mismatch while testing 'double' in class MsgTest
                     65: //                     line 179 in file "rettest.m":
                     66: //                     3.1416:2.9999935e+231
                     67: //
                     68: //     ERROR: unexpected exit while processing test '%s' using %s.
                     69: //
                     70: // An unexpected exit was called during testing, most likely indicating
                     71: // a program fault.  If so, the fault will also be diagnosed with a stack
                     72: // backtrace.
                     73: //
                     74: // As before, the first '%s' is the type currently under test; the
                     75: // second is either "MsgTest" or "SuperTest".
                     76: 
                     77: 
                     78: #include <objc/objc.h>
                     79: #include "rettest.h"
                     80: #include <objc/objc-class.h>
                     81: #include <stdio.h>
                     82: 
                     83: int currentLine = 0;
                     84: char *currentTest = "", *currentFile = "";
                     85: id currentReceiver = nil;
                     86: int nErrors = 0;
                     87: 
                     88: 
                     89: #import "ret1.h"
                     90: #import "ret2.h"
                     91: 
                     92: 
                     93: // exit handler
                     94: // This prints a diagnostic if an exit is called in the middle of processing,
                     95: // for example if a segmentation violation resulted from one of the test
                     96: // methods.
                     97: myCleanup(estat,arg)
                     98: int estat;
                     99: char* arg;
                    100: {
                    101:        if (estat != 0) {
                    102:                fprintf (stderr,
                    103:                         "ERROR: unexpected exit while processing test '%s' using %s\n\t",
                    104:                         currentTest, [currentReceiver str]);
                    105:                fprintf (stderr, "line %d in file \"%s\"\n", currentLine, currentFile);
                    106:        }
                    107: }
                    108: 
                    109: //extern id (*_objc_msgPreop)();
                    110: //extern void _objc_msgCollectStats();
                    111: //extern void _objc_msgPrintStats();
                    112: 
                    113: main(argc, argv)
                    114: int    argc;
                    115: char   **argv;
                    116: {
                    117:        id foo = 0;
                    118: 
                    119:        if (argc > 1)
                    120:          {
                    121: //       _objc_msgPreop = _objc_msgCollectStats;
                    122:          }
                    123: 
                    124:        currentReceiver = [MsgTest new];
                    125: 
                    126:        doTests(currentReceiver);
                    127:        // print hit/miss info.
                    128: //     if (_objc_msgPreop)
                    129: //       _objc_msgPrintStats();
                    130: 
                    131:        doTests(currentReceiver);
                    132:        // print hit/miss info.
                    133: //     if (_objc_msgPreop)
                    134: //       _objc_msgPrintStats();
                    135: 
                    136:        if (nErrors == 0)
                    137:                fprintf (stderr, "All return tests to `MsgTest' succeeded\n");
                    138:        else
                    139:                fprintf (stderr, "%d errors noted\n", nErrors);
                    140: 
                    141:        [foo bar];
                    142: #if 1
                    143:        currentReceiver = [SuperTest new];
                    144:        doTests(currentReceiver);
                    145: 
                    146:        // print hit/miss info.
                    147: //     if (_objc_msgPreop)
                    148: //       _objc_msgPrintStats();
                    149: 
                    150:        if (nErrors == 0)
                    151:                fprintf (stderr, "All return tests to `SuperTest' succeeded\n");
                    152:        else
                    153:                fprintf (stderr, "%d errors noted\n", nErrors);
                    154: 
                    155: #endif
                    156:        exit (0);       // OK exit
                    157: }
                    158: 
                    159: // Function to call all the test methods for the argument
                    160: // instance.
                    161: doTests(retInstance)
                    162: id retInstance;
                    163: {
                    164:        // scalars
                    165:        RETDECL(char);
                    166:        RETDECL(uchar_t);
                    167:        RETDECL(short);
                    168:        RETDECL(ushort_t);
                    169:        RETDECL(int);
                    170:        RETDECL(unsigned);
                    171:        RETDECL(long);
                    172:        RETDECL(ulong_t);
                    173:        RETDECL(float);
                    174:        RETDECL(double);
                    175:        // pointers
                    176:        RETDECL(id);
                    177:        RETDECL(STR);
                    178:        // structures
                    179:        RETDECL(S_BITS_16_t);
                    180:        RETDECL(S_BITS_32_t);
                    181:        RETDECL(S_BITS_64_t);
                    182:        RETDECL(S_BITS_BIG_t);
                    183:        // unions
                    184:        RETDECL(U_BITS_16_t);
                    185:        RETDECL(U_BITS_32_t);
                    186:        RETDECL(U_BITS_64_t);
                    187:        RETDECL(U_BITS_BIG_t);
                    188:        // enums
                    189:        RETDECL(E_BITS_8_t);
                    190:        RETDECL(E_BITS_16_t);
                    191: #ifdef INT_32
                    192:        RETDECL(E_BITS_32_t);
                    193: #endif
                    194: 
                    195: 
                    196:        NEXTTEST("char");
                    197:        if (RETTEST(retInstance,char)) {
                    198:                RETERR("%d:%d",char_value, char_refValue);
                    199:        }
                    200: 
                    201:        NEXTTEST("unsigned char");
                    202:        if (RETTEST(retInstance,uchar_t)) {
                    203:                RETERR("%u:%u",uchar_t_value, uchar_t_refValue);
                    204:        }
                    205: 
                    206:        NEXTTEST("short");
                    207:        if (RETTEST(retInstance,short)) {
                    208:                RETERR("%d:%d",short_value, short_refValue);
                    209:        }
                    210: 
                    211:        NEXTTEST("unsigned short");
                    212:        if (RETTEST(retInstance,ushort_t)) {
                    213:                RETERR("%u:%u",ushort_t_value, ushort_t_refValue);
                    214:        }
                    215: 
                    216:        NEXTTEST("int");
                    217:        if (RETTEST(retInstance,int)) {
                    218:                RETERR("%d:%d",int_value, int_refValue);
                    219:        }
                    220:        
                    221:        NEXTTEST("unsigned int");
                    222:        if (RETTEST(retInstance,unsigned)) {
                    223:                RETERR("%u:%u",unsigned_value, unsigned_refValue);
                    224:        }
                    225: 
                    226:        NEXTTEST("long");
                    227:        if (RETTEST(retInstance,long)) {
                    228:                RETERR("%ld:%ld",long_value, long_refValue);
                    229:        }
                    230: 
                    231:        NEXTTEST("unsigned long");
                    232:        if (RETTEST(retInstance,ulong_t)) {
                    233:                RETERR("%lu:%lu",ulong_t_value, ulong_t_refValue);
                    234:        }
                    235: 
                    236:        NEXTTEST("float");
                    237:        if (RETTEST(retInstance,float)) {
                    238:                RETERR("%.8g:%.8g",float_value, float_refValue);
                    239:        }
                    240: 
                    241:        NEXTTEST("double");
                    242:        if (RETTEST(retInstance,double)) {
                    243:                RETERR("%.17g:%.17g",double_value, double_refValue);
                    244:        }
                    245: 
                    246:        // pointer types
                    247:        NEXTTEST("id");
                    248:        if (RETTEST(retInstance,id)) {
                    249:                RETERR("%lx:%lx",id_value, id_refValue);
                    250:        }
                    251: 
                    252:        NEXTTEST("char*");
                    253:        if (RETTEST(retInstance,STR)) {
                    254:                RETERR4("%lx=%s:%lx=%s",STR_value, STR_value,
                    255:                        STR_refValue, STR_refValue);
                    256:        }
                    257: 
                    258:        // Now test the aggregate types
                    259:        NEXTTEST("struct S_BITS_16");
                    260:        if (SRETTEST(retInstance,S_BITS_16_t)) {
                    261:                RETERR("*%lx:*%lx",&S_BITS_16_t_value, &S_BITS_16_t_refValue);
                    262:        }
                    263: 
                    264:        NEXTTEST("struct S_BITS_32");
                    265:        if (SRETTEST(retInstance,S_BITS_32_t)) {
                    266:                RETERR("*%lx:*%lx",&S_BITS_32_t_value, &S_BITS_32_t_refValue);
                    267:        }
                    268: 
                    269:        NEXTTEST("struct S_BITS_64");
                    270:        if (SRETTEST(retInstance,S_BITS_64_t)) {
                    271:                RETERR("*%lx:*%lx",&S_BITS_64_t_value, &S_BITS_64_t_refValue);
                    272:        }
                    273: 
                    274:        NEXTTEST("struct S_BITS_BIG");
                    275:        if (SRETTEST(retInstance,S_BITS_BIG_t)) {
                    276:                RETERR("*%lx:*%lx",&S_BITS_BIG_t_value, &S_BITS_BIG_t_refValue);
                    277:        }
                    278: 
                    279:        // unions
                    280:        NEXTTEST("union U_BITS_16");
                    281:        if (SRETTEST(retInstance,U_BITS_16_t)) {
                    282:                RETERR("*%lx:*%lx",&U_BITS_16_t_value, &U_BITS_16_t_refValue);
                    283:        }
                    284: 
                    285:        NEXTTEST("union U_BITS_32");
                    286:        if (SRETTEST(retInstance,U_BITS_32_t)) {
                    287:                RETERR("*%lx:*%lx",&U_BITS_32_t_value, &U_BITS_32_t_refValue);
                    288:        }
                    289: 
                    290:        NEXTTEST("union U_BITS_64");
                    291:        if (SRETTEST(retInstance,U_BITS_64_t)) {
                    292:                RETERR("*%lx:*%lx",&U_BITS_64_t_value, &U_BITS_64_t_refValue);
                    293:        }
                    294: 
                    295:        NEXTTEST("union U_BITS_BIG");
                    296:        if (SRETTEST(retInstance,U_BITS_BIG_t)) {
                    297:                RETERR("*%lx:*%lx",&U_BITS_BIG_t_value, &U_BITS_BIG_t_refValue);
                    298:        }
                    299: 
                    300:        NEXTTEST("enum E_BITS_8");
                    301:        if (RETTEST(retInstance,E_BITS_8_t)) {
                    302:                RETERR("*%d:*%d",E_BITS_8_t_value, E_BITS_8_t_refValue);
                    303:        }
                    304: 
                    305:        NEXTTEST("enum E_BITS_16");
                    306:        if (RETTEST(retInstance,E_BITS_16_t)) {
                    307:                RETERR("*%d:*%d",E_BITS_16_t_value, E_BITS_16_t_refValue);
                    308:        }
                    309: 
                    310: #if 0
                    311: #ifdef INT_32
                    312:        NEXTTEST("enum E_BITS_32");
                    313:        if (RETTEST(retInstance,E_BITS_32_t)) {
                    314:                RETERR("*%d:*%d",E_BITS_32_t_value, E_BITS_32_t_refValue);
                    315:        }
                    316: #endif
                    317: #endif
                    318: 
                    319: }
                    320: 
                    321: // function to handle errors coming from return value
                    322: // mismatches.  Print a standard tag and the received
                    323: // and expected values.
                    324: #import <stdarg.h>
                    325: 
                    326: retError(char *fmt, char *file, int line, ...)
                    327: {
                    328:        va_list vp;
                    329: 
                    330:        nErrors += 1;
                    331:        fprintf (stderr, "ERROR: return value mismatch while testing '%s' in class %s\n\t",
                    332:                 currentTest, [currentReceiver str]);
                    333:        fprintf (stderr, "line %d in file \"%s\":\n\t", line, file);
                    334:        va_start(vp, line);
                    335:        vfprintf(stderr,fmt,vp);
                    336:        va_end(vp);
                    337:        fputc('\n',stderr);
                    338: }
                    339: 
                    340: doArgCheck(class,method,self,_cmd)
                    341: Class class;
                    342: SEL method;
                    343: id self;
                    344: SEL _cmd;
                    345: {
                    346:        if (self->isa != class && self->isa->super_class != class)
                    347:                error("bad 'self' argument in '%s.%s': 0x%lx",
                    348:                        class->name, SELNAME(method), self);
                    349:        if (method != _cmd)
                    350:                error("bad '_cmd' argument in '%s.%s': 0x%lx",
                    351:                        class->name, method, SELNAME(_cmd));
                    352: }
                    353: 
                    354: // General error discovered in some class
                    355: error(char *fmt, ...)
                    356: {
                    357:        va_list vp;
                    358: 
                    359:        nErrors += 1;
                    360:        fprintf (stderr, "ERROR: ");
                    361:        va_start(vp, fmt);
                    362:        vfprintf(stderr,fmt,vp);
                    363:        va_end(vp);
                    364:        fputc('\n',stderr);
                    365: }
                    366: 
                    367: // Compare two arbitrary sized objects one byte at a time.
                    368: retCompare(a1,a2,size)
                    369: char *a1, *a2;
                    370: int size;
                    371: {
                    372:        while (size-- > 0)
                    373:                if (*a1++ != *a2++)
                    374:                        return 1;
                    375:        return 0;
                    376: }
                    377: 

unix.superglobalmegacorp.com

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