Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

StringTest.C File Reference

Regression and verification code for the String class. More...

#include <stdio.h>
#include <string.h>
#include "String.h"

Include dependency graph for StringTest.C:

Include dependency graph

Go to the source code of this file.

Functions

void checkRefCntVal (String s, size_t shouldBe, const char *prefix)
 checkRefCntVal: pass by value, where reference count gets incremented by one on entry and decremented by one on exit.

void checkRefCnt (String &s, size_t shouldBe, const char *prefix)
 checkRefCnt: pass by reference.

void test_constructors ()
 test_constructors

void test_char_cast ()
 test_char_cast

void test_assign ()
void test_plus_equal ()
 test_plus_equal

void test_plus ()
 test_plus

void test_relops ()
 test_relops

void test_arrayop ()
 Array reference [] operator tests.

void test_insert ()
 test_insert()

void test_substr_func_valarg (SubString sub, size_t errorNum)
void test_substring ()
 test_substring

void test_resize ()
 test_resize

 main ()


Detailed Description

Regression and verification code for the String class.

No errors should be printed when this code runs.

You really need to run these regression tests before using this code on your system. This code has been tested on a variety of platforms. Although C++ compilers are getting more standard conformant, this the String class uses C++ features which historically been supported differently by different compilers.

Note that the existence of these regression tests does not change that statement this code is provided without waranty. You use this code at your own risk.

I also recommend verifying this code using Purify or a similar memory usage verification tool. This level of pain and difficulty should not be necessary, but hey, its C++.

In an earlier version of the String class the SubString class was included in the same .h file, with some function implementations in String.C.

This version separates the two classes. A set of regression tests (SubStrTest.C) was written for the SubString class. However, for historical reasons, this file also include some tests for SubString, which overlap with the tests in SubStrTest.C.

Compiling this code:

This code is written to compile on Microsoft Visual C++ 6.0 and higher. It will also compile on GNU C++ and Sun's 6.0 and later C++ compilers. To compile under Microsoft VC++:

cl -Zi -TP -GX SubString.C String.C StringTest.C -o StringTest

The -GX flag is needed to support exceptions, which are used rather than the assert() functions in the earlier versions.

Copyright and Use

You may use this source code without limitation and without fee as long as you include:

This software was written and is copyrighted by Ian Kaplan, Bear Products International, www.bearcave.com, 2001.

This software is provided "as is", without any warrenty or claim as to its usefulness. Anyone who uses this source code uses it at their own risk. Nor is any support provided by Ian Kaplan and Bear Products International.

Please send any bug fixes or suggested source changes to:

iank@bearcave.com

Definition in file StringTest.C.


Function Documentation

void checkRefCnt String s,
size_t  shouldBe,
const char *  prefix
 

checkRefCnt: pass by reference.

The reference count in the String object is unchanged, since the object is passed by reference.

Definition at line 87 of file StringTest.C.

References String::getRefCnt().

Referenced by test_constructors().

00088 {
00089   if (s.getRefCnt() != shouldBe)
00090     printf("%s refCnt = %d (should be %d)\n", 
00091            prefix, s.getRefCnt(), shouldBe );
00092 } // checkRefCnt

void checkRefCntVal String  s,
size_t  shouldBe,
const char *  prefix
 

checkRefCntVal: pass by value, where reference count gets incremented by one on entry and decremented by one on exit.

Definition at line 74 of file StringTest.C.

References String::getRefCnt().

Referenced by test_constructors().

00075 {
00076   if (s.getRefCnt() != shouldBe)
00077     printf("%s refCnt = %d (should be %d)\n", 
00078            prefix, s.getRefCnt(), shouldBe );
00079 } // checkRefCntVal

main  ) 
 

Definition at line 1108 of file StringTest.C.

References test_arrayop(), test_assign(), test_char_cast(), test_constructors(), test_insert(), test_plus(), test_plus_equal(), test_relops(), test_resize(), and test_substring().

01109 {
01110   test_constructors();
01111   test_char_cast();
01112   test_assign();
01113   test_plus_equal();
01114   test_plus();
01115   test_relops();
01116   test_arrayop();
01117   test_insert();
01118   test_substring();
01119   test_resize();
01120   return 0;
01121 }

void test_arrayop  ) 
 

Array reference [] operator tests.

There are two versions: left hand size and right hand size array operators. The right hand side version returns a value, the left hand size operator returns an address (to which a value can be assigned).

Definition at line 718 of file StringTest.C.

References String::getRefCnt().

Referenced by main().

00719 {
00720   const char *jabbar     = "He took his vorpal sword in hand";
00721   const char *newJabbar1 = "He took her vorpal sword in hand";
00722   //     index 9   -----------------^
00723   const char *newJabbar2 = "He took her vorpal ruler in hand";
00724   //     index 19  ----------------------------^
00725   const char *newWord = "ruler";
00726 
00727   const size_t len = strlen( jabbar );
00728   String jabbarString( jabbar );
00729   String jabbarRefStr = jabbarString;
00730 
00731   //
00732   // Make sure that integer operators on the RHS work properly
00733   //
00734   if (jabbarString[3] != 't') {
00735     printf("0. string index failed\n");
00736   }
00737 
00738   // make sure than in index operation does not cause a copy
00739   if (jabbarRefStr.getRefCnt() != 2) {
00740     printf("0.5. string index seems to have caused a copy\n");
00741   }
00742 
00743   for (size_t i = 0; i < len; i++) {
00744     char lhsCh = jabbarString[i];
00745     char rhsCh = jabbar[i];
00746     if (lhsCh != rhsCh) {
00747       printf("1. mismatch on rhs String index\n");
00748     }
00749   }
00750 
00751   // references are jabbarString, jabbarRefStr and now, "a"
00752   String a = jabbarString;
00753   if (a.getRefCnt() != 3)
00754     printf("2. reference count is wrong\n");
00755 
00756   a[9] = 'e';
00757   a[10] = 'r';
00758 
00759   // The string has been changed, so a "copy on write" should 
00760   // have taken place.  Now there is a single copy, with the
00761   // change.
00762   if (a.getRefCnt() != 1)
00763     printf("3. 'a' reference count is wrong\n");
00764 
00765   if (jabbarString.getRefCnt() != 2)
00766     printf("4. jabbarString reference count is wrong\n");
00767   
00768   const char *tmp = a;
00769   if (strcmp(tmp, newJabbar1) != 0) {
00770     printf("5. strings don't match: a = %s, should be %s\n",
00771            tmp, newJabbar1 );
00772   }
00773 
00774   // make sure that the original string is unchanged
00775   tmp = jabbarString;
00776   if (strcmp(tmp, jabbar) != 0) {
00777     printf("6. strings don't match: a = %s, should be %s\n",
00778            tmp, jabbar );
00779   }
00780 
00781 } // test_arrayop

void test_assign  ) 
 

Definition at line 179 of file StringTest.C.

References String::getRefCnt().

Referenced by main().

00180 {
00181   printf("Test assignment\n");
00182 
00183   const char *testStr = "my girl is the best";
00184   String a = "abcd";
00185 
00186   const char *tmp = a;
00187 
00188   if (strcmp(tmp, "abcd") != 0)
00189     printf("1. Assignment in declaration failed\n");
00190 
00191   const char *init_b = "this is not it";
00192   String b(init_b);
00193   String original_b;
00194 
00195   original_b = b;
00196 
00197   b = testStr;
00198   if (b.getRefCnt() != 1)
00199     printf("2. reference count for b is wrong\n");
00200 
00201   tmp = b;
00202   if (strcmp(tmp, testStr) != 0)
00203     printf("3. String has incorrect contents\n");
00204 
00205   if (original_b.getRefCnt() != 1)
00206      printf("4. reference count for original_b is wrong\n");
00207 
00208   if (original_b != init_b)
00209      printf("5. modification of b improperly changed original_b\n");
00210 
00211   String c( testStr );
00212   c = b;
00213   if (b.getRefCnt() != 2)
00214     printf("6. reference count is wrong\n");
00215 
00216   const char *nullPtr = 0;
00217   String d;
00218 
00219   if (d != "") {
00220     printf("7. comparision to a null string failed\n");
00221   }
00222 
00223   d = nullPtr;
00224   if (d != "") {
00225     printf("8. assignment of a null C-string failed\n");
00226   }
00227 
00228   d = testStr;
00229   tmp = d;
00230   if (strcmp(tmp, testStr) != 0)
00231     printf("9. String has incorrect contents\n");
00232 
00233   String e = String( testStr );
00234   tmp = e;
00235   if (strcmp(tmp, testStr) != 0)
00236     printf("10. String has incorrect contents\n");
00237 
00238   if (e.getRefCnt() != 1)
00239     printf("11. refCnt is wrong: refCnt = %d, should be 1\n",
00240            e.getRefCnt() );
00241 
00242   const char *constCStr = "1234567890";
00243   const size_t len = sizeof(constCStr) / sizeof(char);
00244   String foo = constCStr;
00245   String bar = foo;
00246   if (foo.getRefCnt() != 2) {
00247     printf("12. refcnt is wrong: refCnt = %d, should be 2\n",
00248            foo.getRefCnt() );
00249   }
00250 
00251   // This makes sure that the [] operator is implemented properly
00252   // and does not cause a "copy-on-write" on a read operation.
00253   bool contentOK = true;
00254   for (size_t i = 0; i < len; i++) {
00255     if (constCStr[i] != foo[i]) {
00256       contentOK = false;
00257       break;
00258     }
00259   }
00260   if (!contentOK) {
00261     printf("13: content is wrong\n");
00262   }
00263   // make sure refCnt is still OK
00264   if (bar.getRefCnt() != 2) {
00265     printf("14. refcnt is wrong: refCnt = %d, should be 2\n",
00266            bar.getRefCnt() );
00267   }
00268 
00269   const char *testStr2 = "null is a lonely number";
00270   String r = testStr2;
00271   String r2 = r;
00272   r = '\0';
00273   if (r != "") {
00274     printf("15. assignment of null character did not result in empty str\n");
00275   }
00276 
00277   if (r2 != testStr2) {
00278     printf("16. null character assignment changed a shared string\n");
00279   }
00280 
00281   if (r2.getRefCnt() != 1) {
00282     printf("17. reference count is wrong\n");
00283   }
00284 
00285   const char *testStr3 = "\"Writing tests is hard!\" said Barbie";
00286   String s = testStr3;
00287   String s2 = s;
00288   s = "";
00289   if (s != "") {
00290     printf("18. assignment of empty string did not result in empty str\n");
00291   }
00292 
00293   if (s2 != testStr3) {
00294     printf("19. empty string assignment changed a shared string\n");
00295   }
00296 
00297   if (s2.getRefCnt() != 1) {
00298     printf("17. reference count is wrong\n");
00299   }
00300 
00301   // Test chained assignment
00302   const char *testStr4 = "working on the chain gang";
00303   String w, x, y;
00304   w = x = y = testStr4;
00305 
00306   if (w != testStr4 ||
00307       x != testStr4 ||
00308       y != testStr4) {
00309     printf("18. chained assignment failed\n");
00310   }
00311 
00312   if (y.getRefCnt() != 3) {
00313     printf("19. reference count in chained assignment is wrong\n");
00314   }
00315 
00316   String z = "still working on the gang";
00317   w = x = y = z;
00318   if (w != x &&
00319       x != y &&
00320       y != z) {
00321     printf("20. chained assignment failed\n");
00322   }
00323 
00324   if (y.getRefCnt() != 4) {
00325     printf("21. reference count in chained assignment is wrong\n");
00326   }
00327 } // test_assign

void test_char_cast  ) 
 

test_char_cast

Definition at line 151 of file StringTest.C.

Referenced by main().

00152 {
00153   printf("Test character cast\n");
00154 
00155   const char *testStr = "the quick brown fox";
00156   String a( testStr );
00157   const char *tmp = a;
00158 
00159   if (tmp == 0)
00160     printf("1. error: result of cast is null\n");
00161   else if (strcmp(testStr, tmp) != 0)
00162     printf("2. error: strings are not equal\n");
00163 
00164 } // test_char_cast

void test_constructors  ) 
 

test_constructors

Definition at line 98 of file StringTest.C.

References checkRefCnt(), checkRefCntVal(), String::getRefCnt(), and String::strlen().

Referenced by main().

00099 {
00100   String a( "abcd" );
00101   String b( a );
00102 
00103   printf("Test String constructors\n");
00104 
00105   if (b.getRefCnt() != 2)
00106     printf("1. Reference count is wrong: refCnt = %d (should be 2)\n",
00107            b.getRefCnt() );
00108 
00109   String c = a;
00110   if (b.getRefCnt() != 3)
00111     printf("2. Reference count is wrong: refCnt = %d (should be 3)\n",
00112            b.getRefCnt() );
00113 
00114   if (a.getRefCnt() != 3)
00115     printf("3. Reference count is wrong: refCnt = %d (should be 3)\n",
00116            b.getRefCnt() );
00117 
00118   checkRefCntVal( a, 4, "4. ");
00119 
00120   if (a.getRefCnt() != 3)
00121     printf("4. Reference count is wrong: refCnt = %d (should be 3)\n",
00122            b.getRefCnt() );
00123 
00124   checkRefCnt( a, 3, "5. ");
00125 
00126   String d( 'd' );
00127 
00128   // test for construction with an empty string
00129   String e;
00130   String f( e );
00131   checkRefCnt( f, 2, "6. ");
00132   checkRefCntVal( f, 3, "7. ");
00133 
00134   // test of a pointer containing null
00135   const char *nullPtr = 0;
00136   String g( nullPtr );
00137 
00138   // test of a null address
00139   String h( (const char *)0 );
00140 
00141   String i( '\0' );
00142   if (i.strlen() != 0) {
00143     printf("8. Adding a null character should not increase length\n");
00144   }
00145 } // test_constructors

void test_insert  ) 
 

test_insert()

In an earlier version of the String object used an explicit insert function to insert a string into another string. This is very much like assigning to a SubString. In the case of an insert the length of the section being replaced is 0.

This code attempts to not only make sure that insert works, but also that insert works for various corner cases (e.g., insert of an empty string or a null C string).

Definition at line 800 of file StringTest.C.

References String::getRefCnt().

Referenced by main().

00801 {
00802   printf("Test string insert\n");
00803 
00804   const char *origA = "abcdefgh";
00805   const char *rslt1 = "abcd1234efgh";
00806   String a(origA);
00807   String b("1234");
00808   String c = a;
00809 
00810   // test insert of a String into a String
00811 
00812   // reference count should be 2, since a and c have the
00813   // same shared data
00814   if (a.getRefCnt() != 2)
00815     printf("1. reference count is wrong\n");
00816 
00817   a(4,0) = b;
00818   // make sure a is "abcd1234efgh"
00819   if (a != rslt1) {
00820     printf("2. insert failed. a = [%s], should be [%s]\n",
00821            (const char *)a, rslt1 );
00822   }
00823 
00824   // a should be unique
00825   if (a.getRefCnt() != 1)
00826     printf("3. reference count in a is wrong\n");
00827 
00828   // c should be unique
00829   if (c.getRefCnt() != 1)
00830     printf("4. reference count in c is wrong\n");
00831 
00832   // The contents of c should be unchanged
00833   if (c != origA)
00834     printf("5. contents of c is wrong\n");
00835 
00836   // test insert of C-string into a String
00837   String d = c;
00838   d(4,0) = "1234";
00839   // make sure d is "abcd1234efgh"
00840   if (d != rslt1) {
00841     printf("6. insert failed. d = [%s], should be [%s]\n",
00842            (const char *)d, rslt1 );
00843   }  
00844 
00845   String c_prime = c;  // reference count is 2
00846 
00847   // test insert of a zero length C string into a String
00848   // (remember, c is still "abcdefgh")
00849   c(4, 0) = "";
00850   // make sure c is "abcdefgh" (e.g., nothing happened)
00851   if (c != origA) {
00852     printf("7. insert failed. c = [%s], should be [%s]\n",
00853            (const char *)c, origA );
00854   }
00855 
00856   // Insert a null string into a String object (should do nothing)
00857   c_prime(4, 0) = (const char *)0;
00858   // make sure that reference count is still 2
00859   if (c.getRefCnt() != 2)
00860     printf("8. c.getRefCnt() = %d, should be 2\n", c.getRefCnt());
00861 
00862   if (c_prime.getRefCnt() != 2)
00863     printf("9. c_prime.getRefCnt() = %d, should be 2\n", c_prime.getRefCnt());
00864 
00865   if (c_prime != origA) {
00866     printf("10. insert failed. c_prime = [%s], should be [%s]\n",
00867            (const char *)c_prime, origA );
00868   }
00869 
00870   // test insert of an empty String into "c", an non-empty string.
00871   String emptyString;
00872 
00873   // try insert at index 0
00874   c(0,0) = emptyString;
00875   // make sure c is "abcdefgh" (e.g., nothing happened)
00876   if (c != origA) {
00877     printf("11. insert failed. c = [%s], should be [%s]\n",
00878            (const char *)c, origA );
00879   }
00880 
00881   // try insert at index 4
00882   c(4,0) = emptyString;
00883   // make sure c is "abcdefgh" (e.g., nothing happened)
00884   if (c != origA) {
00885     printf("12. insert failed. c = [%s], should be [%s]\n",
00886            (const char *)c, origA );
00887   }
00888 } // test_insert

void test_plus  ) 
 

test_plus

Definition at line 435 of file StringTest.C.

References String::getRefCnt().

Referenced by main().

00436 {
00437   printf("Test + operator\n");
00438 
00439   const char *firstHalf = "abcd";
00440   const char *secondHalf = " efgh";
00441   const char *concatStr = "abcd efgh";
00442 
00443   //
00444   // Test String + String
00445   //
00446   String t1( firstHalf );
00447   String t2( secondHalf );
00448   String a = t1 + t2;
00449   if (a.getRefCnt() != 1) {
00450     printf("1. refCnt is wrong: refCnt = %d, should be 1\n",
00451            a.getRefCnt() );
00452   }
00453 
00454   if (strcmp((const char *)a, concatStr) != 0)
00455     printf("2. String contents are not correct: a = %s (should be [%s])\n",
00456            (const char *)a, concatStr );
00457 
00458   //
00459   // Test String + const char *
00460   //
00461   String b = t1 + secondHalf;
00462 
00463   if (b.getRefCnt() != 1) {
00464     printf("3. refCnt is wrong: refCnt = %d, should be 1\n",
00465            b.getRefCnt() );
00466   }
00467 
00468   const char *tmp = b;
00469   if (strcmp(tmp, concatStr) != 0)
00470     printf("4. String contents are not correct: b = %s (should be [%s])\n",
00471            tmp, concatStr );
00472 
00473   //
00474   // test the global String addition operator const char * + String
00475   //
00476   String c = firstHalf + t2;
00477   tmp = c;
00478   if (strcmp(tmp, concatStr) != 0)
00479     printf("5. String contents are not correct: c = %s (should be [%s])\n",
00480            tmp, concatStr );
00481 
00482   //
00483   // Make sure that the operands of the addition are not altered by
00484   // the addition
00485   //
00486   String first( firstHalf );
00487   String second( secondHalf );
00488   String d = first + second;
00489   tmp = first;
00490   if (strcmp(tmp, firstHalf) != 0)
00491     printf("6. first has been altered: first = %s (should be [%s])\n",
00492            tmp, firstHalf );
00493 
00494   tmp = second;
00495   if (strcmp(tmp, secondHalf) != 0)
00496     printf("7. second has been altered: second = %s (should be [%s])\n",
00497            tmp, secondHalf );
00498 
00499   tmp = d;
00500   if (strcmp(tmp, concatStr) != 0)
00501     printf("8. String contents are not correct: d = %s (should be [%s])\n",
00502            tmp, concatStr );
00503 
00504   //
00505   // Test character concatenation.  Here the character operands
00506   // are converted to String objects.
00507   //
00508   String e("12345");
00509   String f;
00510   String g;
00511 
00512   f = e + '6' + '7' + '8' + '9';
00513   g = 'a' + f;
00514 
00515   if (e != "12345")
00516     printf("9. String e changed\n");
00517 
00518   if (f != "123456789") {
00519      const char *tmp = f;
00520      printf("10. String f is %s, it should be \"123456789\"\n", tmp);
00521   }
00522 
00523   if (g != "a123456789")
00524     printf("11. g is incorrect\n");
00525 
00526   // Test addition with chained assignment and string operands
00527   String w( "foo" );
00528   String x( "bar" );
00529   String y;
00530   String z = y = w + x;
00531 
00532   if (y != "foobar") {
00533      const char *tmp = y;
00534      printf("12. String y is %s, it should be \"foobar\"\n", tmp );
00535   }
00536 
00537   if (z != "foobar") {
00538      const char *tmp = z;
00539      printf("13. String z is %s, it should be \"foobar\"\n", tmp );
00540   }
00541 
00542   // The reference counts for w and x should both be 1
00543   if (w.getRefCnt() != 1) {
00544      printf("14. w.getRefCnt() = %d, it should be 1\n", w.getRefCnt() );
00545   }
00546   if (x.getRefCnt() != 1) {
00547      printf("15. x.getRefCnt() = %d, it should be 1\n", x.getRefCnt() );
00548   }
00549 
00550   if (y.getRefCnt() != 2) {
00551      printf("16. y.getRefCnt() = %d, it should be 2\n", y.getRefCnt() );
00552   }
00553   if (z.getRefCnt() != 2) {
00554      printf("17. z.getRefCnt() = %d, it should be 2\n", z.getRefCnt() );
00555   }
00556 } // test_plus

void test_plus_equal  ) 
 

test_plus_equal

Definition at line 333 of file StringTest.C.

References String::getRefCnt().

Referenced by main().

00334 {
00335   const char *firstHalf = "abcd";
00336   const char *secondHalf = " efgh";
00337   const char *concatStr = "abcd efgh";
00338 
00339   printf("Test += operator\n");
00340 
00341   String a( firstHalf );
00342 
00343   a += secondHalf;
00344 
00345   const char *tmp = a;
00346 
00347   if (strcmp(tmp, concatStr) != 0)
00348     printf("1. Strings did not match: str = %s (should be [%s]\n",
00349            tmp, concatStr );
00350 
00351   String b;
00352 
00353   b += firstHalf;
00354   tmp = b;
00355   if (strcmp(tmp, firstHalf) != 0)
00356     printf("2. Strings did not match: str = %s (should be [%s]\n",
00357            tmp, firstHalf );
00358 
00359   String d, c;
00360 
00361   c += d;
00362   if (c.getRefCnt() != 1)
00363     printf("3. refCnt should (still) be 1\n");
00364 
00365   if (d != "" || c != "") {
00366     printf("4. Strings c and d should be the empty string, but are not\n");
00367   }
00368 
00369   c += secondHalf;
00370   tmp = c;
00371   if (strcmp(tmp, secondHalf) != 0)
00372     printf("5. Strings did not match: str = %s (should be [%s]\n",
00373            tmp, secondHalf );
00374 
00375   String e("1234");
00376 
00377   for (size_t i = 5; i < 10; i++) {
00378     e += (char)(i + (char)'0');
00379   }
00380   if (e != "123456789") {
00381     tmp = e;
00382     printf("6. Character concat failed: d = %s, should be 123456789\n",
00383            tmp );
00384   }
00385 
00386   const char *testStr1 = "metal jacket";
00387   String empty;
00388   String full(testStr1);
00389 
00390   empty += full;
00391 
00392   if (empty.getRefCnt() != 1) {
00393     printf("7. empty.getRefCnt() = %d, should be 1\n", empty.getRefCnt() );
00394   }
00395 
00396   if (empty != testStr1) {
00397     printf("8. empty string += String failed\n");
00398   }
00399 
00400   const char *testStr2 = "foo";
00401   String empty2;
00402   const char *str = testStr2;
00403 
00404   empty2 += str;
00405   if (empty2.getRefCnt() != 1) {
00406     printf("9. empty2.getRefCnt() = %d, should be 1\n", empty2.getRefCnt() );
00407   }
00408 
00409   if (empty2 != testStr2) {
00410     printf("10. empty string += C-string failed\n");
00411   }
00412 
00413   // test chained assignment
00414   const char *testStr3 = "twas brillig";
00415   String s1 = "twas ";
00416   String s2 = "brillig";
00417   String s3 = s1 += s2;
00418 
00419   if (s3 != s1 && s1 != testStr3) {
00420     printf("11. chained assignment with += failed\n");
00421   }
00422 
00423   if (s3.getRefCnt() != 2 &&
00424       s1.getRefCnt() != 2 &&
00425       s2.getRefCnt() != 1) {
00426     printf("12. reference count for chained assignment with += failed\n");
00427   }
00428 } // test_plus_equal

void test_relops  ) 
 

test_relops

Test relational operators

Definition at line 567 of file StringTest.C.

Referenced by main().

00568 {
00569   printf("Test relational operators\n");
00570 
00571   const char *less = "abcd";
00572   const char *greater = "wxyz";
00573   const char *equal = "abcd";
00574   String lessString( less );
00575   String greaterString( greater );
00576   String equalString( equal );  // note that equalString == lessString == less
00577   String same;
00578 
00579   same = less;
00580 
00581   //
00582   // ==
00583   //
00584   // String String
00585   //
00586   // Check the case where both strings contain no data
00587   // (and so are equal).
00588   String x, y;  // two empty strings
00589   if (x != y)
00590     printf("0. empty strings are not equal\n");
00591 
00592   if (x != "") {
00593     printf("0.5: String not equal to empty C string\n");
00594   }
00595 
00596   if (! (lessString == equalString))
00597     printf("1. String == String failed\n");
00598 
00599   // String const char *
00600   if (! (lessString == equal))
00601     printf("2. String == const char * failed\n");
00602 
00603   // const char *  String
00604   if (! (equal == lessString))
00605     printf("3. const char * == String failed\n");
00606 
00607   if (! (same == less))
00608     printf("String == String failed for String objs w/same shared data\n");
00609 
00610   //
00611   // !=
00612   //
00613   // String String
00614   if (! (lessString != greaterString))
00615     printf("4. String != String failed\n");
00616 
00617   // String const char *
00618   if (! (lessString != greater))
00619     printf("5. String != const char * failed\n");
00620 
00621   // const char *  String
00622   if (! (less != greaterString))
00623     printf("6. const char * != String failed\n");
00624 
00625   //
00626   // >=
00627   //
00628   // String String
00629   if (! (greaterString >= lessString))
00630     printf("7. String >= String failed for >\n");
00631 
00632   if (! (lessString >= equalString))
00633     printf("8. String >= String failed for ==\n");
00634 
00635   // String const char *
00636   if (! (greaterString >= less))
00637     printf("9. String >= const char * failed for >\n");
00638 
00639   if (! (lessString >= equal))
00640     printf("10. String >= const char * failed ==\n");
00641 
00642   // const char *  String
00643   if (! (greater >= lessString))
00644     printf("11. const char * >= String failed for >\n");
00645 
00646   if (! (equal >= lessString))
00647     printf("12. const char * >= String failed for ==\n");
00648 
00649   //
00650   // <=
00651   //
00652   // String String
00653   if (! (lessString <= greaterString))
00654     printf("13. String <= String failed for <\n");
00655 
00656   if (! (lessString <= equalString))
00657     printf("14. String <= String failed for ==\n");
00658 
00659   // String const char *
00660   if (! (lessString <= greater))
00661     printf("15. String <= const char * failed for <\n");
00662 
00663   if (! (lessString <= equal))
00664     printf("16. String <= const char * failed for ==\n");
00665 
00666   // const char *  String
00667   if (! (less <= greaterString))
00668     printf("17. const char * <= String failed for <\n");
00669 
00670   if (! (equal <= lessString))
00671     printf("18. const char * <= String failed for ==\n");
00672 
00673   //
00674   // >
00675   //
00676   // String String
00677   if (! (greaterString > lessString))
00678     printf("19. String > String failed\n");
00679 
00680   // String const char *
00681   if (! (greaterString > less))
00682     printf("20. String > const char * failed\n");
00683 
00684   // const char *  String
00685   if (! (greater > lessString))
00686     printf("21. const char * > String failed\n");
00687 
00688   //
00689   // <
00690   //
00691   // String String
00692   if (! (lessString < greaterString))
00693     printf("22. String < String failed\n");
00694 
00695   // String const char *
00696   if (! (lessString < greater))
00697     printf("23. String < const char * failed\n");
00698 
00699   // const char *  String
00700   if (! (less < greaterString))
00701     printf("24. const char * < String failed\n");
00702 
00703 } // test_relops

void test_resize  ) 
 

test_resize

Test the String object resize function.

Definition at line 1051 of file StringTest.C.

References String::resize(), and String::strlen().

Referenced by main().

01052 {
01053   const char *init_a = "01234567890123456789";
01054   String a( init_a );
01055   String b = a;
01056   const char *tmp;
01057 
01058   printf("Test resize\n");
01059 
01060   b.resize(10);  // set size of String b to 10
01061   if (b.strlen() != 10)
01062     printf("1. b.strlen() = %d, should be 10\n", b.strlen() );
01063 
01064   if (b != "0123456789") {
01065     tmp = b;
01066     printf("2. b = %s, should be \"0123456789\"\n", tmp );
01067   }
01068 
01069   if (a != init_a)
01070     printf("3. a was improperly modified by resizing b\n");
01071 
01072   if (a.strlen() != 20)
01073     printf("4. a.strlen() = %d, should be 20\n", a.strlen() );
01074 
01075   b.resize(20);
01076   if (b != "0123456789          ") {
01077     tmp = b;
01078     printf("5. b = %s, should be \"0123456789          \"\n", tmp );
01079   }
01080   if (b.strlen() != 20)
01081     printf("6. b.strlen() = %d, should be 20\n", b.strlen() );
01082 
01083   if (a != init_a)
01084     printf("8. resizing b modified a\n");
01085 
01086   b.resize( 0 );
01087 
01088   String empty;
01089 
01090   if (b != empty)
01091     printf("9. b is not the same as the empty string\n");
01092 
01093   if (a != init_a)
01094     printf("10. resizing b modified a\n");
01095 
01096   if (b.strlen() != 0)
01097     printf("11. b.strlen() = %d, should be 0\n", b.strlen() );
01098 
01099   if (b != "") {
01100     printf("12. b should be the same as the empty string\n");
01101   }
01102 
01103 } // test_resize

void test_substr_func_valarg SubString  sub,
size_t  errorNum
 

Definition at line 893 of file StringTest.C.

References SubString::getRefCnt().

Referenced by test_substring().

00894 {
00895   if (sub.getRefCnt() != 1) {
00896     printf("%d. sub.getRefCnt() = %d, should be 1\n", 
00897            errorNum, sub.getRefCnt() );
00898   }
00899 
00900   if (sub != "de") {
00901     printf("%d. sub.string = %s, should be \"de\"\n",
00902            errorNum + 1, (const char *)((String)sub) );
00903   }
00904 } // test_substr_func_valarg

void test_substring  ) 
 

test_substring

Test operations on SubStrings via the String() operator.

These test overlap the SubString class tests. They are here for historical reasons.

Definition at line 917 of file StringTest.C.

References String::getRefCnt(), String::strlen(), and test_substr_func_valarg().

Referenced by main().

00918 {
00919   printf("Test sub-string operations\n");
00920   const char *init_a = "abcdefgh";
00921   String a(init_a);
00922 
00923   if (a(3, 4).getRefCnt() != 1) {
00924     printf("1. reference count is wrong\n");
00925   }
00926 
00927   test_substr_func_valarg( a(3, 2 ), 2 );
00928 
00929   String b = a;
00930 
00931   // b is "abcdefgh
00932   // insert "1234" at position 3
00933   b(3, 4) = "1234";
00934 
00935   if (a != init_a) {
00936     printf("3. \"a\" was altered when b(3, 4) was changed\n");
00937   }
00938 
00939   if (b != "abc1234h") {
00940     printf("4. b = %s, should be \"abc1234h\"\n", (const char *)b);
00941   }
00942 
00943   if (a.getRefCnt() != 1 || b.getRefCnt() != 1) {
00944     printf("5. a.getRefCnt() = %d, b.getRefCnt() = %d (both should be 1)\n",
00945            a.getRefCnt(), b.getRefCnt() );
00946   }
00947 
00948   String c;
00949   c = b(3, 4);
00950   if (c != "1234") {
00951     printf("6. c = %s, should be \"1234\"\n", (const char *)c);
00952   }
00953 
00954   if (c.strlen() != 4) {
00955     printf("7. c.strlen() = %d, should be 4\n", c.strlen());
00956   }
00957 
00958   String d("1234abcdefgh");
00959   String e;
00960 
00961   e = d(4, 8) + d(0, 4); // e = d << 4
00962   if (e != "abcdefgh1234") {
00963     printf("8. e = %s, should be \"abcdefgh1234\"\n", (const char *)e );
00964   }
00965 
00966   if (d != "1234abcdefgh") {
00967     printf("9. d was changed by the SubString operations\n");
00968   }
00969 
00970   if (d.getRefCnt() != 1) {
00971     printf("10. d.getRefCnt() = %d, it should be 1\n", d.getRefCnt());
00972   }
00973 
00974   //
00975   // According to 10.4.10 Temporary Objects in "The C++ Programming
00976   // Language", Third Edition, by Stroustrup:
00977   //
00978   //   Unless bound to a reference or used to initialize a named
00979   //   object, a temporary object is destroyed at the end of teh full
00980   //   expression in which it was created.  A full expression is an
00981   //   expression that is not a subexpression of some other
00982   //   expression.
00983   //
00984   // Stroustrup goes on to provide an example using the Standard
00985   // Template Library (STL) "string" class.  Here the c_str()
00986   // function returns a "C" language string.
00987   //
00988   //    const char* cs = (s1 + s2).c_str().
00989   //
00990   //    A temporary object of class string is created to hold s1+s2.
00991   //    Next, a pointer to a C-style string is extracted from the
00992   //    object.  Then - at the end of the expression - the temporary
00993   //    object is deleted.  Now, where was the C-style string
00994   //    allocated?  Probably as part of the temporary object holding
00995   //    s1+s2, and that storage is not guaranteed to exist after that
00996   //    temporary is destroyted.  Consequently, cs points to
00997   //    deallocated storage.
00998   //
00999   // In the case of the String container, the expression
01000   //
01001   //     e = d(4, 8) + d(0, 4);
01002   // 
01003   // creates a String object temporary, which is assigned to "e"
01004   //
01005   //   <allocate String temporary object CompilerTemp>
01006   //   <CompilerTemp> = d(4, 8) + d(0, 4);
01007   //   e = <CompilerTemp>     Note: at this point getRefCnt = 2
01008   //   <destructor called for CompilerTemp> Note: refCnt decremented
01009   //   next statement
01010   //
01011   // By the time we reach "next statement" the destructor is called
01012   // and the reference counter for "e" is 1, which is what we would
01013   // expect.
01014   //
01015   // If this example does not convience you that C++ is a complicated
01016   // language, nothing will.
01017   //
01018   if (e.getRefCnt() != 1) {
01019     printf("11. e.getRefCnt() = %d, it should be 1\n", e.getRefCnt());
01020   }
01021 
01022   //
01023   // Note that the SubString object created by the () operator is
01024   // a new object and so has a reference count of 1, although the
01025   // String associated with it has a reference count of two.
01026   String z = "lost Z-man";
01027   String y = z; // refCnt is now 2
01028   if (z(5, 5).getRefCnt() != 1) {
01029     printf("12. z(8, 4).getRefCnt() = %d, should be 1\n",
01030            z(8, 4).getRefCnt() );
01031   }
01032 
01033   String f("chopsock");
01034 
01035   f(4, 4) = f(0, 4);
01036   
01037   if (f != "chopchop") {
01038     printf("13. f = %s, should be \"chopchop\"\n", (const char *)f );
01039   }
01040 } // test_substring


Generated on Mon Sep 22 20:23:00 2003 by doxygen 1.3.3