t_string.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : test_string                                                       *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *******************************************************************************
00007 * Copyright (c) 1992-$now By Author.  This program is free software; you can  *
00008 * redistribute it and/or modify it under the terms of the GNU General Public  *
00009 * License as published by the Free Software Foundation; either version 2 of   *
00010 * the License or (at your option) any later version.  This is online at:      *
00011 *     http://www.fsf.org/copyleft/gpl.html                                    *
00012 * Please send any updates to: fred@gruntose.com                               *
00013 \*****************************************************************************/
00014 
00015 #ifndef EMBEDDED_BUILD
00016   #include "t_basis.rh"
00017 #endif
00018 
00019 //#define DEBUG_STRING
00020   // set this to enable debugging features of the string class.
00021 
00022 #include <basis/chaos.h>
00023 #include <basis/earth_time.h>
00024 #include <basis/function.h>
00025 #include <basis/guards.h>
00026 #include <basis/istring.h>
00027 #include <basis/sequence.cpp>
00028 #include <basis/string_array.h>
00029 #include <data_struct/static_memory_gremlin.h>
00030 #include <mechanisms/time_stamp.h>
00031 #include <loggers/file_logger.h>
00032 #include <data_struct/static_memory_gremlin.h>
00033 #include <textual/byte_format.h>
00034 #include <textual/string_convert.h>
00035 #include <textual/string_manipulation.h>
00036 
00037 #ifdef __WIN32__
00038   #include <comdef.h>
00039 #endif
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 
00044 HOOPLE_STARTUP_CODE;
00045 
00046 using namespace earth_time;
00047 
00048 chaos rando;
00049 
00050 //#define DEBUG_STRING_TEST
00051   // uncomment for testing version.
00052 
00053 #define out program_wide_logger()
00054 #define static_class_name() "t_istring"
00055 
00056 const int TEST_RUNTIME_DEFAULT = .5 * MINUTE_ms;
00057   // the test, by default, will run for this long.
00058 
00059 #define WHERE __WHERE__.s()
00060 
00061 //hmmm: this is really awful.  get a better macro...
00062 // test: reports an error if the condition evaluates to true.
00063 int compnum = 0;
00064 #define test(expr) \
00065   compnum++; \
00066   if (expr) { \
00067     istring fred(istring::SPRINTF, "operator test %d did not work", ++compnum); \
00068     deadly_error(WHERE, func, fred.observe()); \
00069   }
00070 
00071 static istring staticity_test("yo!");
00072   // used below to check whether static strings are looking right.
00073 
00074 void run_test_01()
00075 {
00076   FUNCDEF("run_test_01");
00077 
00078   const int TEST_EMPTY = 10000000;
00079   time_stamp started;
00080   for (int i = 0; i < TEST_EMPTY; i++) {
00081     istring glob = istring::empty_string();
00082   }
00083   int duration = int(time_stamp().value() - started.value());
00084   out.log(isprintf("duration of empty string test=%d ms", duration));
00085 
00086   // test simple string operations, like construction, length, equality.
00087   istring fred1("hyeargh!");
00088   istring fred2("matey.");
00089   istring fred3;
00090   fred3 = fred1;
00091   fred3 += fred2;
00092   istring fred4(fred2);
00093 
00094   if (fred1.length() != int(strlen(fred1.s())))
00095     deadly_error(WHERE, func, "length is incorrect (a).");
00096   if (fred2.length() != int(strlen(fred2.s())))
00097     deadly_error(WHERE, func, "length is incorrect (b).");
00098   if (fred3.length() != int(strlen(fred3.s())))
00099     deadly_error(WHERE, func, "length is incorrect (c).");
00100   if (fred4.length() != int(strlen(fred4.s())))
00101     deadly_error(WHERE, func, "length is incorrect (d).");
00102 
00103 #ifdef DEBUG_STRING_TEST
00104   out.log("[ " + fred1 + " & " + fred2 + "] -> " + fred3);
00105 #endif
00106 
00107   if (fred1 != istring("hyeargh!")) 
00108     deadly_error(WHERE, func, "failure in comparison (a).");
00109   if (fred2 != istring("matey."))
00110     deadly_error(WHERE, func, "failure in comparison (b).");
00111   if (fred3 != istring("hyeargh!matey."))
00112     deadly_error(WHERE, func, "failure in comparison (c).");
00113   if (fred4 != istring("matey."))
00114     deadly_error(WHERE, func, "failure in comparison (d-1).");
00115   if (fred4 != fred2)
00116     deadly_error(WHERE, func, "failure in comparison (d-2).");
00117 
00118   isprintf nullo;
00119   if ( (nullo != istring()) || (istring() != nullo) )
00120     deadly_error(WHERE, func, "blank isprintf isn't blank.");
00121   if ( (nullo != istring::empty_string())
00122       || (istring::empty_string() != nullo) )
00123     deadly_error(WHERE, func, "blank isprintf isn't empty.");
00124 
00125 }
00126 
00127 void run_test_02()
00128 {
00129   FUNCDEF("run_test_02");
00130   // assorted tests involving strings as pointers.
00131   istring *fred1 = new istring("flipper ate");
00132   istring *fred2 = new istring(" my sandwich.");
00133   istring *fred3 = new istring;
00134   *fred3 = *fred1;
00135   *fred3 += *fred2;
00136 
00137   // testing adding a null to a string.
00138   *fred2 += (char *)NIL;
00139   *fred3 += (char *)NIL;
00140 
00141 #ifdef DEBUG_STRING_TEST
00142   out.log(istring("[ ") + *fred1 + " & " + *fred2 + "] -> " + *fred3);
00143 #endif
00144 
00145   int die = false;
00146   if (*fred1 != istring("flipper ate")) die++;
00147   if (*fred2 != istring(" my sandwich.")) die++;
00148   if (*fred3 != istring("flipper ate my sandwich.")) die++;
00149   if (die) deadly_error(WHERE, func, "failure in comparison");
00150   delete fred1;
00151   delete fred2;
00152   delete fred3;
00153 }
00154 
00155 void run_test_03()
00156 {
00157   FUNCDEF("run_test_03");
00158   // tests some things about zap.
00159   istring fleermipe("hello my frobious.");
00160   fleermipe.zap(0, fleermipe.length() - 1);
00161   if (fleermipe.length() != 0)
00162     deadly_error(WHERE, func, "length not 0 after deleting entire istring");
00163 }
00164 
00165 void run_test_04()
00166 {
00167   FUNCDEF("run_test_04");
00168   istring test_string("this test string will be chopped up.");
00169 #ifdef DEBUG_STRING_TEST
00170   out.log(istring("original is: ") + test_string);
00171 #endif
00172   istring fred(test_string.s());
00173   fred.zap(0, fred.find('w'));
00174 
00175 #ifdef DEBUG_STRING_TEST
00176   out.log(istring("now, the one chopped through 'w' is: ") + fred);
00177 #endif
00178 
00179   if (fred != istring("ill be chopped up."))
00180     deadly_error(WHERE, func, "first zap failed");
00181 
00182   istring blorg(test_string);
00183   blorg.zap(blorg.find('p'), blorg.length() - 1);
00184 #ifdef DEBUG_STRING_TEST
00185   out.log(istring("now the one chopped from p to the end: ") + blorg);
00186 #endif
00187 
00188   if (blorg != istring("this test string will be cho"))
00189     deadly_error(WHERE, func, "second zap failed");
00190 
00191   istring fleen;
00192   fleen += test_string;
00193   fleen.zap(7, 14);
00194 #ifdef DEBUG_STRING_TEST
00195   out.log(istring("now the one with 7 through 14 missing: ") + fleen);
00196 #endif
00197 
00198   if (fleen != istring("this teg will be chopped up."))
00199     deadly_error(WHERE, func, "third zap failed");
00200 
00201 #ifdef DEBUG_STRING_TEST
00202   out.log(istring("original istring is now: ") + test_string);
00203 #endif
00204   if (test_string != istring("this test string will be chopped up."))
00205     deadly_error(WHERE, func, "original istring was changed");
00206 }
00207 
00208 void run_test_05()
00209 {
00210   FUNCDEF("run_test_05");
00211 #ifdef DEBUG_STRING_TEST
00212   out.log("about to test weird things:");
00213 #endif
00214   istring frieda("glorp");
00215   istring jorb(frieda);
00216   istring *kleeg = new istring(jorb.s());
00217   istring plok = frieda;
00218   test(frieda != jorb);
00219   test(jorb != *kleeg);
00220   test(*kleeg != plok);
00221   test(plok != frieda);
00222   istring glorp("glorp");
00223   test(frieda != glorp);
00224 
00225   WHACK(kleeg);
00226 
00227 #ifdef DEBUG_STRING_TEST
00228   out.log("strings matched up okay.");
00229 #endif
00230 
00231   // test new features sprintf is relying upon.
00232   istring bubba("gumpternations");
00233   bubba += "_02193";
00234 #ifdef DEBUG_STRING_TEST
00235   out.log(istring("bubba = ") + bubba);
00236 #endif
00237   if (bubba != istring("gumpternations_02193"))
00238     deadly_error(WHERE, func, "+= on char pointer failed.");
00239 
00240   istring bubelah("laksos");
00241   bubelah += '3';
00242   bubelah += '8';
00243   bubelah += '2';
00244 #ifdef DEBUG_STRING_TEST
00245   out.log(istring("bubelah = ") + bubelah);
00246 #endif
00247   if (bubelah != istring("laksos382"))
00248     deadly_error(WHERE, func, "+= on char failed.");
00249 
00250   istring simple_spr0(istring::SPRINTF, "%% yoga splorch %%");
00251 #ifdef DEBUG_STRING_TEST
00252   out.log(istring("simple sprintf 0 = ") + simple_spr0);
00253 #endif
00254   if (simple_spr0 != istring("% yoga splorch %"))
00255     deadly_error(WHERE, func, "simple sprintf 0 is wrong");
00256   istring simple_spr1(istring::SPRINTF, "%d", 23);
00257 #ifdef DEBUG_STRING_TEST
00258   out.log(istring("simple sprintf 1 = ") + simple_spr1);
00259 #endif
00260   if (simple_spr1 != istring("23"))
00261     deadly_error(WHERE, func, "simple sprintf 1 is wrong");
00262   istring simple_spr2(istring::SPRINTF, "%s", "yoyo");
00263 #ifdef DEBUG_STRING_TEST
00264   out.log(istring("simple sprintf 2 = ") + simple_spr2);
00265 #endif
00266   if (simple_spr2 != istring("yoyo"))
00267     deadly_error(WHERE, func, "simple sprintf 2 is wrong");
00268 
00269   istring sprintest(istring::SPRINTF, "%s has got me up the %s some %d "
00270      "times, in %p with %d and %lu.", "marge", "ladder", 32, &kleeg,
00271      812377487L, 213123123L);
00272   istring sprintest2;
00273   sprintest2.reset(istring::SPRINTF, "%s has got me up the %s some %d "
00274      "times, in %p with %d and %lu.", "marge", "ladder", 32, &kleeg,
00275      812377487L, 213123123L);
00276   istring addr(istring::SPRINTF, "%p", &kleeg);
00277 #ifdef DEBUG_STRING_TEST
00278   out.log("here is your istring sir...");
00279   out.log(sprintest);
00280   out.log("and addr we will see is...");
00281   out.log(addr);
00282 #endif
00283   if (sprintest != istring(istring::SPRINTF, "marge has got me up the "
00284       "ladder some 32 times, in %s with 812377487 and 213123123.", addr.s()))
00285     deadly_error(WHERE, func, "constructed istring is wrong");
00286   if (sprintest2 != istring(istring::SPRINTF, "marge has got me up the "
00287       "ladder some 32 times, in %s with 812377487 and 213123123.", addr.s()))
00288     deadly_error(WHERE, func, "reset istring is wrong");
00289 }
00290 
00291 void run_test_06()
00292 {
00293   FUNCDEF("run_test_06");
00294   istring bungee;
00295   bungee += "this istring";
00296   bungee += " has been constructed gradua";
00297   bungee += 'l';
00298   bungee += 'l';
00299   bungee += 'y';
00300   istring blorpun(istring::SPRINTF, " out of severa%c", 'l');
00301   bungee += blorpun;
00302   bungee += " different bits,\nincluding";
00303   istring freeple(istring::SPRINTF, "%s constructed %s blarg from %f ", " this", "silly", 3.14159265358);
00304   bungee += freeple;
00305   bungee += "radians awa";
00306   bungee += 'y';
00307   bungee += '.';
00308   bungee += "\nhow does it look?\n";
00309 #ifdef DEBUG_STRING_TEST
00310   out.log(bungee);
00311 #endif
00312 
00313 //MessageBox(0, bungee.s(), "yo, got this", MB_ICONINFORMATION | MB_OK);
00314   if (bungee != istring("this istring has been constructed gradually out of several different bits,\nincluding this constructed silly blarg from 3.141593 radians away.\nhow does it look?\n"))
00315     deadly_error(WHERE, func, "constructed istring is wrong");
00316 }
00317 
00318 void run_test_07()
00319 {
00320   FUNCDEF("run_test_07");
00321   istring a("axes");
00322   istring b("bakesales");
00323   istring x("xylophone");
00324 
00325   test(a >= x);
00326   test(a == b);
00327   test(a > b);
00328   test(b >= x);
00329   test(x <= a);
00330   test(x != x);
00331   test(a != a);
00332 #ifdef DEBUG_STRING_TEST
00333   out.log("comparisons worked");
00334 #endif
00335 }
00336 
00337 void run_test_08()
00338 {
00339   FUNCDEF("run_test_08");
00340 #ifdef DEBUG_STRING_TEST
00341   out.log("now testing + operator");
00342 #endif
00343   istring a("fred");
00344   istring b(" is");
00345   istring c(" his");
00346   istring d(" name.");
00347   istring e;
00348   e = a + b + c + d;
00349 #ifdef DEBUG_STRING_TEST
00350   out.log(istring("result is: ") + e);
00351 #endif
00352   istring f;
00353   f = d + c + b + a;
00354 #ifdef DEBUG_STRING_TEST
00355   out.log(istring("reverse is: ") + f);
00356 #endif
00357   istring g;
00358   g = a + c + d + b;
00359 #ifdef DEBUG_STRING_TEST
00360   out.log(istring("tibetan style is: ") + g);
00361 #endif
00362   int die = false;
00363   if (e != istring("fred is his name.")) die++;
00364   if (f != istring(" name. his isfred")) die++;
00365   if (g != istring("fred his name. is")) die++;
00366   if (die) deadly_error(WHERE, func, "istring looks wrong");
00367 }
00368 
00369 void run_test_09()
00370 {
00371   FUNCDEF("run_test_09");
00372   istring bleer(istring::SPRINTF, "urghla burgla #%d\n", 23);
00373   char holder[50];
00374   for (int i = 0; i < bleer.length(); i++) {
00375     bleer.stuff(holder, i);
00376 #ifdef DEBUG_STRING_TEST
00377     out.log(istring(istring::SPRINTF, "%d", i) + " has: " + holder);
00378 #endif
00379     istring my_copy(bleer);
00380     my_copy.zap(i, bleer.length() - 1);
00381     if (my_copy != istring(holder))
00382       deadly_error(WHERE, func, "inaccurate stuff");
00383   }
00384 }
00385 
00386 void run_test_10()
00387 {
00388   FUNCDEF("run_test_10");
00389 #ifdef DEBUG_STRING_TEST
00390   out.log("The tenth ones:");
00391 #endif
00392   istring george("this one will be mangled.");
00393   if (george.length() != int(strlen(george.s())))
00394     deadly_error(WHERE, func, "length is incorrect (q).");
00395   istring tmp1(george.substring(1, 7));  // constructor.
00396   istring tmp2 = george.substring(10, george.length() - 1);  // constructor.
00397 #ifdef DEBUG_STRING_TEST
00398   out.log(tmp1 + "... " + tmp2);
00399 #endif
00400   if (tmp1 == tmp2)
00401     deadly_error(WHERE, func, "bizarre equality occurred!!");
00402   if ( (tmp1 > tmp2) || (tmp2 < tmp1) )
00403     deadly_error(WHERE, func, "bizarre comparison error.");
00404   if (george.length() != int(strlen(george.s())))
00405     deadly_error(WHERE, func, "length is incorrect (z).");
00406 #ifdef DEBUG_STRING_TEST
00407   out.log(george.substring(1, 7));
00408   out.log("... ");
00409   out.log(george.substring(10, george.length() - 1));
00410 #endif
00411   if (george.length() != int(strlen(george.s())))
00412     deadly_error(WHERE, func, "length is incorrect (a).");
00413   george.insert(14, "terribly ");
00414   if (george.length() != int(strlen(george.s())))
00415     deadly_error(WHERE, func, "length is incorrect (b).");
00416 #ifdef DEBUG_STRING_TEST
00417   out.log(george);
00418 #endif
00419   istring chunky;
00420   istring mssr_boef_la_tet("eeyoy eye eye capn");
00421   mssr_boef_la_tet.substring(chunky, 2, 7);
00422   if (chunky != "yoy ey")
00423     deadly_error(WHERE, func, "contents wrong after substring");
00424 
00425   istring fred(george);
00426   if (!george.compare(fred, 0, 0, george.length() - 1))
00427     deadly_error(WHERE, func, "did not work");
00428   if (!george.compare(fred, 8, 8, george.length() - 1 - 8))
00429     deadly_error(WHERE, func, "partial did not work");
00430 
00431   if (george.length() != int(strlen(george.s())))
00432     deadly_error(WHERE, func, "length is incorrect (c).");
00433   george.zap(14, 22);
00434 #ifdef DEBUG_STRING_TEST
00435   out.log(george);
00436 #endif
00437   istring fred_part;
00438   fred_part = fred.substring(0, 13);
00439   if (fred_part.length() != int(strlen(fred_part.s())))
00440     deadly_error(WHERE, func, "length incorrect (d).");
00441   if (!george.compare(fred_part, 0, 0, 13))
00442     deadly_error(WHERE, func, "did not work");
00443   fred_part = fred.substring(23, fred.length() - 1);
00444   if (fred_part.length() != int(strlen(fred_part.s())))
00445     deadly_error(WHERE, func, "length incorrect (e).");
00446   if (!george.compare(fred_part, 14, 0, fred_part.length() - 1))
00447     deadly_error(WHERE, func, "did not work");
00448 #ifdef DEBUG_STRING_TEST
00449   out.log("compares okay");
00450 #endif
00451 }
00452 
00453 void run_test_11()
00454 {
00455   FUNCDEF("run_test_11");
00456   istring empty;
00457   if (empty.length())
00458     deadly_error(WHERE, func, "empty string judged not");
00459   if (! (!empty.length()) )
00460     deadly_error(WHERE, func, "not on empty string doesn't work");
00461   istring non_empty("grungee");
00462   if (!non_empty.length())
00463     deadly_error(WHERE, func, "non-empty string judged empty");
00464   if (! (! (!non_empty.length()) ) )
00465     deadly_error(WHERE, func, "not on non-empty string doesn't work");
00466 }
00467 
00468 void run_test_12()
00469 {
00470   FUNCDEF("run_test_12");
00471   istring elf0(istring::SPRINTF, "%%_%%_%%");
00472   if (strcmp(elf0.s(), "%_%_%"))
00473     deadly_error(WHERE, func, "failed %% printing");
00474 
00475   char fred[6] = { 'h', 'y', 'a', 'r', 'g', '\0' };
00476   istring fred_copy(istring::UNTERMINATED, fred, 5);
00477   if (fred_copy.length() != 5)
00478     deadly_error(WHERE, func, "length of copy is wrong");
00479   if (fred_copy != istring("hyarg"))
00480     deadly_error(WHERE, func, "length of copy is wrong");
00481 
00482   char hugh[6] = { 'o', 'y', 'o', 'b', 'o', 'y' };
00483   istring hugh_copy(istring::UNTERMINATED, hugh, 3);
00484   if (hugh_copy.length() != 3)
00485     deadly_error(WHERE, func, "length of copy is wrong");
00486   if (hugh_copy != istring("oyo"))
00487     deadly_error(WHERE, func, "length of copy is wrong");
00488 
00489   istring another_copy;
00490   another_copy.reset(istring::UNTERMINATED, fred, strlen(fred));
00491   if (another_copy.length() != 5)
00492     deadly_error(WHERE, func, "length of reset copy is wrong");
00493   if (another_copy != istring("hyarg"))
00494     deadly_error(WHERE, func, "length of reset copy is wrong");
00495 }
00496 
00497 void run_test_13()
00498 {
00499   FUNCDEF("run_test_13");
00500   // check for possible memory leaks in these combined ops....  13th.
00501   const istring churg("borjh sjh oiweoklj");
00502   istring pud = churg;
00503   istring flug = "kase iqk aksjir kljasdo";
00504   const char *nerf = "ausd qwoeui sof zjh qwei";
00505   istring snorp = nerf;
00506   pud = "snugbo";
00507   snorp = flug;
00508   istring pundit("murph");
00509   pundit = nerf;
00510 }
00511 
00512 void run_test_14()
00513 {
00514   FUNCDEF("run_test_14");
00515   // test the new dynamic sprintf'ing for long strings... 14th.
00516   const int longish_size = 5000;
00517   char temp[longish_size];
00518   for (int i = 0; i < longish_size; i++)
00519     temp[i] = char(rando.inclusive(1, 255));
00520   temp[longish_size - 1] = '\0';
00521   istring longish(istring::SPRINTF, "this is a really darned long string of stuff: %s,\nbut doesn't it look interesting?", temp);
00522   // still with us?
00523   longish.zap(longish.length() / 3, 2 * longish.length() / 3);
00524   longish += longish;
00525   if (longish.length() != int(strlen(longish.s())))
00526     deadly_error(WHERE, func, "length is incorrect.");
00527 }
00528 
00529 void run_test_15()
00530 {
00531   FUNCDEF("run_test_15");
00532   // test the new dynamic sprintf'ing for long strings... 15th.
00533   int try_1 = 32767;
00534   istring testy(istring::SPRINTF, "%d", try_1);
00535   if (testy.convert(95) == 95)
00536     deadly_error(WHERE, func, "default value returned, so it failed.");
00537   else if (testy.convert(95) != try_1)
00538     deadly_error(WHERE, func, "correct value was not returned.");
00539 
00540   long try_2 = 2938754L;
00541   testy = istring(istring::SPRINTF, "%ld", try_2);
00542   if (testy.convert(98L) == 98L)
00543     deadly_error(WHERE, func, "default value returned, so it failed.");
00544   else if (testy.convert(98L) != try_2)
00545     deadly_error(WHERE, func, "correct value was not returned.");
00546 
00547   testy = istring(istring::SPRINTF, "%ld", try_2);
00548   if (testy.convert(98L) == 98L)
00549     deadly_error(WHERE, func, "default value returned, so it failed.");
00550   else if (testy.convert(98L) != try_2)
00551     deadly_error(WHERE, func, "correct value was not returned.");
00552 
00553 #ifndef EMBEDDED_BUILD  // until float support added in (blocked out 3/8/96).
00554   float try_3 = float(2938.754);  // weird msvcpp error if don't cast.
00555   testy = istring(istring::SPRINTF, "%f", try_3);
00556   float found = testy.convert(float(98.6));
00557   if (found == 98.6)
00558     deadly_error(WHERE, func, "default value returned, so it failed.");
00559   else if (found != try_3)
00560     deadly_error(WHERE, func, "correct value was not returned.");
00561 
00562   {
00563     double try_4 = 25598437.712385;
00564     testy = istring(istring::SPRINTF, "%f", try_4);
00565     double found2 = testy.convert(double(98.6));
00566     if (found2 == 98.6)
00567       deadly_error(WHERE, func, "default value returned, so it failed.");
00568     else if (found2 != try_4)
00569       deadly_error(WHERE, func, "correct value was not returned.");
00570   }
00571 
00572   {
00573     double try_4 = 25598437.712385e38;
00574     testy = istring(istring::SPRINTF, "%f", try_4);
00575     double found2 = testy.convert(double(98.6));
00576     if (found2 == 98.6)
00577       deadly_error(WHERE, func, "default value returned, so it failed.");
00578     else if (found2 != try_4)
00579       deadly_error(WHERE, func, "correct value was not returned.");
00580   }
00581 #endif
00582 }
00583 
00584 void run_test_16()
00585 {
00586   FUNCDEF("run_test_16");
00587   // the 16th test group tests boundary checking.
00588   istring gorf("abc");
00589   for (int i = -3; i < 25; i++) gorf[i] = 't';
00590   if (gorf != istring("ttt"))
00591     deadly_error(WHERE, func, "correct value was not returned (a).");
00592   if (gorf.length() != 3)
00593     deadly_error(WHERE, func, "length is incorrect (a).");
00594   gorf.insert(3, istring("bru"));
00595   if (gorf != istring("tttbru"))
00596     deadly_error(WHERE, func, "correct value was not returned (b).");
00597   if (gorf.length() != 6)
00598     deadly_error(WHERE, func, "length is incorrect (b).");
00599   gorf.insert(35, istring("snu"));
00600   if (gorf != istring("tttbru"))
00601     deadly_error(WHERE, func, "correct value was not returned (c).");
00602   if (gorf.length() != 6)
00603     deadly_error(WHERE, func, "length is incorrect (c).");
00604   gorf.insert(-30, istring("eep"));
00605   if (gorf != istring("tttbru"))
00606     deadly_error(WHERE, func, "correct value was not returned (d).");
00607   if (gorf.length() != 6)
00608     deadly_error(WHERE, func, "length is incorrect (d).");
00609 }
00610 
00611 void run_test_17()
00612 {
00613   FUNCDEF("run_test_17");
00614   // 17th test checks construction of temporaries.
00615 /* this test set causes the obnoxious 16 bit codeguard error from hell, as
00616    does use of temporary objects in ostream << operators.  argh! */
00617   istring("jubjo");
00618   istring("obo");
00619   istring("flrrpominort").substring(3, 6);
00620 }
00621 
00622 void run_test_18()
00623 {
00624   FUNCDEF("run_test_18");
00625   // 18th test group checks windows related functions.
00626 #ifdef AFXDLL
00627   AfxSetResourceHandle(GET_INSTANCE_HANDLE());
00628     // required for mfc to see the proper instance handle.
00629 
00630   // this tests the "constructor from resource".
00631   istring libname = rc_string(IDS_BASIS_NAME);
00632   if (libname != istring("Basis Library"))
00633     deadly_error(WHERE, func, 
00634         (istring("library name is a mismatch: comes out as \"")
00635              + libname + istring("\".")).s());
00636   #define IDS_SOME_BAD_UNKNOWN_STRING_HANDLE 30802
00637   istring bogus_name = rc_string(IDS_SOME_BAD_UNKNOWN_STRING_HANDLE);
00638   if (bogus_name.length())
00639     deadly_error(WHERE, func, "bogus rc string had length");
00640 
00641   // tests conversions from CString to istring and back.
00642   istring george("yo yo yo");
00643   CString hal = convert(george);
00644   istring borgia = convert(hal);
00645 
00646 #ifdef DEBUG_STRING_TEST
00647   out.log(istring("cstringy conversions: ") + george);
00648   out.log((const char *)hal);
00649   out.log(borgia);
00650 #endif
00651 
00652   if (borgia != george)
00653     deadly_error(WHERE, func, "got the wrong value");
00654 #endif
00655 }
00656 
00657 void run_test_19()
00658 {
00659   FUNCDEF("run_test_19");
00660   // 19th test group is devoted to anthony wenzel's % printing bug.
00661   istring problematic_example(istring::SPRINTF, "this should have %d% more "
00662       "stuffing than before!", 20);
00663 //MessageBox(0, istring("got a string of \"%s!\"", problematic_example.s()).s(), "yo!", MB_OK);
00664   if (problematic_example != istring("this should have 20% more stuffing than before!"))
00665     deadly_error(WHERE, func, "failure to print correct phrase");
00666 }
00667 
00668 void run_test_20()
00669 {
00670   FUNCDEF("run_test_20");
00671   // 20th test group is devoted to another wenzelbug.
00672 
00673   // Hey, I just found out (in an ugly way) that the following doesn't work:
00674   char myText[] = "OK";
00675   istring myString(istring::SPRINTF, "%04s", myText);
00676 #ifdef DEBUG_STRING_TEST
00677   out.log(istring("first try gets: ") + myString);
00678 #endif
00679 
00680   char myText8[] = "OK";
00681   char my_text_4[90];
00682   sprintf(my_text_4, "%4s", myText8);
00683 #ifdef DEBUG_STRING_TEST
00684   out.log(istring("second try gets: ") + istring(my_text_4));
00685 #endif
00686 
00687 #ifndef EMBEDDED_BUILD
00688   // Looks like you don't handle the "%04s" arguments properly.  I can make
00689   // it work as follows:
00690   char myText2[] = "OK";
00691   char myText3[50];
00692   sprintf(myText3, "%4s", myText2);
00693   istring myString2(myText3);
00694 #ifdef DEBUG_STRING_TEST
00695   out.log(istring("third try gets: ") + myString2);
00696 #endif
00697 #endif // firmware.
00698 }
00699 
00700 void run_test_21()
00701 {
00702   FUNCDEF("run_test_21");
00703   // 21st test group checks out the strip spaces and replace functions.
00704   istring spacey("   dufunk  ");
00705   istring temp = spacey;
00706   temp.strip_spaces(istring::FROM_FRONT);
00707   if (temp != istring("dufunk  "))
00708     deadly_error(WHERE, func, "created wrong string");
00709   temp = spacey;
00710   temp.strip_spaces(istring::FROM_END);
00711   if (temp != istring("   dufunk"))
00712     deadly_error(WHERE, func, "created wrong string");
00713   temp = spacey;
00714   temp.strip_spaces(istring::FROM_BOTH_SIDES);
00715   if (temp != istring("dufunk"))
00716     deadly_error(WHERE, func, "created wrong string");
00717 
00718   istring placemat("mary had a red hooded cobra she kept around her neck "
00719       "and it hissed at the people as they walked by her tent.");
00720   if (!placemat.replace("had", "bought"))
00721     deadly_error(WHERE, func, "replace failed");
00722   if (placemat.replace("hoded", "bought"))
00723     deadly_error(WHERE, func, "replace didn't fail but should have");
00724   if (!placemat.replace("she", "funkateria"))
00725     deadly_error(WHERE, func, "replace failed");
00726   if (!placemat.replace("hooded", "hood"))
00727     deadly_error(WHERE, func, "replace failed");
00728   if (!placemat.replace("cobra", "in the"))
00729     deadly_error(WHERE, func, "replace failed");
00730 
00731   int indy = placemat.find("kept");
00732   if (negative(indy))
00733     deadly_error(WHERE, func, "couldn't find string");
00734   placemat[indy - 1] = '.';
00735   placemat.zap(indy, placemat.end());
00736   if (placemat != istring("mary bought a red hood in the funkateria."))
00737     deadly_error(WHERE, func, "got wrong result string");
00738 }
00739 
00740 void run_test_22()
00741 {
00742   FUNCDEF("run_test_22");
00743   // 22nd test: morgan's find bug.
00744   istring B("buzz*buzz*");
00745   {
00746     int x = B.find('*');  // correctly finds the first *.
00747     if (x != 4)
00748       deadly_error(WHERE, func, "got wrong index for first");
00749     x++;   
00750     x = B.find('*', x);  // correctly finds the second *.
00751     if (x != 9)
00752       deadly_error(WHERE, func, "got wrong index for second");
00753     x++;  // now x == B.length().
00754     x = B.find('*', x);
00755       // error was: finds the second * again (and again and again and 
00756       // again...).  At this point it should return OUT_OF_RANGE.
00757     if (x > 0)
00758       deadly_error(WHERE, func, "got wrong outcome for third");
00759   }
00760   {
00761     int x = B.find("z*");  // correctly finds the first z*.
00762     if (x != 3)
00763       deadly_error(WHERE, func, "got wrong index for fourth");
00764     x++;   
00765     x = B.find("z*", x);  // correctly finds the second *.
00766     if (x != 8)
00767       deadly_error(WHERE, func, "got wrong index for fifth");
00768     x++;  // now x == B.length().
00769     x = B.find("z*", x);
00770       // error was: finds the second * again (and again and again and 
00771       // again...).  At this point it should return OUT_OF_RANGE.
00772     if (x > 0)
00773       deadly_error(WHERE, func, "got wrong outcome for sixth");
00774   }
00775 //hmmm: add a reverse version of the test!
00776 }
00777 
00778 void run_test_23()
00779 {
00780   FUNCDEF("run_test_23");
00781   // 23rd test: test the new strip function.
00782   istring strip_string("!@#$%^&*()");
00783   
00784   istring no_stripper("this shouldn't change");
00785   no_stripper.strip(strip_string, istring::FROM_BOTH_SIDES);
00786   if (no_stripper != istring("this shouldn't change"))
00787     deadly_error(WHERE, func, "first test failed comparison");
00788 
00789   istring strippee_orig("&$(*(@&@*()()!()@*(@(*fudge#((@(*@**#)(@#)(#");
00790   istring strippee(strippee_orig);
00791   strippee.strip(strip_string, istring::FROM_BOTH_SIDES);
00792   if (strippee != istring("fudge"))
00793     deadly_error(WHERE, func, "second test failed comparison");
00794 
00795   strippee = strippee_orig;
00796   strippee.strip(strip_string, istring::FROM_FRONT);
00797   if (strippee != istring("fudge#((@(*@**#)(@#)(#"))
00798     deadly_error(WHERE, func, "third test failed comparison");
00799 
00800   strippee = strippee_orig;
00801   strippee.strip(strip_string, istring::FROM_END);
00802   if (strippee != istring("&$(*(@&@*()()!()@*(@(*fudge"))
00803     deadly_error(WHERE, func, "fourth test failed comparison");
00804 }
00805 
00806 void run_test_24()
00807 {
00808   FUNCDEF("run_test_24");
00809 #ifdef __WIN32__
00810   // 24th test group tests _bstr_t conversions.
00811   _bstr_t beast("abcdefgh");
00812 #ifdef DEBUG_STRING_TEST
00813   out.log(istring("the beast is ") + beast.operator char *() +
00814       istring(istring::SPRINTF, " with length %d", beast.length()));
00815 #endif
00816   istring convert = beast;
00817 #ifdef DEBUG_STRING_TEST
00818   out.log(istring("the convert is ") + convert
00819       + istring(istring::SPRINTF, " with length %d", convert.length()));
00820 #endif
00821   if (convert != "abcdefgh")
00822     deadly_error(WHERE, func, "first test failed comparison");
00823 
00824   istring jethro("i want a hog sandwich");
00825   _bstr_t pork = string_convert::to_bstr_t(jethro);
00826   if (strcmp(pork.operator char *(), jethro.s()))
00827     deadly_error(WHERE, func, "second test failed comparison");
00828 #endif
00829 }
00830 
00831 void run_test_25()
00832 {
00833   FUNCDEF("run_test_25");
00834   // 25th test group tests simple comparisons.
00835   istring fred = "asdoiuaoisud";
00836   if (fred != "") {}
00837   else
00838     deadly_error(WHERE, func, "first test failed comparison");
00839   istring bub = fred;
00840   if (fred != bub)
00841     deadly_error(WHERE, func, "second test failed comparison");
00842   fred = "";
00843   if (fred != "")
00844     deadly_error(WHERE, func, "third test failed comparison");
00845   else if (fred.length())
00846     deadly_error(WHERE, func, "fourth test failed comparison");
00847 }
00848 
00849 void run_test_26()
00850 {
00851   FUNCDEF("run_test_26");
00852   // 26th test group does simple timestamp operations.  these are more for
00853   // ensuring boundschecker gets to see some of this.
00854   istring t1 = timestamp(false, false);
00855   istring t2 = timestamp(false, true);
00856   istring t3 = timestamp(true, false);
00857   istring t4 = timestamp(true, true);
00858 }
00859 
00860 void run_test_27()
00861 {
00862   FUNCDEF("run_test_27");
00863   // 27th test group plays around with idate in an attempt to get
00864   // boundschecker to complain.
00865   earth_time::day_in_year d1 = date_now();
00866   earth_time::clock_time t1 =