This is tester.m in view mode; [Download] [Up]
// // overall testing of many of the RCString categories. // has gets() statements to allow checks for dangling // pointers every so often. // #import <stdio.h> #import <stdlib.h> #import <signal.h> #import <fcntl.h> #import <string.h> #import <sys/time.h> #import <RCString.h> int igErrorCount = 0; char *getrandomstring(); int main(int c, char **v) { void xp_test(char *); void insert_test(char *bpBaseString, char *bpToInsert, int index); void retrieve_test(); void replace_test(); char *bvLargeString; char buf[512]; int icCount, iErrorCount, iInsertLocation; struct timeval sTimeVal; #ifdef NeXT int signalHandler(); // install a few signal handlers signal(SIGSEGV, signalHandler); signal(SIGBUS, signalHandler); signal(SIGILL, signalHandler); // turn on fairly high level of malloc error checking malloc_debug(8); #endif NeXT if (c > 1) gets(buf); iErrorCount = igErrorCount; puts("\ntesting of explicity NULL strings"); xp_test(NULL); if (iErrorCount != igErrorCount) printf("committed %d sins\n", igErrorCount - iErrorCount); if (c > 1) gets(buf); iErrorCount = igErrorCount; puts("\ntesting of zero length strings"); xp_test(""); if (iErrorCount != igErrorCount) printf("committed %d sins\n", igErrorCount - iErrorCount); if (c > 1) gets(buf); iErrorCount = igErrorCount; puts("\ntesting of 1-char length strings"); xp_test("a"); if (iErrorCount != igErrorCount) printf("committed %d sins\n", igErrorCount - iErrorCount); if (c > 1) gets(buf); iErrorCount = igErrorCount; puts("\ntesting of 2-char length strings"); xp_test("aB"); if (iErrorCount != igErrorCount) printf("committed %d sins\n", igErrorCount - iErrorCount); if (c > 1) gets(buf); iErrorCount = igErrorCount; puts("\ntesting of 8973-char length strings"); bvLargeString = malloc(8974); for (icCount = 0; icCount < 8973; ++icCount) bvLargeString[icCount] = (icCount % 94) + ' '; xp_test(bvLargeString); if (iErrorCount != igErrorCount) printf("committed %d sins\n", igErrorCount - iErrorCount); if (c > 1) gets(buf); if (igErrorCount) printf("committed %d sins in allocate/free/empty/compare tests\n", igErrorCount); igErrorCount = 0; puts("\ntesting inserting null strings into other null strings"); iErrorCount = igErrorCount; // insert_test(char *bpBaseString, char *bpToInsert, int index) insert_test("", "", 0); insert_test("", "", -1); insert_test("", "", 1); insert_test("", "", 2); if (iErrorCount != igErrorCount) printf("null insertion committed %d sins\n", igErrorCount - iErrorCount); puts("\ntesting inserting null strings into 1-char strings"); iErrorCount = igErrorCount; // insert_test(char *bpBaseString, char *bpToInsert, int index) insert_test("", "a", 0); insert_test("", "a", -1); insert_test("", "a", 1); insert_test("B", "", -2); insert_test("B", "", -1); insert_test("B", "", 0); insert_test("B", "", 1); insert_test("B", "", 2); if (iErrorCount != igErrorCount) printf("insertion committed %d sins\n", igErrorCount - iErrorCount); puts("\ntesting inserting 1-char strings into 1-char strings"); iErrorCount = igErrorCount; // insert_test(char *bpBaseString, char *bpToInsert, int index) insert_test("0", "a", -1); insert_test("0", "a", 0); insert_test("0", "a", 1); insert_test("B", "7", -2); insert_test("B", "7", -1); insert_test("B", "7", 0); insert_test("B", "7", 1); insert_test("B", "7", 2); if (iErrorCount != igErrorCount) printf("insertion committed %d sins\n", igErrorCount - iErrorCount); puts("\ntesting inserting 1-char strings into 2-char strings"); iErrorCount = igErrorCount; // insert_test(char *bpBaseString, char *bpToInsert, int index) insert_test("00", "a", -2); insert_test("00", "a", -1); insert_test("00", "a", 0); insert_test("00", "a", 1); insert_test("00", "a", 2); insert_test("B", "7F", -2); insert_test("B", "7F", -1); insert_test("B", "7F", 0); insert_test("B", "7F", 1); insert_test("B", "7F", 2); if (iErrorCount != igErrorCount) printf("insertion committed %d sins\n", igErrorCount - iErrorCount); // redo the "large" string for (icCount = 0; icCount < 8973; ++icCount) bvLargeString[icCount] = (icCount % 94) + ' '; puts("\ntesting inserting large strings into large strings"); iErrorCount = igErrorCount; insert_test(bvLargeString, bvLargeString, -1); insert_test(bvLargeString, bvLargeString, 0); insert_test(bvLargeString, bvLargeString, 1); insert_test(bvLargeString, bvLargeString, -2); insert_test(bvLargeString, bvLargeString, -1); insert_test(bvLargeString, bvLargeString, 0); insert_test(bvLargeString, bvLargeString, 1); insert_test(bvLargeString, bvLargeString, 2); for (icCount = 0; icCount < 5; ++icCount) { gettimeofday(&sTimeVal, NULL); iInsertLocation = ((sTimeVal.tv_sec % sTimeVal.tv_usec) % 8973); printf("inserting a large string at %d\n", iInsertLocation); insert_test(bvLargeString, bvLargeString, iInsertLocation); } if (iErrorCount != igErrorCount) printf("insertion committed %d sins\n", igErrorCount - iErrorCount); puts("\ntesting replacement methods"); iErrorCount = igErrorCount; replace_test(); if (iErrorCount != igErrorCount) printf("replacement committed %d sins\n", igErrorCount - iErrorCount); if (c > 1) gets(buf); puts("\ntesting retrieval methods"); iErrorCount = igErrorCount; retrieve_test(); if (iErrorCount != igErrorCount) printf("retrieval committed %d sins\n", igErrorCount - iErrorCount); printf("committed %d total sins\n", igErrorCount); if (c > 1) gets(buf); return(0); } char *method_strings[3] = { "-new ", "-newFromString:", "-newFromObject:" }; // // allocation, deletion, emptying and comparison tests. // void xp_test(char *bpTestValue) { int i, j; RCString *oString1, *oString2, *oString3; RCString *ovString[3]; RCString *ovCopies[3]; puts("testing of -new methods"); oString1 = [RCString new]; oString2 = [RCString newFromString:bpTestValue]; oString3 = [RCString newFromObject:oString2]; [oString3 copyReference]; if (!oString1) { fputs(" -new method failed\n", stderr); ++igErrorCount; } if (!oString2) { fputs(" -newFromString method failed\n", stderr); ++igErrorCount; } if (!oString3) { ++igErrorCount; fputs(" -newFromObject method failed\n", stderr); } [oString1 free]; [oString2 free]; [oString3 free]; // reference copy counting puts("\ntesting of reference counting"); ovString[0] = [RCString new]; ovString[1] = [RCString newFromString:bpTestValue]; ovString[2] = [RCString newFromObject:ovString[1]]; [ovString[2] copyReference]; for (j = 0; j < 3; ++j) { if ([ovString[j] references] != 1) { printf("%s created object: %d refs (should be 1), internal rep 0x%x\n", method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]); ++igErrorCount; } } puts("\ncalling copyReference"); for (i = 0; i < 5; ++i) { for (j = 0; j < 3; ++j) { [ovString[j] copyReference]; } } for (j = 0; j < 3; ++j) { if ([ovString[j] references] != 1) { printf("%s created object: %d refs (should be 1), internal rep 0x%x\n", method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]); ++igErrorCount; } } puts("\ncalling newFromObject: on objects that ought have 1 refs"); for (j = 0; j < 3; ++j) ovCopies [j] = [RCString newFromObject:ovString[j]]; for (j = 0; j < 3; ++j) { if ([ovString[j] references] != 2 || [ovCopies[j] references] != 2) { printf( "%s created object: %d refs (should be 2), internal rep 0x%x\n", method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]); printf( "copied object: %d refs (should be 2), internal rep 0x%x\n", [ovCopies[j] references], (unsigned int)[ovCopies[j] internal]); ++igErrorCount; } } puts("\ncalling copyReference on object copies"); for (j = 0; j < 3; ++j) [ovCopies [j] copyReference]; for (j = 0; j < 3; ++j) { if ([ovString[j] references] != 1 || [ovCopies[j] references] != 1) { printf("%s created object: %d refs (should be 1), internal rep 0x%x\n", method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]); printf( "copied object: %d refs (should be 1), internal rep 0x%x\n", [ovCopies[j] references], (unsigned int)[ovCopies[j] internal]); ++igErrorCount; } } for (j = 0; j < 3; ++j) { [ovString[j] free]; [ovCopies[j] free]; } puts("testing of -empty methods"); ovString[0] = [RCString new]; ovString[1]= [RCString newFromString:bpTestValue]; ovString[2] = [RCString newFromObject:ovString[1]]; [ovString[2] copyReference]; for (j = 0; j < 3; ++j) [ovString[j] empty]; for (j = 0; j < 3; ++j) { if ([ovString[j] length] != 0) { fprintf(stderr, "%s created object: %d refs (should be 1), internal rep 0x%x, length NOT 0 after -empty (%u)\n", method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal], [ovString[j] length]); ++igErrorCount; } [ovString[j] free]; } puts("testing of -toUpper method"); ovString[0] = [RCString new]; ovString[1]= [RCString newFromString:bpTestValue]; ovString[2] = [RCString newFromObject:ovString[1]]; [ovString[2] copyReference]; for (j = 0; j < 3; ++j) [ovString[j] toUpper]; for (j = 0; j < 3; ++j) { int icIndex, iLength = [ovString[j] length]; char *bpData = [ovString[j] data]; for (icIndex = 0; icIndex < iLength; ++icIndex) { if (bpData[icIndex] >= 'a' && bpData[icIndex] <= 'z') { printf( "%s created object: %d refs (should be 1), internal rep 0x%x\n", method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]); printf( "\tProblem with character \'%c\', at index %d, lowercase when it shouldn't be\n", bpData[icIndex], icIndex); ++igErrorCount; break; } } [ovString[j] free]; } puts("testing of -toLower method"); ovString[0] = [RCString new]; ovString[1]= [RCString newFromString:bpTestValue]; ovString[2] = [RCString newFromObject:ovString[1]]; [ovString[2] copyReference]; for (j = 0; j < 3; ++j) [ovString[j] toLower]; for (j = 0; j < 3; ++j) { int icIndex, iLength = [ovString[j] length]; char *bpData = [ovString[j] data]; for (icIndex = 0; icIndex < iLength; ++icIndex) { if (bpData[icIndex] >= 'A' && bpData[icIndex] <= 'Z') { printf( "%s created object: %d refs (should be 1), internal rep 0x%x\n", method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]); printf( "\tProblem with character \'%c\', at index %d, uppercase when it shouldn't be\n", bpData[icIndex], icIndex); ++igErrorCount; break; } } [ovString[j] free]; } puts("testing of case-sensitive -compare methods"); oString1 = [RCString newFromString:bpTestValue]; oString2 = [RCString newFromObject:oString1]; if ([oString1 length] && [oString2 length] && [oString1 compareWithObject:oString2]) { puts("special case (same internal rep) comparison. Should match, but it doesn't"); printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], (unsigned int)[oString2 internal]); ++igErrorCount; } if ([oString1 length] && strlen(bpTestValue) > 0 && [oString1 compareWithString:bpTestValue]) { puts("special case (same ASCIIZ string) comparison. Should match, but it doesn't"); printf("ASCIIZ string: \"%s\", object's string: \"%s\"\n", bpTestValue?bpTestValue:"NULL", [oString1 data]); ++igErrorCount; } // trigger up an object that is guaranteed not to match // _if_ case is considered. { int yUpperCase = 0; int icCount; char *bpData = [oString2 data]; for (icCount = 0; icCount < [oString2 length]; ++icCount) if (bpData[icCount] >= 'A' && bpData[icCount] <= 'Z') { yUpperCase = 1; // there is an uppercase character break; } // these should both force copy-on-write if (yUpperCase) [oString2 toLower]; else [oString2 toUpper]; } if ([oString1 length] && [oString2 length] && ![oString1 compareWithObject:oString2]) { puts("Different internal rep comparison. Shouldn't match, but it does"); printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], (unsigned int)[oString2 internal]); printf("object 1's string: \"%s\", object 2's string: \"%s\"\n", [oString1 data], [oString2 data]); ++igErrorCount; } if ([oString1 length] && strlen(bpTestValue) > 0 && ![oString2 compareWithString:bpTestValue]) { puts("Comparison to ASCIIZ string. Shouldn't match, but it does"); printf("object's string: \"%s\", ASCIIZ string: \"%s\"\n", [oString2 data], bpTestValue); ++igErrorCount; } puts("testing of case-insensitive -compare methods"); [oString1 caseSensitive:NO]; [oString2 caseSensitive:NO]; oString3 = [RCString newFromObject:oString1]; if ([oString1 compareWithObject:oString3]) { puts("special case (same internal rep) comparison. Should match, but it doesn't"); printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], (unsigned int)[oString2 internal]); ++igErrorCount; } if ([oString1 compareWithString:bpTestValue]) { puts("Comparison to ASCIIZ string. Should match, but it doesn't"); printf("object's string: \"%s\", ASCIIZ string: \"%s\"\n", [oString2 data], bpTestValue); ++igErrorCount; } if ([oString1 compareWithObject:oString2]) { puts("Different internal rep comparison. Should match, but it doesn't"); printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], (unsigned int)[oString2 internal]); printf("object 1's string: \"%s\", object 2's string: \"%s\"\n", [oString1 data], [oString2 data]); ++igErrorCount; } if ([oString2 compareWithString:bpTestValue]) { puts("Comparison to ASCIIZ string. Should match, but it doesn't"); printf("object's string: \"%s\", ASCIIZ string: \"%s\"\n", [oString2 data], bpTestValue); ++igErrorCount; } [oString1 free]; [oString2 free]; [oString3 free]; } void insert_test(char *bpBaseString, char *bpToInsert, int index) { RCString *oStringAppend; RCString *oStringPrepend; RCString *oStringMiddle; char *bpTmpBuffer; int icCnt, iSize; iSize = strlen(bpBaseString) + strlen(bpToInsert) + 1; bpTmpBuffer = malloc(iSize); bzero(bpTmpBuffer, iSize); oStringAppend = [RCString newFromString:bpBaseString]; [oStringAppend appendString:bpToInsert]; strcpy(bpTmpBuffer, bpBaseString); strcat(bpTmpBuffer, bpToInsert); if (strcmp(bpTmpBuffer, [oStringAppend data])) { ++igErrorCount; printf("tried to append \"%s\" to \"%s\": should be \"%s\", is \"%s\"\n", bpToInsert, bpBaseString, bpTmpBuffer, [oStringAppend data]); } bzero(bpTmpBuffer, iSize); oStringPrepend = [RCString newFromString:bpBaseString]; [oStringPrepend prependString:bpToInsert]; strcpy(bpTmpBuffer, bpToInsert); strcat(bpTmpBuffer, bpBaseString); if (strcmp(bpTmpBuffer, [oStringPrepend data])) { ++igErrorCount; printf( "tried to prepend \"%s\" to \"%s\": should be \"%s\", is \"%s\"\n", bpToInsert, bpBaseString, bpTmpBuffer, [oStringPrepend data]); } bzero(bpTmpBuffer, iSize); oStringMiddle = [RCString newFromString:bpBaseString]; [oStringMiddle insertString:bpToInsert at:index]; if (index >= 0) { if (index > strlen(bpBaseString)) index = strlen(bpBaseString); for (icCnt = 0; icCnt < index; ++icCnt) bpTmpBuffer[icCnt] = bpBaseString[icCnt]; strcat(&bpTmpBuffer[index], bpToInsert); if (index < strlen(bpBaseString)) strcat(bpTmpBuffer, &bpBaseString[index]); } else { strcat(bpTmpBuffer, bpBaseString); } if (strcmp(bpTmpBuffer, [oStringMiddle data])) { ++igErrorCount; printf("tried to stick \"%s\" in \"%s\": should be \"%s\", is \"%s\"\n", bpToInsert, bpBaseString, bpTmpBuffer, [oStringMiddle data]); } [oStringAppend free]; [oStringPrepend free]; [oStringMiddle free]; free(bpTmpBuffer); } void replace_test() { RCString *o1, *o2; struct srep *sTmp; char *bpOldString, *bpNewString; o1 = [RCString new]; sTmp = [o1 internal]; [o1 replaceWithAsciiString:NULL]; if (sTmp != [o1 internal]) { if (strlen([o1 data]) != 0) { puts("replacing (empty string) object's internal string with a NULL"); ++igErrorCount; } } [o1 free]; bpOldString = getrandomstring(); o1 = [RCString newFromString:bpOldString]; sTmp = [o1 internal]; bpNewString = getrandomstring(); [o1 replaceWithAsciiString:bpNewString]; if (sTmp != [o1 internal]) { if (![o1 compareWithString:bpOldString]) { puts("replacing object's internal string with a another string"); ++igErrorCount; } } [o1 free]; free(bpOldString); free(bpNewString); bpOldString = getrandomstring(); o1 = [RCString newFromString:bpOldString]; o2 = [RCString newFromObject:o1]; bpNewString = getrandomstring(); [o2 replaceWithAsciiString:bpNewString]; if ([o1 internal] == [o2 internal]) { puts("replaceWithAsciiString: failure"); ++igErrorCount; } [o1 replaceWithObject:o2]; if ([o1 internal] != [o2 internal]) { puts("replaceWithObject: failure"); ++igErrorCount; } [o1 free]; [o2 free]; free(bpOldString); free(bpNewString); return; } void retrieve_test() { char *bpTestString = getrandomstring(); RCString *o1 = [RCString newFromString:bpTestString]; if (o1) { char *bpSubString; RCString *oSubObject; int iLength, iMaxLength; // check entire string iMaxLength = strlen(bpTestString); bpSubString = [o1 subStringAt:0 extent:iMaxLength]; if (strcmp(bpSubString, bpTestString)) { puts("comparison of entire string from subStringAt: method failed"); ++igErrorCount; } oSubObject = [o1 subObjectAt:0 extent:iMaxLength]; if (oSubObject) { if ([o1 compareWithObject:oSubObject] || [oSubObject compareWithObject:o1]) { puts("comparison of entire object with subobject failed"); ++igErrorCount; } [oSubObject free]; } else { puts("subObjectAt:extent: method didn't produce an object"); ++igErrorCount; } if (bpSubString) free(bpSubString); // check all substrings, beginning at start of string for (iLength = 1; iLength < iMaxLength; iLength += 10) { bpSubString = [o1 subStringAt:0 extent:iLength]; if (strncmp(bpSubString, bpTestString, iLength)) { printf("substring of length %d, beginning at start of string doesn't match\n", iLength); free(bpSubString); ++igErrorCount; break; } oSubObject = [o1 subObjectAt:0 extent:iLength]; if (oSubObject) { if (strncmp([o1 data], [oSubObject data], iLength)) { puts("comparison of entire object with subobject failed"); printf("comparison of object with subobject for length %d failed", iLength); ++igErrorCount; } [oSubObject free]; } else { printf("subObjectAt:extent: method didn't produce an object for length %d", iLength); ++igErrorCount; } free(bpSubString); } // check all substrings, from end of string for (iLength = iMaxLength; iLength > 1; iLength -= 10) { bpSubString = [o1 subStringAt:(iMaxLength - iLength) extent:iLength]; if (strncmp(bpSubString, &bpTestString[iMaxLength - iLength], iLength)) { printf("substring of length %d, beginning at start of string doesn't match\n", iLength); free(bpSubString); ++igErrorCount; break; } oSubObject = [o1 subObjectAt:(iMaxLength - iLength) extent:iLength]; if (oSubObject) { if (strncmp([oSubObject data], &([o1 data][iMaxLength - iLength]), iLength)) { printf("comparison of object with subobject for length %d failed\n", iLength); ++igErrorCount; } [oSubObject free]; } else { printf("subObjectAt:extent: method didn't produce an object for length %d\n", iLength); ++igErrorCount; } free(bpSubString); } [o1 free]; } free(bpTestString); } #ifdef NeXT int signalHandler(int something) { printf("signalHandler(%d) (0x%x)\n", something, (unsigned int)something); exit(0); } #endif char * getrandomstring() { struct timeval sTimeVal; int iLength, iBegin, icIndex; char *bpRandStr; gettimeofday(&sTimeVal, NULL); iLength = ((sTimeVal.tv_sec % sTimeVal.tv_usec) % 8192); iBegin = (sTimeVal.tv_sec + sTimeVal.tv_usec)%26; bpRandStr = malloc(iLength + 1); if (bpRandStr) { for (icIndex = 0; icIndex < iLength; ++icIndex) bpRandStr[icIndex] = (iBegin++ % 0x5f) + ' '; bpRandStr[iLength] = '\0'; } return bpRandStr; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.