home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / Classes / RCString / tester.m < prev   
Encoding:
Text File  |  1993-01-19  |  19.9 KB  |  702 lines

  1. //
  2. // overall testing of many of the RCString categories.
  3. // has gets() statements to allow checks for dangling
  4. // pointers every so often.
  5. //
  6. #import <stdio.h>
  7. #import <stdlib.h>
  8. #import <signal.h>
  9. #import <fcntl.h>
  10. #import <string.h>
  11. #import <sys/time.h>
  12. #import <RCString.h>
  13.  
  14. int igErrorCount = 0;
  15.  
  16. char *getrandomstring();
  17.  
  18. int
  19. main(int c, char **v)
  20. {
  21.     void xp_test(char *);
  22.     void insert_test(char *bpBaseString, char *bpToInsert, int index);
  23.     void retrieve_test();
  24.     void replace_test();
  25.     char *bvLargeString;
  26.     char buf[512];
  27.     int icCount, iErrorCount, iInsertLocation;
  28.     struct timeval sTimeVal;
  29.  
  30. #ifdef NeXT
  31.     int signalHandler();
  32.  
  33.     // install a few signal handlers
  34.     signal(SIGSEGV, signalHandler);
  35.     signal(SIGBUS,  signalHandler);
  36.     signal(SIGILL,  signalHandler);
  37.  
  38.     // turn on fairly high level of malloc error checking
  39.     malloc_debug(8);
  40. #endif NeXT
  41.  
  42.     if (c > 1)
  43.         gets(buf);
  44.  
  45.     iErrorCount = igErrorCount;
  46.     puts("\ntesting of explicity NULL strings");
  47.     xp_test(NULL);
  48.     if (iErrorCount != igErrorCount)
  49.         printf("committed %d sins\n", igErrorCount - iErrorCount);
  50.     if (c > 1)
  51.         gets(buf);
  52.  
  53.     iErrorCount = igErrorCount;
  54.     puts("\ntesting of zero length strings");
  55.     xp_test("");
  56.     if (iErrorCount != igErrorCount)
  57.         printf("committed %d sins\n", igErrorCount - iErrorCount);
  58.     if (c > 1)
  59.         gets(buf);
  60.  
  61.     iErrorCount = igErrorCount;
  62.     puts("\ntesting of 1-char length strings");
  63.     xp_test("a");
  64.     if (iErrorCount != igErrorCount)
  65.         printf("committed %d sins\n", igErrorCount - iErrorCount);
  66.     if (c > 1)
  67.         gets(buf);
  68.  
  69.     iErrorCount = igErrorCount;
  70.     puts("\ntesting of 2-char length strings");
  71.     xp_test("aB");
  72.     if (iErrorCount != igErrorCount)
  73.         printf("committed %d sins\n", igErrorCount - iErrorCount);
  74.     if (c > 1)
  75.         gets(buf);
  76.  
  77.     iErrorCount = igErrorCount;
  78.     puts("\ntesting of 8973-char length strings");
  79.     bvLargeString = malloc(8974);
  80.     for (icCount = 0; icCount < 8973; ++icCount)
  81.         bvLargeString[icCount] = (icCount % 94) + ' ';
  82.     xp_test(bvLargeString);
  83.     if (iErrorCount != igErrorCount)
  84.         printf("committed %d sins\n", igErrorCount - iErrorCount);
  85.     if (c > 1)
  86.         gets(buf);
  87.  
  88.     if (igErrorCount)
  89.         printf("committed %d sins in allocate/free/empty/compare tests\n",
  90.             igErrorCount);
  91.  
  92.     igErrorCount = 0;
  93.  
  94.     puts("\ntesting inserting null strings into other null strings");
  95.     iErrorCount = igErrorCount;
  96.     // insert_test(char *bpBaseString, char *bpToInsert, int index)
  97.     insert_test("", "", 0);
  98.     insert_test("", "", -1);
  99.     insert_test("", "", 1);
  100.     insert_test("", "", 2);
  101.     if (iErrorCount != igErrorCount)
  102.         printf("null insertion committed %d sins\n", igErrorCount - iErrorCount);
  103.  
  104.     puts("\ntesting inserting null strings into 1-char strings");
  105.     iErrorCount = igErrorCount;
  106.     // insert_test(char *bpBaseString, char *bpToInsert, int index)
  107.     insert_test("", "a", 0);
  108.     insert_test("", "a", -1);
  109.     insert_test("", "a", 1);
  110.     insert_test("B", "", -2);
  111.     insert_test("B", "", -1);
  112.     insert_test("B", "", 0);
  113.     insert_test("B", "", 1);
  114.     insert_test("B", "", 2);
  115.     if (iErrorCount != igErrorCount)
  116.         printf("insertion committed %d sins\n", igErrorCount - iErrorCount);
  117.  
  118.     puts("\ntesting inserting 1-char strings into 1-char strings");
  119.     iErrorCount = igErrorCount;
  120.     // insert_test(char *bpBaseString, char *bpToInsert, int index)
  121.     insert_test("0", "a", -1);
  122.     insert_test("0", "a", 0);
  123.     insert_test("0", "a", 1);
  124.     insert_test("B", "7", -2);
  125.     insert_test("B", "7", -1);
  126.     insert_test("B", "7", 0);
  127.     insert_test("B", "7", 1);
  128.     insert_test("B", "7", 2);
  129.     if (iErrorCount != igErrorCount)
  130.         printf("insertion committed %d sins\n", igErrorCount - iErrorCount);
  131.  
  132.     puts("\ntesting inserting 1-char strings into 2-char strings");
  133.     iErrorCount = igErrorCount;
  134.     // insert_test(char *bpBaseString, char *bpToInsert, int index)
  135.     insert_test("00", "a", -2);
  136.     insert_test("00", "a", -1);
  137.     insert_test("00", "a", 0);
  138.     insert_test("00", "a", 1);
  139.     insert_test("00", "a", 2);
  140.     insert_test("B", "7F", -2);
  141.     insert_test("B", "7F", -1);
  142.     insert_test("B", "7F", 0);
  143.     insert_test("B", "7F", 1);
  144.     insert_test("B", "7F", 2);
  145.     if (iErrorCount != igErrorCount)
  146.         printf("insertion committed %d sins\n", igErrorCount - iErrorCount);
  147.  
  148.     // redo the "large" string
  149.     for (icCount = 0; icCount < 8973; ++icCount)
  150.         bvLargeString[icCount] = (icCount % 94) + ' ';
  151.  
  152.     puts("\ntesting inserting large strings into large strings");
  153.     iErrorCount = igErrorCount;
  154.     insert_test(bvLargeString, bvLargeString, -1);
  155.     insert_test(bvLargeString, bvLargeString, 0);
  156.     insert_test(bvLargeString, bvLargeString, 1);
  157.     insert_test(bvLargeString, bvLargeString, -2);
  158.     insert_test(bvLargeString, bvLargeString, -1);
  159.     insert_test(bvLargeString, bvLargeString, 0);
  160.     insert_test(bvLargeString, bvLargeString, 1);
  161.     insert_test(bvLargeString, bvLargeString, 2);
  162.  
  163.     for (icCount = 0; icCount < 5; ++icCount) {
  164.         gettimeofday(&sTimeVal, NULL);
  165.         iInsertLocation = ((sTimeVal.tv_sec % sTimeVal.tv_usec) % 8973);
  166.         printf("inserting a large string at %d\n", iInsertLocation);
  167.         insert_test(bvLargeString, bvLargeString, iInsertLocation);
  168.     }
  169.     if (iErrorCount != igErrorCount)
  170.         printf("insertion committed %d sins\n", igErrorCount - iErrorCount);
  171.  
  172.     puts("\ntesting replacement methods");
  173.     iErrorCount = igErrorCount;
  174.     replace_test();
  175.     if (iErrorCount != igErrorCount)
  176.         printf("replacement committed %d sins\n", igErrorCount - iErrorCount);
  177.  
  178.     if (c > 1)
  179.         gets(buf);
  180.  
  181.     puts("\ntesting retrieval methods");
  182.     iErrorCount = igErrorCount;
  183.     retrieve_test();
  184.     if (iErrorCount != igErrorCount)
  185.         printf("retrieval committed %d sins\n", igErrorCount - iErrorCount);
  186.  
  187.     printf("committed %d total sins\n", igErrorCount);
  188.  
  189.     if (c > 1)
  190.         gets(buf);
  191.  
  192.     return(0);
  193. }
  194.  
  195. char *method_strings[3] = { "-new           ", "-newFromString:",
  196.     "-newFromObject:" };
  197.  
  198. //
  199. //  allocation, deletion, emptying and comparison tests.
  200. //
  201. void
  202. xp_test(char *bpTestValue)
  203. {
  204.     int i, j;
  205.  
  206.     RCString *oString1, *oString2, *oString3;
  207.     RCString *ovString[3];
  208.     RCString *ovCopies[3];
  209.  
  210.     puts("testing of -new methods");
  211.     oString1 = [RCString new];
  212.     oString2 = [RCString newFromString:bpTestValue];
  213.     oString3 = [RCString newFromObject:oString2];
  214.     [oString3 copyReference];
  215.  
  216.     if (!oString1) {
  217.         fputs(" -new method failed\n", stderr);
  218.         ++igErrorCount;
  219.     }
  220.     if (!oString2) {
  221.         fputs(" -newFromString method failed\n", stderr);
  222.         ++igErrorCount;
  223.     }
  224.     if (!oString3) {
  225.         ++igErrorCount;
  226.         fputs(" -newFromObject method failed\n", stderr);
  227.     }
  228.  
  229.     [oString1 free];
  230.     [oString2 free];
  231.     [oString3 free];
  232.  
  233.     // reference copy counting
  234.     puts("\ntesting of reference counting");
  235.     ovString[0] = [RCString new];
  236.     ovString[1] = [RCString newFromString:bpTestValue];
  237.     ovString[2] = [RCString newFromObject:ovString[1]];
  238.     [ovString[2] copyReference];
  239.  
  240.     for (j = 0; j < 3; ++j) {
  241.         if ([ovString[j] references] != 1) {
  242.             printf("%s created object: %d refs (should be 1), internal rep 0x%x\n",
  243.                 method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]);
  244.             ++igErrorCount;
  245.         }
  246.     }
  247.  
  248.     puts("\ncalling copyReference");
  249.     for (i = 0; i < 5; ++i) {
  250.         for (j = 0; j < 3; ++j) {
  251.             [ovString[j] copyReference];
  252.         }
  253.     }
  254.  
  255.     for (j = 0; j < 3; ++j) {
  256.         if ([ovString[j] references] != 1) {
  257.             printf("%s created object: %d refs (should be 1), internal rep 0x%x\n",
  258.                 method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]);
  259.             ++igErrorCount;
  260.         }
  261.     }
  262.  
  263.     puts("\ncalling newFromObject: on objects that ought have 1 refs");
  264.     for (j = 0; j < 3; ++j)
  265.         ovCopies [j] = [RCString newFromObject:ovString[j]];
  266.  
  267.     for (j = 0; j < 3; ++j) {
  268.         if ([ovString[j] references] != 2 || [ovCopies[j] references] != 2) {
  269.             printf(
  270.             "%s created object: %d refs (should be 2), internal rep 0x%x\n",
  271.             method_strings[j], [ovString[j] references],
  272.             (unsigned int)[ovString[j] internal]);
  273.             printf(
  274.             "copied object: %d refs (should be 2), internal rep 0x%x\n",
  275.             [ovCopies[j] references], (unsigned int)[ovCopies[j] internal]);
  276.             ++igErrorCount;
  277.         }
  278.     }
  279.  
  280.     puts("\ncalling copyReference on object copies");
  281.     for (j = 0; j < 3; ++j)
  282.         [ovCopies [j] copyReference];
  283.  
  284.     for (j = 0; j < 3; ++j) {
  285.         if ([ovString[j] references] != 1 || [ovCopies[j] references] != 1) {
  286.         printf("%s created object: %d refs (should be 1), internal rep 0x%x\n",
  287.             method_strings[j], [ovString[j] references],
  288.             (unsigned int)[ovString[j] internal]);
  289.             printf(
  290.             "copied object: %d refs (should be 1), internal rep 0x%x\n",
  291.             [ovCopies[j] references], (unsigned int)[ovCopies[j] internal]);
  292.  
  293.             ++igErrorCount;
  294.         }
  295.     }
  296.  
  297.     for (j = 0; j < 3; ++j) {
  298.         [ovString[j] free];
  299.         [ovCopies[j] free];
  300.     }
  301.  
  302.     puts("testing of -empty methods");
  303.     ovString[0] = [RCString new];
  304.     ovString[1]= [RCString newFromString:bpTestValue];
  305.     ovString[2] = [RCString newFromObject:ovString[1]];
  306.     [ovString[2] copyReference];
  307.     for (j = 0; j < 3; ++j)
  308.         [ovString[j] empty];
  309.     for (j = 0; j < 3; ++j) {
  310.         if ([ovString[j] length] != 0) {
  311.             fprintf(stderr, 
  312.         "%s created object: %d refs (should be 1), internal rep 0x%x, length NOT 0 after -empty (%u)\n",
  313.             method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal], [ovString[j] length]);
  314.             ++igErrorCount;
  315.         }
  316.         [ovString[j] free];
  317.     }
  318.  
  319.     puts("testing of -toUpper method");
  320.     ovString[0] = [RCString new];
  321.     ovString[1]= [RCString newFromString:bpTestValue];
  322.     ovString[2] = [RCString newFromObject:ovString[1]];
  323.     [ovString[2] copyReference];
  324.     for (j = 0; j < 3; ++j)
  325.         [ovString[j] toUpper];
  326.     for (j = 0; j < 3; ++j) {
  327.         int icIndex, iLength = [ovString[j] length];
  328.         char *bpData = [ovString[j] data];
  329.         for (icIndex = 0; icIndex < iLength; ++icIndex) {
  330.             if (bpData[icIndex] >= 'a' && bpData[icIndex] <= 'z') {
  331.                 printf(
  332. "%s created object: %d refs (should be 1), internal rep 0x%x\n",
  333. method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]);
  334.                 printf(
  335. "\tProblem with character \'%c\', at index %d, lowercase when it shouldn't be\n",
  336.                     bpData[icIndex], icIndex);
  337.                 ++igErrorCount;
  338.                 break;
  339.             }
  340.         }
  341.         [ovString[j] free];
  342.     }
  343.  
  344.     puts("testing of -toLower method");
  345.     ovString[0] = [RCString new];
  346.     ovString[1]= [RCString newFromString:bpTestValue];
  347.     ovString[2] = [RCString newFromObject:ovString[1]];
  348.     [ovString[2] copyReference];
  349.     for (j = 0; j < 3; ++j)
  350.         [ovString[j] toLower];
  351.     for (j = 0; j < 3; ++j) {
  352.         int icIndex, iLength = [ovString[j] length];
  353.         char *bpData = [ovString[j] data];
  354.         for (icIndex = 0; icIndex < iLength; ++icIndex) {
  355.             if (bpData[icIndex] >= 'A' && bpData[icIndex] <= 'Z') {
  356.                 printf(
  357. "%s created object: %d refs (should be 1), internal rep 0x%x\n",
  358. method_strings[j], [ovString[j] references], (unsigned int)[ovString[j] internal]);
  359.                 printf(
  360. "\tProblem with character \'%c\', at index %d, uppercase when it shouldn't be\n",
  361.                     bpData[icIndex], icIndex);
  362.                 ++igErrorCount;
  363.                 break;
  364.             }
  365.         }
  366.         [ovString[j] free];
  367.     }
  368.  
  369.  
  370.     puts("testing of case-sensitive -compare methods");
  371.     oString1 = [RCString newFromString:bpTestValue];
  372.     oString2 = [RCString newFromObject:oString1];
  373.  
  374.     if ([oString1 length] && [oString2 length]
  375.         && [oString1 compareWithObject:oString2]) {
  376.         puts("special case (same internal rep) comparison.  Should match, but it doesn't");
  377.         printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], 
  378.             (unsigned int)[oString2 internal]);
  379.         ++igErrorCount;
  380.     }
  381.     if ([oString1 length] && strlen(bpTestValue) > 0
  382.         && [oString1 compareWithString:bpTestValue]) {
  383.         puts("special case (same ASCIIZ string) comparison.  Should match, but it doesn't");
  384.         printf("ASCIIZ string: \"%s\", object's string: \"%s\"\n",
  385.             bpTestValue?bpTestValue:"NULL", [oString1 data]);
  386.         ++igErrorCount;
  387.     }
  388.  
  389.     // trigger up an object that is guaranteed not to match
  390.     // _if_ case is considered.
  391.     {
  392.         int yUpperCase = 0;
  393.         int icCount;
  394.         char *bpData = [oString2 data];
  395.         for (icCount = 0; icCount < [oString2 length]; ++icCount)
  396.             if (bpData[icCount] >= 'A' && bpData[icCount] <= 'Z') {
  397.                 yUpperCase = 1;  // there is an uppercase character
  398.                 break;
  399.             }
  400.  
  401.         // these should both force copy-on-write
  402.         if (yUpperCase)
  403.             [oString2 toLower];
  404.         else
  405.             [oString2 toUpper];
  406.     }
  407.  
  408.     if ([oString1 length] && [oString2 length] 
  409.         && ![oString1 compareWithObject:oString2]) {
  410.         puts("Different internal rep comparison.  Shouldn't match, but it does");
  411.         printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], 
  412.             (unsigned int)[oString2 internal]);
  413.         printf("object 1's string: \"%s\", object 2's string: \"%s\"\n",
  414.             [oString1 data], [oString2 data]);
  415.         ++igErrorCount;
  416.     }
  417.     if ([oString1 length] && strlen(bpTestValue) > 0
  418.         && ![oString2  compareWithString:bpTestValue]) {
  419.         puts("Comparison to ASCIIZ string.  Shouldn't match, but it does");
  420.         printf("object's string: \"%s\", ASCIIZ string: \"%s\"\n",
  421.             [oString2 data], bpTestValue);
  422.         ++igErrorCount;
  423.     }
  424.  
  425.     puts("testing of case-insensitive -compare methods");
  426.     [oString1 caseSensitive:NO];
  427.     [oString2 caseSensitive:NO];
  428.     oString3 = [RCString newFromObject:oString1];
  429.  
  430.     if ([oString1 compareWithObject:oString3]) {
  431.         puts("special case (same internal rep) comparison.  Should match, but it doesn't");
  432.         printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], 
  433.             (unsigned int)[oString2 internal]);
  434.         ++igErrorCount;
  435.     }
  436.     if ([oString1  compareWithString:bpTestValue]) {
  437.         puts("Comparison to ASCIIZ string.  Should match, but it doesn't");
  438.         printf("object's string: \"%s\", ASCIIZ string: \"%s\"\n",
  439.             [oString2 data], bpTestValue);
  440.         ++igErrorCount;
  441.     }
  442.     if ([oString1 compareWithObject:oString2]) {
  443.         puts("Different internal rep comparison.  Should match, but it doesn't");
  444.         printf("internal reps at 0x%x and 0x%x\n", (unsigned int)[oString1 internal], 
  445.             (unsigned int)[oString2 internal]);
  446.         printf("object 1's string: \"%s\", object 2's string: \"%s\"\n",
  447.             [oString1 data], [oString2 data]);
  448.         ++igErrorCount;
  449.     }
  450.     if ([oString2  compareWithString:bpTestValue]) {
  451.         puts("Comparison to ASCIIZ string.  Should match, but it doesn't");
  452.         printf("object's string: \"%s\", ASCIIZ string: \"%s\"\n",
  453.             [oString2 data], bpTestValue);
  454.         ++igErrorCount;
  455.     }
  456.  
  457.     [oString1 free];
  458.     [oString2 free];
  459.     [oString3 free];
  460.  
  461. }
  462.  
  463. void
  464. insert_test(char *bpBaseString, char *bpToInsert, int index)
  465. {
  466.     RCString       *oStringAppend;
  467.     RCString       *oStringPrepend;
  468.     RCString       *oStringMiddle;
  469.     char *bpTmpBuffer;
  470.     int icCnt, iSize;
  471.  
  472.     iSize = strlen(bpBaseString) + strlen(bpToInsert) + 1;
  473.     bpTmpBuffer = malloc(iSize);
  474.     bzero(bpTmpBuffer, iSize);
  475.  
  476.     oStringAppend = [RCString newFromString:bpBaseString];
  477.     [oStringAppend appendString:bpToInsert];
  478.     strcpy(bpTmpBuffer, bpBaseString);
  479.     strcat(bpTmpBuffer, bpToInsert);
  480.     if (strcmp(bpTmpBuffer, [oStringAppend data])) {
  481.         ++igErrorCount;
  482.         printf("tried to append \"%s\" to \"%s\": should be \"%s\", is \"%s\"\n",
  483.             bpToInsert, bpBaseString, bpTmpBuffer, [oStringAppend data]);
  484.     }
  485.  
  486.     bzero(bpTmpBuffer, iSize);
  487.  
  488.     oStringPrepend = [RCString newFromString:bpBaseString];
  489.     [oStringPrepend prependString:bpToInsert];
  490.     strcpy(bpTmpBuffer, bpToInsert);
  491.     strcat(bpTmpBuffer, bpBaseString);
  492.     if (strcmp(bpTmpBuffer, [oStringPrepend data])) {
  493.         ++igErrorCount;
  494.         printf(
  495.             "tried to prepend \"%s\" to \"%s\": should be \"%s\", is \"%s\"\n",
  496.             bpToInsert, bpBaseString, bpTmpBuffer, [oStringPrepend data]);
  497.     }
  498.  
  499.     bzero(bpTmpBuffer, iSize);
  500.  
  501.     oStringMiddle = [RCString newFromString:bpBaseString];
  502.     [oStringMiddle insertString:bpToInsert at:index];
  503.  
  504.     if (index >= 0) {
  505.         if (index > strlen(bpBaseString))
  506.             index = strlen(bpBaseString);
  507.         for (icCnt = 0; icCnt < index; ++icCnt)
  508.             bpTmpBuffer[icCnt] = bpBaseString[icCnt];
  509.         strcat(&bpTmpBuffer[index], bpToInsert);
  510.         if (index < strlen(bpBaseString))
  511.             strcat(bpTmpBuffer, &bpBaseString[index]);
  512.     } else {
  513.         strcat(bpTmpBuffer, bpBaseString);
  514.     }
  515.  
  516.     if (strcmp(bpTmpBuffer, [oStringMiddle data])) {
  517.         ++igErrorCount;
  518.         printf("tried to stick \"%s\" in \"%s\": should be \"%s\", is \"%s\"\n",
  519.             bpToInsert, bpBaseString, bpTmpBuffer, [oStringMiddle data]);
  520.     }
  521.  
  522.     [oStringAppend free];
  523.     [oStringPrepend free];
  524.     [oStringMiddle free];
  525.     free(bpTmpBuffer);
  526. }
  527.  
  528. void
  529. replace_test()
  530. {
  531.     RCString *o1, *o2;
  532.     struct srep *sTmp;
  533.     char *bpOldString, *bpNewString;
  534.  
  535.     o1 = [RCString new];
  536.     sTmp = [o1 internal];
  537.     [o1 replaceWithAsciiString:NULL];
  538.     if (sTmp != [o1 internal]) {
  539.         if (strlen([o1 data]) != 0) {
  540.             puts("replacing (empty string) object's internal string with a NULL");
  541.             ++igErrorCount;
  542.         }
  543.     }
  544.     [o1 free];
  545.  
  546.     bpOldString = getrandomstring();
  547.     o1 = [RCString newFromString:bpOldString];
  548.     sTmp = [o1 internal];
  549.     bpNewString = getrandomstring();
  550.     [o1 replaceWithAsciiString:bpNewString];
  551.     if (sTmp != [o1 internal]) {
  552.         if (![o1 compareWithString:bpOldString]) {
  553.             puts("replacing object's internal string with a another string");
  554.             ++igErrorCount;
  555.         }
  556.     }
  557.     [o1 free];
  558.     free(bpOldString);
  559.     free(bpNewString);
  560.  
  561.  
  562.     bpOldString = getrandomstring();
  563.     o1 = [RCString newFromString:bpOldString];
  564.     o2 = [RCString newFromObject:o1];
  565.     bpNewString = getrandomstring();
  566.     [o2 replaceWithAsciiString:bpNewString];
  567.  
  568.     if ([o1 internal] == [o2 internal]) {
  569.         puts("replaceWithAsciiString: failure");
  570.         ++igErrorCount;
  571.     }
  572.  
  573.     [o1 replaceWithObject:o2];
  574.     if ([o1 internal] != [o2 internal]) {
  575.         puts("replaceWithObject: failure");
  576.         ++igErrorCount;
  577.     }
  578.  
  579.     [o1 free];
  580.     [o2 free];
  581.     free(bpOldString);
  582.     free(bpNewString);
  583.  
  584.     return;
  585. }
  586.  
  587. void
  588. retrieve_test()
  589. {
  590.     char *bpTestString = getrandomstring();
  591.     RCString *o1 = [RCString newFromString:bpTestString];
  592.  
  593.     if (o1) {
  594.         char *bpSubString;
  595.         RCString *oSubObject;
  596.         int iLength, iMaxLength;
  597.  
  598.         // check entire string
  599.         iMaxLength = strlen(bpTestString);
  600.         bpSubString = [o1 subStringAt:0 extent:iMaxLength];
  601.         if (strcmp(bpSubString, bpTestString)) {
  602.             puts("comparison of entire string from subStringAt: method failed");
  603.             ++igErrorCount;
  604.         }
  605.         oSubObject = [o1 subObjectAt:0 extent:iMaxLength];
  606.         if (oSubObject) {
  607.             if ([o1 compareWithObject:oSubObject]
  608.                 || [oSubObject compareWithObject:o1]) {
  609.                 puts("comparison of entire object with subobject failed");
  610.                 ++igErrorCount;
  611.             }
  612.             [oSubObject free];
  613.         } else {
  614.             puts("subObjectAt:extent: method didn't produce an object");
  615.             ++igErrorCount;
  616.         }
  617.         if (bpSubString) free(bpSubString);
  618.  
  619.         // check all substrings, beginning at start of string
  620.         for (iLength = 1; iLength < iMaxLength; iLength += 10) {
  621.             bpSubString = [o1 subStringAt:0 extent:iLength];
  622.             if (strncmp(bpSubString, bpTestString, iLength)) {
  623.                 printf("substring of length %d, beginning at start of string doesn't match\n", iLength);
  624.                 free(bpSubString);
  625.                 ++igErrorCount;
  626.                 break;
  627.             }
  628.             oSubObject = [o1 subObjectAt:0 extent:iLength];
  629.             if (oSubObject) {
  630.                 if (strncmp([o1 data], [oSubObject data], iLength)) {
  631.                     puts("comparison of entire object with subobject failed");
  632.                     printf("comparison of object with subobject for length %d failed", iLength);
  633.                     ++igErrorCount;
  634.                 }
  635.                 [oSubObject free];
  636.             } else {
  637.                 printf("subObjectAt:extent: method didn't produce an object for length %d", iLength);
  638.                 ++igErrorCount;
  639.             }
  640.             free(bpSubString);
  641.         }
  642.         // check all substrings, from end of string
  643.         for (iLength = iMaxLength; iLength > 1; iLength -= 10) {
  644.             bpSubString = [o1 subStringAt:(iMaxLength - iLength) extent:iLength];
  645.             if (strncmp(bpSubString, &bpTestString[iMaxLength - iLength], iLength)) {
  646.                 printf("substring of length %d, beginning at start of string doesn't match\n", iLength);
  647.                 free(bpSubString);
  648.                 ++igErrorCount;
  649.                 break;
  650.             }
  651.             oSubObject = [o1 subObjectAt:(iMaxLength - iLength) extent:iLength];
  652.             if (oSubObject) {
  653.                 if (strncmp([oSubObject data],
  654.                     &([o1 data][iMaxLength - iLength]), iLength)) {
  655.                     printf("comparison of object with subobject for length %d failed\n", iLength);
  656.                     ++igErrorCount;
  657.                 }
  658.                 [oSubObject free];
  659.             } else {
  660.                 printf("subObjectAt:extent: method didn't produce an object for length %d\n", iLength);
  661.                 ++igErrorCount;
  662.             }
  663.             free(bpSubString);
  664.         }
  665.  
  666.  
  667.         [o1 free];
  668.     }
  669.  
  670.     free(bpTestString);
  671. }
  672.  
  673. #ifdef NeXT
  674. int
  675. signalHandler(int something)
  676. {
  677.     printf("signalHandler(%d) (0x%x)\n", something, (unsigned int)something);
  678.     exit(0);
  679. }
  680. #endif
  681.  
  682. char *
  683. getrandomstring()
  684. {
  685.     struct timeval sTimeVal;
  686.     int iLength, iBegin, icIndex;
  687.     char *bpRandStr;
  688.  
  689.     gettimeofday(&sTimeVal, NULL);
  690.     iLength = ((sTimeVal.tv_sec % sTimeVal.tv_usec) % 8192);
  691.     iBegin = (sTimeVal.tv_sec + sTimeVal.tv_usec)%26;
  692.  
  693.     bpRandStr = malloc(iLength + 1);
  694.     if (bpRandStr) {
  695.         for (icIndex = 0; icIndex < iLength; ++icIndex)
  696.             bpRandStr[icIndex] = (iBegin++ % 0x5f) + ' ';
  697.         bpRandStr[iLength] = '\0';
  698.     }
  699.  
  700.     return bpRandStr;
  701. }
  702.