home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / c / WLIB.ZIP / WSTR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-26  |  31.0 KB  |  1,698 lines

  1. #include <stdlib.h>
  2. #include <math.h>
  3. #include <ctype.h>
  4. #include <WStr.h>
  5. #pragma hdrstop
  6.  
  7. // copyright (c) 1992, 1993 by Paul Wheaton
  8.  
  9. //.parse
  10.  
  11. /////////  BaseString class
  12.  
  13. static char GarbageChar;
  14.  
  15. char& BaseString::operator[](int Index)
  16.   {
  17.     if (Index >= Len)
  18.       {
  19.         GarbageChar=0;
  20.         return GarbageChar;
  21.       }
  22.     return P[Index];
  23.   }
  24.  
  25.   /*
  26.  
  27.   The idea here is that if a programmer were to give an index out of range
  28.   then they won't be messing up something.  If they wrote "S[5]='X'" and S
  29.   was a string of length 2, then GarbageChar would be set to 'X' and S would
  30.   be unaffected.  "MyChar=S[5]" would result in MyChar being assigned 0.
  31.  
  32.   */
  33.  
  34. //.parse
  35.  
  36. Bool BaseString::operator==(const BaseString& S) const
  37.   {
  38.     if (Len != S.Len) return No;
  39.     int I = Len/(sizeof(int));
  40.     const int* P1 = (const int*)P;
  41.     const int* P2 = (const int*)S.P;
  42.     while (I!=0)
  43.       {
  44.         if (*P1 != *P2) return No;
  45.         P1++;
  46.         P2++;
  47.         I--;
  48.       }
  49.     I= Len%(sizeof(int));
  50.     if (I!=0)
  51.       {
  52.         const char* PP1=(const char*)P1;
  53.         const char* PP2=(const char*)P2;
  54.         while (I!=0)
  55.           {
  56.             if (*PP1 != *PP2) return No;
  57.             PP1++;
  58.             PP2++;
  59.             I--;
  60.           }
  61.       }
  62.     return Yes;
  63.   }
  64.  
  65. //.parse
  66.  
  67. void BaseString::ToLower()
  68.   {
  69.     int I = Len;
  70.     char* Q = P;
  71.     while (I--) { *Q = tolower(*Q); Q++; }
  72.   }
  73.  
  74. //.parse
  75.  
  76. void BaseString::ToUpper()
  77.   {
  78.     register int I = Len;
  79.     register char* Q = P;
  80.     while (I--) { *Q = toupper(*Q); Q++; }
  81.   }
  82.  
  83. //.parse
  84.  
  85. int BaseString::Index(char SearchChar, int StartIndex) const
  86.   {
  87.     if (StartIndex>=Len) return(NotFound);
  88.     int I=StartIndex;
  89.     while ((I<Len) && (P[I]!=SearchChar)) I++;
  90.     if (I==Len) return(NotFound);
  91.     else return(I);
  92.   }
  93.  
  94. //.parse
  95.  
  96. int BaseString::Index(const char* SearchStr, int StartIndex) const
  97.   {
  98.     if (StartIndex>=Len) return(NotFound);
  99.     char* Pos=strstr(P+StartIndex,SearchStr);
  100.     if (Pos==NULL) return NotFound;
  101.     else return int(Pos-P);
  102.   }
  103.  
  104. //.parse
  105.  
  106. int BaseString::Count(char C) const
  107.   {
  108.     int Num=0;
  109.     int I;
  110.     For(I,Len) if(P[I]==C) Num++;
  111.     return Num;
  112.   }
  113.  
  114. //.parse
  115.  
  116. void BaseString::Delete(int Index,int Length)
  117.   {
  118.     // *this=BeforeSub(Index)+FromSub(Index+Length);
  119.     int S=Index+Length;
  120.     while (S<Len)
  121.       {
  122.         P[Index]=P[S];
  123.         Index++;
  124.         S++;
  125.       }
  126.     P[Index]='\0';
  127.     Len=Index;
  128.   }
  129.  
  130. //.parse
  131.  
  132. void BaseString::DeleteLast()
  133.   {
  134.     if (Len>0)
  135.       {
  136.         Len--;
  137.         P[Len]='\0';
  138.       }
  139.   }
  140.  
  141. //.parse
  142.  
  143. void BaseString::Trim()
  144.   {
  145.     if (Len==0) return;
  146.     int I=0;
  147.     while ((P[I]==' ')&&(I<Len)) I++;
  148.     if (I>0) Delete(0,I);
  149.     if (Len==0) return;
  150.     TrimTrail();
  151.   }
  152.  
  153. //.parse
  154.  
  155. void BaseString::TrimTrailTo(char C)
  156.   {
  157.     if (Len>0)
  158.       {
  159.         Len--;
  160.         while ((P[Len]!=C)&&(Len>0)) Len--;
  161.         P[Len]='\0';
  162.       }
  163.   }
  164.  
  165. //.parse
  166.  
  167. void BaseString::TrimTrail()
  168.   {
  169.     if (Len>0)
  170.       {
  171.         Len--;
  172.         while ((P[Len]==' ')&&(Len>0)) Len--;
  173.         Len++;
  174.         P[Len]='\0';
  175.       }
  176.   }
  177.  
  178. //.parse
  179.  
  180. char BaseString::At(int Index) const
  181.   {
  182.     if (Index>=Len) return '\0';
  183.     return (P[Index]);
  184.   }
  185.  
  186. //.parse
  187.  
  188. char BaseString::Last() const
  189.   {
  190.     if (Len==0) return '\0';
  191.     else return P[Len-1];
  192.   }
  193.  
  194. //.parse
  195.  
  196. void BaseString::Clip(int NewLen)
  197.   {
  198.     if ((NewLen<Len)&&(NewLen>=0))
  199.       {
  200.         Len=NewLen;
  201.         P[Len]='\0';
  202.       }
  203.   }
  204.  
  205. //.parse
  206.  
  207. String40 BaseString::Word(int Num)
  208.   {
  209.     String40 S;
  210.     if (Len>0)
  211.       {
  212.         int LastPos=0;
  213.         int Pos=0;
  214.         int I=0;
  215.         Bool Done=False;
  216.         while (!Done)
  217.           {
  218.             Pos=Index(' ',LastPos);
  219.             if (Pos==NotFound)
  220.               {
  221.                 if (I==Num)
  222.                   {
  223.                     // functions such as "From" and "At" are not available here
  224.                     S.Len=Len-LastPos;
  225.                     if (S.Len>40) S.Len=40;
  226.                     memcpy(S.P,P+LastPos,S.Len);
  227.                     S.P[S.Len]='\0';
  228.                   }
  229.                 Done=True;
  230.               }
  231.             else
  232.               {
  233.                 if (I==Num)
  234.                   {
  235.                     S.Len=Pos-LastPos;
  236.                     if (S.Len>40) S.Len=40;
  237.                     memcpy(S.P,P+LastPos,S.Len);
  238.                     S.P[S.Len]='\0';
  239.                     Done=True;
  240.                   }
  241.                 else
  242.                   {
  243.                     I++;
  244.                     LastPos=Pos+1;
  245.                   }
  246.               }
  247.           }
  248.       }
  249.     return S;
  250.   }
  251.  
  252. //.parse
  253.  
  254. String40 BaseString::XWord(int Num)
  255.   {
  256.     String40 S;
  257.     if (Len>0)
  258.       {
  259.         int LastPos=0;
  260.         int Pos=0;
  261.         int I=0;
  262.         Bool Done=False;
  263.         while (!Done)
  264.           {
  265.             Pos=Index(' ',LastPos);
  266.             if (Pos==NotFound)
  267.               {
  268.                 if (I==Num)
  269.                   {
  270.                     S.Len=Len-LastPos;
  271.                     if (S.Len>40) S.Len=40;
  272.                     memcpy(S.P,P+LastPos,S.Len);
  273.                     S.P[S.Len]='\0';
  274.                     Delete(LastPos,S.Length());
  275.                     TrimTrail();
  276.                   }
  277.                 Done=True;
  278.               }
  279.             else
  280.               {
  281.                 if (I==Num)
  282.                   {
  283.                     int L=Pos-LastPos;
  284.                     S.Len=Pos-LastPos;
  285.                     if (S.Len>40) S.Len=40;
  286.                     memcpy(S.P,P+LastPos,S.Len);
  287.                     S.P[S.Len]='\0';
  288.                     Delete(LastPos,L+1);
  289.                     Done=True;
  290.                   }
  291.                 else
  292.                   {
  293.                     I++;
  294.                     LastPos=Pos+1;
  295.                   }
  296.               }
  297.           }
  298.       }
  299.     return S;
  300.   }
  301.  
  302. ///////////  String class
  303.  
  304. //.parse
  305.  
  306. void String::ReNew(int NewCapacity)  // replaces ANSI-C realloc
  307.   {
  308.     #ifdef MAJORBBS
  309.       char* P2=(char*)malloc(NewCapacity);
  310.     #else
  311.       char* P2=new char[NewCapacity];
  312.     #endif
  313.     if (P2==NULL)
  314.       {
  315.         char* E="00000 out of string mem rn";
  316.         E[4]=NewCapacity%10+'0';
  317.         NewCapacity/=10;
  318.         E[3]=NewCapacity%10+'0';
  319.         NewCapacity/=10;
  320.         E[2]=NewCapacity%10+'0';
  321.         NewCapacity/=10;
  322.         E[1]=NewCapacity%10+'0';
  323.         NewCapacity/=10;
  324.         E[0]=NewCapacity%10+'0';
  325.         NewCapacity/=10;
  326.         FatalError(E);
  327.       }
  328.     strncpy(P2,P,NewCapacity-1);
  329.     #ifdef MAJORBBS
  330.       free(P);
  331.     #else
  332.       delete(P);
  333.     #endif
  334.     P=P2;
  335.     P[NewCapacity-1]=0;
  336.   }
  337.  
  338. void String::New()
  339.   {
  340.     if (Alloc<16) Alloc=16;
  341.     #ifdef MAJORBBS
  342.       P = (char*)malloc(Alloc);
  343.     #else
  344.       P = new char[Alloc];
  345.     #endif
  346.     if (P==NULL)
  347.       {
  348.         char* E="00000 out of string mem";
  349.         E[4]=Alloc%10+'0';
  350.         Alloc/=10;
  351.         E[3]=Alloc%10+'0';
  352.         Alloc/=10;
  353.         E[2]=Alloc%10+'0';
  354.         Alloc/=10;
  355.         E[1]=Alloc%10+'0';
  356.         Alloc/=10;
  357.         E[0]=Alloc%10+'0';
  358.         FatalError(E);
  359.       }
  360.   }
  361.  
  362. //.parse
  363.  
  364. String::String(const char& C, int L, int Extra)
  365.   {
  366.     Len = L;
  367.     Alloc = Len + Extra + 1;
  368.     New();
  369.     register int I=Len;
  370.     P[I] = 0;
  371.     while (I) P[--I] = C;
  372.   }
  373.  
  374. //.parse
  375.  
  376. String::String(int Extra)
  377.   {
  378.     Len = 0;
  379.     Alloc = Extra + 1;
  380.     New();
  381.     *P='\0';
  382.   }
  383.  
  384. //.parse
  385.  
  386. String::String(const char* CS, int Extra)
  387.   {
  388.     Len = strlen(CS);
  389.     Alloc = Len + Extra + 1;
  390.     New();
  391.     strcpy(P,CS);
  392.   }
  393.  
  394. //.parse
  395.  
  396. String::String(const BaseString& S, int Extra)
  397.   {
  398.     Len = S.Len;
  399.     Alloc = Len + Extra + 1;
  400.     New();
  401.     strcpy(P,S.P);
  402.   }
  403.  
  404. //.parse
  405.  
  406. String::String(const String& S)
  407.   {
  408.     Len=S.Len;
  409.     Alloc=Len+1;
  410.     New();
  411.     strcpy(P,S.P);
  412.   }
  413.  
  414. //.parse
  415.  
  416. void String::operator=(const BaseString& S)
  417.   {
  418.     if (P == S.P) return;
  419.     Len = S.Len;
  420.     if (Len >= Alloc)
  421.       {
  422.         #ifdef MAJORBBS
  423.           free(P);
  424.         #else
  425.           delete(P);
  426.         #endif
  427.         Alloc = S.Alloc;
  428.         New();
  429.       }
  430.     strcpy(P,S.P);
  431.   }
  432.  
  433. //.parse
  434.  
  435. void String::operator=(const char* CS)
  436.   {
  437.     Len = strlen(CS);
  438.     if (Len >= Alloc)
  439.       {
  440.         Alloc = Len + DefaultStringExtra + 1;
  441.         #ifdef MAJORBBS
  442.           free(P);
  443.         #else
  444.           delete(P);
  445.         #endif
  446.         New();
  447.       }
  448.     strcpy(P,CS);
  449.   }
  450.  
  451. //.parse
  452.  
  453. void String::operator=(const char C)
  454.   {
  455.     Len=1;
  456.     P[0]=C;
  457.     P[1]='\0';
  458.   }
  459.  
  460. //.parse
  461.  
  462. String String::operator+(const String40& S) const
  463.   {
  464.     String T(Len+S.Len+1);
  465.     strcpy(T.P,P);
  466.     strcpy(&(T.P[Len]), S.P);
  467.     T.Len = Len+S.Len;
  468.     return(T);
  469.   }
  470.  
  471. //.parse
  472.  
  473. String String::operator+(const String120& S) const
  474.   {
  475.     String T(Len+S.Len+1);
  476.     strcpy(T.P,P);
  477.     strcpy(&(T.P[Len]), S.P);
  478.     T.Len = Len+S.Len;
  479.     return(T);
  480.   }
  481.  
  482. //.parse
  483.  
  484. String String::operator+(const String& S) const
  485.   {
  486.     String T(Len+S.Len+1);
  487.     strcpy(T.P,P);
  488.     strcpy(&(T.P[Len]), S.P);
  489.     T.Len = Len+S.Len;
  490.     return(T);
  491.   }
  492.  
  493. //.parse
  494.  
  495. String String::operator+(const char* CS) const
  496.   {
  497.     int CSLen = strlen(CS);
  498.     String T(Len+CSLen+1);
  499.     strcpy (T.P,P);
  500.     strcpy (&(T.P[Len]), CS);
  501.     T.Len = Len+CSLen;
  502.     return T;
  503.   }
  504.  
  505. //.parse
  506.  
  507. String String::operator+(char C) const
  508.   {
  509.     String S(*this,1);
  510.     S.P[Len]=C;
  511.     S.Len++;
  512.     S.P[S.Len]='\0';
  513.     return S;
  514.   }
  515.  
  516. //.parse
  517.  
  518. String operator+(const String40& SS, const String& S)
  519.   {
  520.     String T(SS.Length()+S.Len+1);
  521.     strcpy(T.P,(const char*)SS);
  522.     strcpy(&(T.P[SS.Length()]), S.P);
  523.     T.Len = SS.Length()+S.Len;
  524.     return(T);
  525.   }
  526.  
  527. //.parse
  528.  
  529. String operator+(const String120& SS, const String& S)
  530.   {
  531.     String T(SS.Length()+S.Len+1);
  532.     strcpy(T.P,(const char*)SS);
  533.     strcpy(&(T.P[SS.Length()]), S.P);
  534.     T.Len = SS.Length()+S.Len;
  535.     return(T);
  536.   }
  537.  
  538. //.parse
  539.  
  540. String operator+(const char* CS, const String& S)
  541.   {
  542.     int CSLen=strlen(CS);
  543.     String T(int(CSLen+S.Len+1));
  544.     strcpy(T.P,CS);
  545.     strcpy(&(T.P[CSLen]),S.P);
  546.     T.Len = CSLen + S.Len;
  547.     return T;
  548.   }
  549.  
  550. //.parse
  551.  
  552. String operator+(char C, const String& S)
  553.   {
  554.     int NewLen=S.Len+1;
  555.     String T(NewLen);
  556.     T.P[0]=C;
  557.     strcpy(&(T.P[1]),S.P);
  558.     T.Len = NewLen;
  559.     return T;
  560.   }
  561.  
  562. //.parse
  563.  
  564. void String::operator+=(const BaseString& S)
  565.   {
  566.     if (S.Len==0) return;
  567.     int NewLen=Len+S.Len;
  568.     if (Alloc <= NewLen)
  569.       {
  570.         Alloc = NewLen+1;
  571.         ReNew(Alloc);
  572.       }
  573.     strcpy(&P[Len],S.P);
  574.     Len += S.Len;
  575.   }
  576.  
  577. //.parse
  578.  
  579. void String::operator+=(const char* CS)
  580.   {
  581.     int CSLen = strlen(CS);
  582.     if (CSLen==0) return;
  583.     int NewLen=Len+CSLen;
  584.     if (Alloc <= NewLen)
  585.       {
  586.         Alloc = NewLen+1;
  587.         ReNew(Alloc);
  588.       }
  589.     strcpy(&(P[Len]),CS);
  590.     Len += CSLen;
  591.   }
  592.  
  593. //.parse
  594.  
  595. void String::operator+=(char C)
  596.   {
  597.     *this=*this+C;
  598.     /*
  599.     if (Alloc < Len+2)
  600.       {
  601.         Alloc += (DefaultStringExtra+1);
  602.         ReNew(Alloc);
  603.       }
  604.     P[Len]=C;
  605.     Len++;
  606.     P[Len]=0;
  607.     */
  608.   }
  609.  
  610. //.parse
  611.  
  612. void String::Left(int NewSize)
  613.   {
  614.     if (Len>NewSize)
  615.       {
  616.         Len=NewSize;
  617.         P[Len]=0;
  618.       }
  619.     else *this+=Spaces(NewSize-Len);
  620.   }
  621.  
  622. //.parse
  623.  
  624. void String::Right(int NewSize)
  625.   {
  626.     if (Len>NewSize)
  627.       {
  628.         Len=NewSize;
  629.         P[Len]=0;
  630.       }
  631.     else
  632.       {
  633.         String T=Spaces(NewSize-Len)+(*this);
  634.         *this=T;
  635.       }
  636.   }
  637.  
  638. //.parse
  639.  
  640. void String::Center(int NewSize)
  641.   {
  642.     if (Len>NewSize)
  643.       {
  644.         Len=NewSize;
  645.         P[Len]=0;
  646.       }
  647.     else
  648.       {
  649.         int TotSpaces=NewSize-Len;
  650.         int LeftSpaces=TotSpaces/2;
  651.         *this=Spaces(LeftSpaces)+(*this)+Spaces(TotSpaces-LeftSpaces);
  652.       }
  653.   }
  654.  
  655. //.parse
  656.  
  657. void String::Tail(int NewSize)
  658.   {
  659.     if (Len>NewSize) *this=From(Len-NewSize);
  660.     else *this=Spaces(NewSize-Len)+*this;
  661.   }
  662.  
  663. //.parse
  664.  
  665. int String::ReAlloc(int NewCapacity)
  666.   {
  667.     if (NewCapacity < Len) NewCapacity = Len;
  668.     if (Alloc != NewCapacity+1)
  669.       {
  670.         Alloc = NewCapacity+1;
  671.         ReNew(Alloc);
  672.       }
  673.     return Alloc - 1;
  674.   }
  675.  
  676. //.parse
  677.  
  678. String String::At(int Index, int Length) const
  679.   {
  680.     if (Index>=Len)
  681.       {
  682.         String S="";
  683.         return S;
  684.       }
  685.     if (Index+Length>Len) Length=Len-Index;
  686.     String S(int(Length+1));
  687.     memcpy(S.P,&P[Index],Length);
  688.     S.P[Length]='\0';
  689.     S.Len=Length;
  690.     return S;
  691.   }
  692.  
  693. //.parse
  694.  
  695. void String::Insert(char C,int Index)
  696.   {
  697.     if (Index<0) Index=0;
  698.     if ((Len+1)>=Alloc) ReNew(Alloc+DefaultStringExtra+1);
  699.     if (Index>=Len)
  700.       {
  701.         P[Len]=C;
  702.         P[Len+1]='\0';
  703.       }
  704.     else
  705.       {
  706.         memmove(P+Index+1,P+Index,Len-Index+1);
  707.         P[Index]=C;
  708.       }
  709.     Len++;
  710.   }
  711.  
  712. void String::Insert(const char* St,int Index)
  713.   {
  714.     if (Index<0) Index=0;
  715.     int SLen=strlen(St);
  716.     if (SLen>0)
  717.       {
  718.         if ((Len+SLen)>=Alloc) ReNew(Alloc+DefaultStringExtra+SLen);
  719.         if (Index>=Len) strcpy(P+Len,St);
  720.         else
  721.           {
  722.             memmove(P+Index+SLen,P+Index,Len-Index+1);
  723.             memcpy(P+Index,St,SLen);
  724.           }
  725.         Len+=SLen;
  726.       }
  727.     //*this=Before(Index)+St+From(Index);
  728.   }
  729.  
  730. ////////  StackString class
  731.  
  732. //.parse
  733.  
  734. void StackString::operator=(const BaseString& S)
  735.   {
  736.     if (P == S.P) return;
  737.     Len = Min(S.Len,Alloc-1);
  738.     memcpy(P,S.P,Len);
  739.     P[Len]='\0';
  740.   }
  741.  
  742. //.parse
  743.  
  744. void StackString::operator=(const char* CS)
  745.   {
  746.     Len = Min(int(strlen(CS)),Alloc-1);
  747.     memcpy(P,CS,Len);
  748.     P[Len]='\0';
  749.   }
  750.  
  751. void StackString::operator=(const char C)
  752.   {
  753.     Len=1;
  754.     P[0]=C;
  755.   }
  756.  
  757. //.parse
  758.  
  759. void StackString::operator+=(const BaseString& S)
  760.   {
  761.     if (S.Len==0) return;
  762.     int MaxCopy=Alloc-Len-1;
  763.     int CopyLen=Min(MaxCopy,S.Len);
  764.     memcpy(&P[Len],S.P,CopyLen);
  765.     Len+=CopyLen;
  766.     P[Len]='\0';
  767.   }
  768.  
  769. //.parse
  770.  
  771. void StackString::operator+=(const char* CS)
  772.   {
  773.     int CSLen = strlen(CS);
  774.     if (CSLen==0) return;
  775.     int MaxCopy=Alloc-Len-1;
  776.     int CopyLen=Min(MaxCopy,CSLen);
  777.     memcpy(&P[Len],CS,CopyLen);
  778.     Len+=CopyLen;
  779.     P[Len]='\0';
  780.   }
  781.  
  782. //.parse
  783.  
  784. void StackString::operator+=(char C)
  785.   {
  786.     if (Len<(Alloc-1))
  787.       {
  788.         P[Len]=C;
  789.         Len++;
  790.         P[Len]='\0';
  791.       }
  792.   }
  793.  
  794. //.parse
  795.  
  796. void StackString::Left(int NewSize)
  797.   {
  798.     if (Len>NewSize)
  799.       {
  800.         Len=NewSize;
  801.         P[Len]=0;
  802.       }
  803.     else if (NewSize>Len)
  804.       {
  805.         int End=Min(NewSize,Alloc-1);
  806.         int Dif=End-Len;
  807.         memset(P+Len,' ',Dif);
  808.         Len+=Dif;
  809.         P[Len]='\0';
  810.       }
  811.   }
  812.  
  813. //.parse
  814.  
  815. void StackString::Right(int NewSize)
  816.   {
  817.     if (Len>NewSize)
  818.       {
  819.         Len=NewSize;
  820.         P[Len]=0;
  821.       }
  822.     else if (NewSize>Len)
  823.       {
  824.         int End=Min(NewSize,Alloc-1);
  825.         int Dif=End-Len;
  826.         memmove(P+Dif,P,Len);
  827.         memset(P,' ',Dif);
  828.         Len+=Dif;
  829.         P[Len]='\0';
  830.       }
  831.   }
  832.  
  833. //.parse
  834.  
  835. void StackString::Center(int NewSize)
  836.   {
  837.     if (Len>NewSize)
  838.       {
  839.         Len=NewSize;
  840.         P[Len]=0;
  841.       }
  842.     else
  843.       {
  844.         NewSize=Min(NewSize,Alloc-1);
  845.         Right(((NewSize-Len)/2)+Len);
  846.         Left(NewSize);
  847.       }
  848.   }
  849.  
  850. //.parse
  851.  
  852. void StackString::Tail(int NewSize)
  853.   {
  854.     if (Len>NewSize)
  855.       {
  856.         memmove(P,P+(Len-NewSize),NewSize);
  857.         Len=NewSize;
  858.         P[Len]='\0';
  859.       }
  860.     else Right(NewSize);
  861.   }
  862.  
  863. //.parse
  864.  
  865. void StackString::Sub(StackString& D, int I, int L)
  866.   {
  867.     if ((I+L)>Len) L=Len-I;
  868.     D.Len=L;
  869.     memcpy(D.P,P+I,L);
  870.     D.P[L]='\0';
  871.   }
  872.  
  873. //.parse
  874.  
  875. void StackString::Insert(char C,int Index)
  876.   {
  877.     if ((Len==Alloc-1)&&(Index<Len)) Len--;
  878.     if (Index>=Len)
  879.       {
  880.         P[Len]=C;
  881.         Len++;
  882.       }
  883.     else
  884.       {
  885.         memmove(P+Index+1,P+Index,Len-Index+1);
  886.         P[Index]=C;
  887.         Len++;
  888.       }
  889.     P[Len]='\0';
  890.   }
  891.  
  892. //.parse
  893.  
  894. void StackString::Insert(const char* St,int Index)
  895.   {
  896.     int StLen=strlen(St);
  897.     if (Index>Len) Index=Len;
  898.     int MoveNum=Len-Index;
  899.     int TotLen=StLen+Len;
  900.     int Excess=TotLen-(Alloc-1);
  901.     if (Excess>0)
  902.       {
  903.         MoveNum-=Excess;
  904.         if (MoveNum<0) StLen+=MoveNum;
  905.       }
  906.     if (MoveNum>0)
  907.       {
  908.         memmove(P+Index+StLen,P+Index,MoveNum);
  909.         Len+=MoveNum;
  910.       }
  911.     if (StLen>0)
  912.       {
  913.         memcpy(P+Index,St,StLen);
  914.         Len+=StLen;
  915.       }
  916.     P[Len]='\0';
  917.   }
  918.  
  919. ///////  String40 class
  920.  
  921. //.parse
  922.  
  923. String40::String40()
  924.   {
  925.     P=&Buf[0];
  926.     Buf[0]='\0';
  927.     Len=0;
  928.     Alloc=41;
  929.   }
  930.  
  931. //.parse
  932.  
  933. String40::String40(const char& C, int L)
  934.   {
  935.     P=&Buf[0];
  936.     Alloc=41;
  937.     Len=L;
  938.     if (Len>40) Len=40;
  939.     memset(P,C,Len);
  940.     Buf[Len]='\0';
  941.   }
  942.  
  943. //.parse
  944.  
  945. String40::String40(const char* CS)
  946.   {
  947.     P=&Buf[0];
  948.     Alloc=41;
  949.     Len=strlen(CS);
  950.     if (Len>40) Len=40;
  951.     memcpy(P,CS,Len);
  952.     Buf[Len]='\0';
  953.   }
  954.  
  955. //.parse
  956.  
  957. String40::String40(const BaseString& BS)
  958.   {
  959.     P=&Buf[0];
  960.     Alloc=41;
  961.     Len=BS.Len;
  962.     if (Len>40) Len=40;
  963.     memcpy(P,BS.P,Len);
  964.     Buf[Len]='\0';
  965.   }
  966.  
  967. //.parse
  968.  
  969. String40::String40(const String40& S)
  970.   {
  971.     P=&Buf[0];
  972.     Alloc=41;
  973.     Len=S.Len;
  974.     strcpy(P,S.P);
  975.   }
  976.  
  977. //.parse
  978.  
  979. String40 String40::operator+(const String40& S) const
  980.   {
  981.     String40 T(*this);
  982.     T+=S;
  983.     return T;
  984.   }
  985.  
  986. //.parse
  987.  
  988. String40 String40::operator+(const char* S) const
  989.   {
  990.     String40 T(*this);
  991.     T+=S;
  992.     return T;
  993.   }
  994.  
  995. //.parse
  996.  
  997. String40 String40::operator+(char C) const
  998.   {
  999.     String40 T(*this);
  1000.     T+=C;
  1001.     return T;
  1002.   }
  1003.  
  1004. //.parse
  1005.  
  1006. String40 operator+(const char* S1, const String40& S2)
  1007.   {
  1008.     String40 T(S1);
  1009.     T+=S2;
  1010.     return T;
  1011.   }
  1012.  
  1013. //.parse
  1014.  
  1015. String40 operator+(char C, const String40& S)
  1016.   {
  1017.     String40 T(C);
  1018.     T+=S;
  1019.     return T;
  1020.   }
  1021.  
  1022. //.parse
  1023.  
  1024. String40 String40::At(int Index, int Length) const
  1025.   {
  1026.     String40 T;
  1027.     StackString::Sub(T,Index,Length);
  1028.     return T;
  1029.   }
  1030.  
  1031. ///////  String120 class
  1032.  
  1033. //.parse
  1034.  
  1035. String120::String120()
  1036.   {
  1037.     P=&Buf[0];
  1038.     Buf[0]='\0';
  1039.     Len=0;
  1040.     Alloc=121;
  1041.   }
  1042.  
  1043. //.parse
  1044.  
  1045. String120::String120(const char& C, int L)
  1046.   {
  1047.     P=&Buf[0];
  1048.     Alloc=121;
  1049.     Len=L;
  1050.     if (Len>120) Len=120;
  1051.     memset(P,C,Len);
  1052.     Buf[Len]='\0';
  1053.   }
  1054.  
  1055. //.parse
  1056.  
  1057. String120::String120(const char* CS)
  1058.   {
  1059.     P=&Buf[0];
  1060.     Alloc=121;
  1061.     Len=strlen(CS);
  1062.     if (Len>120) Len=120;
  1063.     memcpy(P,CS,Len);
  1064.     Buf[Len]='\0';
  1065.   }
  1066.  
  1067. //.parse
  1068.  
  1069. String120::String120(const BaseString& BS)
  1070.   {
  1071.     P=&Buf[0];
  1072.     Alloc=121;
  1073.     Len=BS.Len;
  1074.     if (Len>120) Len=120;
  1075.     memcpy(P,BS.P,Len);
  1076.     Buf[Len]='\0';
  1077.   }
  1078.  
  1079. //.parse
  1080.  
  1081. String120::String120(const String120& S)
  1082.   {
  1083.     P=&Buf[0];
  1084.     Alloc=121;
  1085.     Len=S.Len;
  1086.     strcpy(P,S.P);
  1087.   }
  1088.  
  1089. //.parse
  1090.  
  1091. String120 String120::operator+(const String40& S) const
  1092.   {
  1093.     String120 T(*this);
  1094.     T+=S;
  1095.     return T;
  1096.   }
  1097.  
  1098. //.parse
  1099.  
  1100. String120 String120::operator+(const String120& S) const
  1101.   {
  1102.     String120 T(*this);
  1103.     T+=S;
  1104.     return T;
  1105.   }
  1106.  
  1107. //.parse
  1108.  
  1109. String120 String120::operator+(const char* S) const
  1110.   {
  1111.     String120 T(*this);
  1112.     T+=S;
  1113.     return T;
  1114.   }
  1115.  
  1116. //.parse
  1117.  
  1118. String120 String120::operator+(char C) const
  1119.   {
  1120.     String120 T(*this);
  1121.     T+=C;
  1122.     return T;
  1123.   }
  1124.  
  1125. //.parse
  1126.  
  1127. String120 operator+(const String40& S1, const String120& S2)
  1128.   {
  1129.     String120 T(S1);
  1130.     T+=S2;
  1131.     return T;
  1132.   }
  1133.  
  1134. //.parse
  1135.  
  1136. String120 operator+(const char* S1, const String120& S2)
  1137.   {
  1138.     String120 T(S1);
  1139.     T+=S2;
  1140.     return T;
  1141.   }
  1142.  
  1143. //.parse
  1144.  
  1145. String120 operator+(char C, const String120& S)
  1146.   {
  1147.     String120 T(C);
  1148.     T+=S;
  1149.     return T;
  1150.   }
  1151.  
  1152. //.parse
  1153.  
  1154. String120 String120::At(int Index, int Length) const
  1155.   {
  1156.     String120 T;
  1157.     StackString::Sub(T,Index,Length);
  1158.     return T;
  1159.   }
  1160.  
  1161. //.parse
  1162.  
  1163. String CenterText(const char* CS, int NewSize)
  1164.   {
  1165.     String S=CS;
  1166.     S.Center(NewSize);
  1167.     return S;
  1168.   }
  1169.  
  1170. //.parse
  1171.  
  1172. String Form(int FLen,SLong Val)
  1173.   {
  1174.     String Mask=TailText("##,###,###,###",FLen);
  1175.       //  SLong has 10 significant digits + 1 sign digit
  1176.     if (Mask[0]==',') Mask[0]='#';
  1177.     String ReturnString=Form(Mask,double(Val));
  1178.     return ReturnString;
  1179.   }
  1180.  
  1181. //.parse
  1182.  
  1183. static Bool DigitToken(char C)
  1184.   {
  1185.     return ((C=='@') || (C=='#'));
  1186.   }
  1187.  
  1188. static void FindDigitToken(String &S, int &I)
  1189.   {
  1190.     while (!DigitToken(S[I])) I++;
  1191.   }
  1192.  
  1193. static void DoFillers(String &Mask, int Fillers)
  1194.   {
  1195.     int I=0;
  1196.     while (Fillers)
  1197.       {
  1198.         FindDigitToken(Mask,I);
  1199.         if (Mask[I]=='@') Mask[I]='0';
  1200.         else Mask[I]=' ';
  1201.         Fillers--;
  1202.       }
  1203.   }
  1204.  
  1205. static void DoSpaceFillers(String &Mask, int Fillers)
  1206.   {
  1207.     int I=0;
  1208.     FindDigitToken(Mask,I);
  1209.     while (Fillers)
  1210.       {
  1211.         if (Mask[I]=='#') Fillers--;
  1212.         Mask[I]=' ';
  1213.         I++;
  1214.       }
  1215.     if (Mask[I]==',') Mask[I]=' ';
  1216.   }
  1217.  
  1218. static void DoNeg(String &Mask)
  1219.   {
  1220.     int I=0;
  1221.     FindDigitToken(Mask,I);
  1222.     if (Mask[I+1]==',')
  1223.       {
  1224.         Mask[I]=' ';
  1225.         I++;
  1226.       }
  1227.     Mask[I]='-';
  1228.   }
  1229.  
  1230. String Form(const char* M,double Val)
  1231.   {
  1232.     String Mask=M;
  1233.     Bool Negative=(Val<0.0);
  1234.     Val=Abs(Val);
  1235.     int MaskDecPos=Mask.Index('.'); //  The position of the decimal in Mask
  1236.     int MI;  //  Mask Index:  the part of the mask currently being fooled with
  1237.     String DecStr="";
  1238.     if (MaskDecPos!=NotFound)
  1239.       {
  1240.         int Digits=0;
  1241.         for(MI=MaskDecPos+1;MI<Mask.Length();MI++)
  1242.           {
  1243.             if (Mask[MI]=='#') Mask[MI]='@';
  1244.             if (Mask[MI]=='@') Digits++;
  1245.           }
  1246.         MI=MaskDecPos+1;
  1247.         double D=(Val-floor(Val));
  1248.         Val-=D;
  1249.         double Mult=pow(10,Digits);
  1250.         D*=Mult;
  1251.         if (D+0.5>Mult)
  1252.           {
  1253.             D=0.0;
  1254.             Val+=1.0;
  1255.           }
  1256.         DecStr=Form(Mask.From(MI),D);
  1257.           //  recursive call!  This part will be skipped cuz there's no decimal in the mask
  1258.         Mask.Left(MI);  //  chop off decimal portion
  1259.       }
  1260.     int Digits=0;  // the number of digits there are available to fill
  1261.     For(MI,Mask.Length())
  1262.         if (DigitToken(Mask[MI])) Digits++;
  1263.     String IStr=DStr(Val+0.5);  //  convert the integral part to a string
  1264.     Bool NegBrackets=(Mask[0]=='<');
  1265.     Bool NegCharNeeded=((!NegBrackets)&&(Negative));
  1266.     if (NegCharNeeded) Digits--;
  1267.     if (IStr.Length()>Digits)  // then fill with *'s
  1268.       {
  1269.         For(MI,Mask.Length())
  1270.             if (DigitToken(Mask[MI])) Mask[MI]='*';
  1271.       }
  1272.     else
  1273.       {
  1274.         int Fillers=Digits-IStr.Length();
  1275.         MI=0;
  1276.         FindDigitToken(Mask,MI);
  1277.         if (Mask[MI]=='#')
  1278.           {
  1279.             DoSpaceFillers(Mask,Fillers);
  1280.             if (NegCharNeeded) DoNeg(Mask);
  1281.           }
  1282.         else
  1283.           {
  1284.             if (NegCharNeeded) DoNeg(Mask);
  1285.             DoFillers(Mask,Fillers);
  1286.           }
  1287.         int I;  //  IStr Index
  1288.         For(I,IStr.Length())
  1289.           {
  1290.             FindDigitToken(Mask,MI);
  1291.             Mask[MI]=IStr[I];
  1292.           }
  1293.       }
  1294.     Mask+=DecStr;
  1295.     if (NegBrackets && (!Negative))
  1296.       {
  1297.         Mask[0]=' ';
  1298.         Mask[Mask.Length()-1]=' ';
  1299.       }
  1300.     return (Mask);
  1301.   }
  1302.  
  1303. //.parse
  1304.  
  1305. String Form(int FLen,const double& Val)
  1306.   {
  1307.     String Mask=TailText("#,###,###,###",FLen);
  1308.       //  SLong has 10 significant digits
  1309.     if (Mask[0]==',') Mask[0]='#';
  1310.     String ReturnString=Form(Mask,Val);
  1311.     return ReturnString;
  1312.   }
  1313.  
  1314. //.parse
  1315.  
  1316. String Form(int FLen,const Long& Val)
  1317.   {return Form(FLen,float(Val));}
  1318.  
  1319. String Form(int FLen,const float& Val)
  1320.   {
  1321.     return Form(int(FLen),double(Val));
  1322.   }
  1323.  
  1324. #ifndef MAJORBBS
  1325. String HexStr(Long Num)
  1326.   {
  1327.     char TmpStr[35];
  1328.     ltoa(Num,TmpStr,16);
  1329.     String X=TmpStr;
  1330.     return(X);
  1331.   }
  1332. #endif
  1333.  
  1334. //.parse
  1335.  
  1336. String LeftText(const char* CS, int NewSize)
  1337.   {
  1338.     String S=CS;
  1339.     S.Left(NewSize);
  1340.     return(S);
  1341.   }
  1342.  
  1343. #ifndef MAJORBBS
  1344. String OctalStr(Long Num)
  1345.   {
  1346.     char TmpStr[35];
  1347.     ltoa(Num,TmpStr,8);
  1348.     String X=TmpStr;
  1349.     return(X);
  1350.   }
  1351. #endif
  1352.  
  1353. //.parse
  1354.  
  1355. String StringOf(int HowMany, char What)
  1356.  {
  1357.    String S(What,HowMany,0);
  1358.    return(S);
  1359.  }
  1360.  
  1361. //.parse
  1362.  
  1363. String Str(long Num)
  1364.   {
  1365.     const BuffyLen=13;
  1366.     char Buffy[BuffyLen]="           0";
  1367.     char* BuffyPos=&Buffy[BuffyLen-2];
  1368.     Bool Neg=False;
  1369.     if (Num<0)
  1370.       {
  1371.         Neg=True;
  1372.         Num=-Num;
  1373.       }
  1374.     if (Num>0)
  1375.       {
  1376.         while (Num>0)
  1377.           {
  1378.             *BuffyPos=char((Num%10)+48);
  1379.             Num/=10;
  1380.             BuffyPos--;
  1381.           }
  1382.         BuffyPos++;
  1383.         if (Neg)
  1384.           {
  1385.             BuffyPos--;
  1386.             *BuffyPos='-';
  1387.           }
  1388.       }
  1389.     return String(BuffyPos);
  1390.   }
  1391.  
  1392. //.parse
  1393.  
  1394. String40 CommaStr(long Num)
  1395.   {
  1396.     const BuffyLen=15;
  1397.     char Buffy[BuffyLen]=",,,,,,,,,,,,,0";
  1398.     int I=0;
  1399.     char* BuffyPos=&Buffy[BuffyLen-2];
  1400.     while (Num>0)
  1401.       {
  1402.         *BuffyPos=char((Num%10)+48);
  1403.         Num/=10;
  1404.         BuffyPos--;
  1405.         I++;
  1406.         if (I%3==0) BuffyPos--;
  1407.       }
  1408.     BuffyPos++;
  1409.     if (*BuffyPos==',') BuffyPos++;
  1410.     return String(BuffyPos);
  1411.   }
  1412.  
  1413. //.parse
  1414.  
  1415. String RightText(const char* CS, int NewSize)
  1416.   {
  1417.     String S=CS;
  1418.     S.Right(NewSize);
  1419.     return S;
  1420.   }
  1421.  
  1422. //.parse
  1423.  
  1424. String TailText(const char* CS, int NewSize)
  1425.   {
  1426.     String S=CS;
  1427.     S.Tail(NewSize);
  1428.     return S;
  1429.   }
  1430.  
  1431. //.parse
  1432.  
  1433. String Trim(const char* S)
  1434.   {
  1435.     String St=S;
  1436.     St.Trim();
  1437.     return St;
  1438.   }
  1439.  
  1440. //.parse
  1441.  
  1442. String TrimTrail(const char* S)
  1443.   {
  1444.     String St=S;
  1445.     St.TrimTrail();
  1446.     return St;
  1447.   }
  1448.  
  1449. //.parse
  1450.  
  1451. String DStr(double Num)
  1452.   {
  1453.     Bool Sign=(Num<(-0.0000000000001));
  1454.     if (Sign) Num=-Num;
  1455.     double N=floor(Num);
  1456.     String S;
  1457.     while (N>0.1)
  1458.       {
  1459.         N/=10.0;
  1460.         double D=(N-floor(N));
  1461.         S=char(Round(D*10.0)+48)+S;
  1462.         N-=D;
  1463.       }
  1464.     if (Sign) S='-'+S;
  1465.     if (S.Length()==0) S='0';
  1466.     return(S);
  1467.   }
  1468.  
  1469. //.parse
  1470.  
  1471. String Spaces(int HowMany)
  1472.  {
  1473.    String S(' ',HowMany,0);
  1474.    return(S);
  1475.  }
  1476.  
  1477. //.parse
  1478.  
  1479. void String::Replace(const char* SearchStr, const char* ReplaceStr)
  1480.   {
  1481.     int SLen=strlen(SearchStr);
  1482.     int RLen=strlen(ReplaceStr);
  1483.     Bool SameLen=(SLen==RLen);
  1484.     int Pos=0;
  1485.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1486.       {
  1487.         if (SameLen)
  1488.           {
  1489.             int I;
  1490.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1491.           }
  1492.         else if (SLen>RLen)
  1493.           {
  1494.             Delete(Pos,SLen-RLen);
  1495.             int I;
  1496.             For(I,RLen) P[Pos+I]=ReplaceStr[I];
  1497.           }
  1498.         else
  1499.           {
  1500.             int I;
  1501.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1502.             Insert(&ReplaceStr[SLen],Pos+SLen);
  1503.           }
  1504.       }
  1505.   }
  1506.  
  1507. //.parse
  1508.  
  1509. void String::Replace(const char SearchChar, const char* ReplaceStr)
  1510.   {
  1511.     int RLen=strlen(ReplaceStr);
  1512.     int Pos=0;
  1513.     while((Pos=Index(SearchChar,Pos))!=NotFound)
  1514.       {
  1515.         if (RLen>1)
  1516.           {
  1517.             P[Pos]=*ReplaceStr;
  1518.             Insert(&ReplaceStr[1],Pos+1);
  1519.           }
  1520.         if (RLen==1) P[Pos]=*ReplaceStr;
  1521.         else Delete(Pos);
  1522.       }
  1523.   }
  1524.  
  1525. //.parse
  1526.  
  1527. void String::Replace(const char* SearchStr, const char ReplaceChar)
  1528.   {
  1529.     int SLen=strlen(SearchStr);
  1530.     int Pos=0;
  1531.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1532.       {
  1533.         if (SLen>1)
  1534.           {
  1535.             Delete(Pos,SLen-1);
  1536.             P[Pos]=ReplaceChar;
  1537.           }
  1538.         else P[Pos]=ReplaceChar;
  1539.       }
  1540.   }
  1541.  
  1542. //.parse
  1543.  
  1544. void String::Replace(const char SearchChar, const char ReplaceChar)
  1545.   {
  1546.     int Pos=0;
  1547.     while((Pos=Index(SearchChar,Pos))!=NotFound) P[Pos]=ReplaceChar;
  1548.   }
  1549.  
  1550. //.parse
  1551.  
  1552. void String120::Replace(const char* SearchStr, const char* ReplaceStr)
  1553.   {
  1554.     int SLen=strlen(SearchStr);
  1555.     int RLen=strlen(ReplaceStr);
  1556.     Bool SameLen=(SLen==RLen);
  1557.     int Pos=0;
  1558.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1559.       {
  1560.         if (SameLen)
  1561.           {
  1562.             int I;
  1563.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1564.           }
  1565.         else if (SLen>RLen)
  1566.           {
  1567.             Delete(Pos,SLen-RLen);
  1568.             int I;
  1569.             For(I,RLen) P[Pos+I]=ReplaceStr[I];
  1570.           }
  1571.         else
  1572.           {
  1573.             int I;
  1574.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1575.             Insert(&ReplaceStr[SLen],Pos+SLen);
  1576.           }
  1577.       }
  1578.   }
  1579.  
  1580. //.parse
  1581.  
  1582. void String120::Replace(const char SearchChar, const char* ReplaceStr)
  1583.   {
  1584.     int RLen=strlen(ReplaceStr);
  1585.     int Pos=0;
  1586.     while((Pos=Index(SearchChar,Pos))!=NotFound)
  1587.       {
  1588.         if (RLen>1)
  1589.           {
  1590.             P[Pos]=*ReplaceStr;
  1591.             Insert(&ReplaceStr[1],Pos+1);
  1592.           }
  1593.         if (RLen==1) P[Pos]=*ReplaceStr;
  1594.         else Delete(Pos);
  1595.       }
  1596.   }
  1597.  
  1598. //.parse
  1599.  
  1600. void String120::Replace(const char* SearchStr, const char ReplaceChar)
  1601.   {
  1602.     int SLen=strlen(SearchStr);
  1603.     int Pos=0;
  1604.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1605.       {
  1606.         if (SLen>1)
  1607.           {
  1608.             Delete(Pos,SLen-1);
  1609.             P[Pos]=ReplaceChar;
  1610.           }
  1611.         else P[Pos]=ReplaceChar;
  1612.       }
  1613.   }
  1614.  
  1615. //.parse
  1616.  
  1617. void String120::Replace(const char SearchChar, const char ReplaceChar)
  1618.   {
  1619.     int Pos=0;
  1620.     while((Pos=Index(SearchChar,Pos))!=NotFound) P[Pos]=ReplaceChar;
  1621.   }
  1622.  
  1623. //.parse
  1624.  
  1625. void String40::Replace(const char* SearchStr, const char* ReplaceStr)
  1626.   {
  1627.     int SLen=strlen(SearchStr);
  1628.     int RLen=strlen(ReplaceStr);
  1629.     Bool SameLen=(SLen==RLen);
  1630.     int Pos=0;
  1631.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1632.       {
  1633.         if (SameLen)
  1634.           {
  1635.             int I;
  1636.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1637.           }
  1638.         else if (SLen>RLen)
  1639.           {
  1640.             Delete(Pos,SLen-RLen);
  1641.             int I;
  1642.             For(I,RLen) P[Pos+I]=ReplaceStr[I];
  1643.           }
  1644.         else
  1645.           {
  1646.             int I;
  1647.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1648.             Insert(&ReplaceStr[SLen],Pos+SLen);
  1649.           }
  1650.       }
  1651.   }
  1652.  
  1653. //.parse
  1654.  
  1655. void String40::Replace(const char SearchChar, const char* ReplaceStr)
  1656.   {
  1657.     int RLen=strlen(ReplaceStr);
  1658.     int Pos=0;
  1659.     while((Pos=Index(SearchChar,Pos))!=NotFound)
  1660.       {
  1661.         if (RLen>1)
  1662.           {
  1663.             P[Pos]=*ReplaceStr;
  1664.             Insert(&ReplaceStr[1],Pos+1);
  1665.           }
  1666.         if (RLen==1) P[Pos]=*ReplaceStr;
  1667.         else Delete(Pos);
  1668.       }
  1669.   }
  1670.  
  1671. //.parse
  1672.  
  1673. void String40::Replace(const char* SearchStr, const char ReplaceChar)
  1674.   {
  1675.     int SLen=strlen(SearchStr);
  1676.     int Pos=0;
  1677.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1678.       {
  1679.         if (SLen>1)
  1680.           {
  1681.             Delete(Pos,SLen-1);
  1682.             P[Pos]=ReplaceChar;
  1683.           }
  1684.         else P[Pos]=ReplaceChar;
  1685.       }
  1686.   }
  1687.  
  1688. //.parse
  1689.  
  1690. void String40::Replace(const char SearchChar, const char ReplaceChar)
  1691.   {
  1692.     int Pos=0;
  1693.     while((Pos=Index(SearchChar,Pos))!=NotFound) P[Pos]=ReplaceChar;
  1694.   }
  1695.  
  1696.  
  1697.  
  1698.