string.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 698 行 · 第 1/2 页

C
698
字号
//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
// Created: MBN 06/27/89 -- Initial design and implementation
// Updated: DKM 07/07/89 -- To work around Xenix 31 char limit:
//                          Shortened is_less_than        to is_lt
//                                    is_greater_than     to is_gt
//                                    is_less_or_equal    to is_le
//                                    is_greater_or_equal to is_ge
//                          Removed is_equal_or_less and is_greater_or_less
// Updated: MBN 09/07/89 -- Added conditional exception handling
// Updated: MBN 09/26/89 -- Fixed bug to set size when growth size ratio given
// Updated: LGO 10/11/89 -- Removed operator>>
// Updated: MBN 10/24/89 -- Fixed backwards comparison in is_lt and is_gt
// Updated: LGO 10/28/89 -- Removed is_lt, is_gt, is_le, is_ge, is_equal
//                          and is_not_equal (use char* functions instead)
// Updated: LGO 01/03/90 -- Avoid use of strncat
// Updated: LGO 01/03/90 -- Re-write trim, right_trim, left_trim, upcase,
//                          downcase, capitalize, insert, replace, yank,
//                          sub_string, and strncpy to reduce heap allocation
// Updated: LGO 01/04/90 -- Delay memory allocation (see Empty_String_g)
// Updated: MJF 03/12/90 -- Added group names to RAISE
// Updated: DLS 03/22/91 -- New lite version
// Updated: JAM 08/11/92 -- removed DOS specifics, stdized #includes
// Updated: JAM 08/11/92 -- added static data member def
//
// This file contains  member and  friend function implementation code  for the
// CoolString  class defined in the String.h   header file.   Where appropriate and
// possible,  interfaces to,  and us  of,   existing  system functions has been
// incorporated. An overview of the structure of the CoolString class, along with a
// synopsis of each member  and friend function, can be  found  in the String.h
// header file.
//

#ifndef STRINGH                                 // If class not been defined
#include <cool/String.h>                        // Include class header file
#endif

#include <ctype.h>              // Include character processing macros


char* Empty_String_g = "";              // Used to allocate empty CoolStrings
                                        // this allows operator char* to work

// update_memory -- Private method to perform common memory check/adjustment
// Input:           CoolString reference, pointer to initial CoolString value
// Output:          None

void update_memory (CoolString& s) {
  long size = s.size;
  if (s.growth_ratio != 0.0) {          // If a growth ratio is set
    size = long(size * (1.0 + s.growth_ratio)); // Get new size
    if (size < s.length)                // But if this is still not big enough
      size = s.length;                  // grow to big enough size
  }
  else if ((s.length - size) < s.alloc_size_s) // If small growth factor
    size += s.alloc_size_s;             // Increment by allocation size
  else                                  // Else adding lots of characters
    size = s.length;                    // so grow to bigger size
  s.resize(size);                       // Grow the String
}


// CoolString() -- Simple constructor for a string object. Memory is allocated
//             for the char* pointer of size MEM_BLK_SIZE
// Input:      None
// Output:     CoolString reference


CoolString::CoolString () {             
  if (this->alloc_size_s == 0)          // If allocation size is uninitialized
    this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  this->growth_ratio = 0.0;             // Initialize growth ratio
  this->length = 0;                     // Zero characters in string
  this->size = 0;                       // Size of allocated block 
  this->str = Empty_String_g;           // No memory allocated
}


// CoolString(char) -- Constructor to initialize a string object with a char
// Input:          character
// Output:         CoolString reference to new object

CoolString::CoolString (char c) {       
  if (this->alloc_size_s == 0)          // If allocation size is uninitialized
    this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  this->growth_ratio = 0.0;             // Initialize growth ratio
  this->length = 1;                     // Length of character is 1
  this->size = this->length+1;          // Size of allocated block
  this->str = new char[size];           // Allocate memory for string
  *this->str = c;                       // Assign character
  *(this->str+1) = END_OF_STRING;       // END_OF_STRING terminator for string
}


// CoolString(char*) -- Constructor to initialize a string object with a char*
// Input:           char* pointer
// Output:          CoolString reference to new object

CoolString::CoolString (const char* c) { 
  if (this->alloc_size_s == 0)           // If allocation size is uninitialized
    this->alloc_size_s = MEM_BLK_SZ;     // Set memory block allocation size
  this->growth_ratio = 0.0;              // Initialize growth ratio
  this->length = strlen (c);             // Determine length of string
  this->size = this->length+1;           // Size of allocated block
  this->str = new char[size];            // Allocate memory for string
  strcpy ((char *)this->str, c);         // Copy characters 
}


// CoolString(CoolString&) -- Constructor to initialize a string object to
//                    that of another String.
// Input:             CoolString reference
// Output:            CoolString reference to new object

CoolString::CoolString (const CoolString& s) { 
  if (this->alloc_size_s == 0)          // If allocation size is uninitialized
    this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  this->growth_ratio = s.growth_ratio;  // Initialize growth ratio
  this->length = s.length;              // length of character string
  if (s.length > 0) {
    this->str = new char[s.size];       // Allocate memory for string
    strcpy ((char *)this->str, s.str);  // Copy characters
    this->size = s.size;                // Size of allocated block
  }
  else {
    this->str = Empty_String_g;         // Don't allocate when empty
    this->size = 0;
  }
}


// CoolString(char*, size) -- Constructor to initialize a string object with
//                        a char* and provide an initial size value
// Input:                 char* pointer and size value
// Output:                CoolString reference to new object

CoolString::CoolString (const char* c, long sz) {
  if (this->alloc_size_s == 0)          // If allocation size is uninitialized
    this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  this->length = strlen (c);            // Determine length of character string
  if (this->length > sz)                // If initial string is larger
    this->size = length+1;              // Size of allocated block
  else
    this->size = sz+1;                  // Size of allocated block
  this->str = new char[size];           // Allocate memory for string 
  strcpy ((char *)this->str, c);        // Copy characters
}


// CoolString(CoolString&, long) -- Constructor to initialize a string
//                          object with a String and provide
//                          an initial block size value
// Input:                   CoolString reference and size value
// Output:                  CoolString reference to new object

CoolString::CoolString (const CoolString& s, long sz) { 
  if (this->alloc_size_s == 0)          // If allocation size is uninitialized
    this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  this->length = s.length;              // Determine length of character string
  if (this->length > sz)                // If initial string is larger
    this->size = length+1;              // Size of allocated block
  else
    this->size = sz+1;                  // Size of allocated block
  this->str = new char[size];           // Allocate memory for string
  strcpy ((char *)this->str, s.str);    // Copy characters over
}


// ~CoolString() -- CoolString object destructor
// Input:       CoolString object
// Output:      None

CoolString::~CoolString () {                    // CoolString object destructor
  if (this->str != Empty_String_g)
    delete this->str;                   // Deallocate string memory
}


// clear -- Flush the character string from the string object by setting
//          the char* pointer to NULL and the length to zero.
// Input:   this* 
// Output:  None

void CoolString::clear() {
  *(this->str) = NULL;                  // Clear this CoolString by using NULL
  this->length = 0;                     // Set new string length
}


// strcpy -- CoolString copy of a single character to a CoolString object
// Input:    CoolString reference and a character
// Output:   CoolString object containing a character string

CoolString& strcpy (CoolString& s, char c) {
  if (s.size < 2) {                     // Allocate memory block
    if (s.str != Empty_String_g)        // When memory allocated
      delete s.str;                     // Delete block
    s.size = s.alloc_size_s;            // Size of allocated block
    s.str = new char[s.size];           // Allocate memory for string
  }
  s.length = 1;                         // Character string length
  *(s.str) = c;                         // Assign character
  *(s.str+1) = END_OF_STRING;           // END_OF_STRING terminator for string
  return s;                             // Return CoolString reference
}  


// strcpy -- CoolString copy of a char* to a CoolString object
// Input:    CoolString reference and a char* 
// Output:   CoolString object containing a character string

CoolString& strcpy (CoolString& s, const char *c) {
  s.length = strlen (c);                // Determine length of character string
  if (s.size <= s.length)               // If not enough memory allocated
    update_memory (s);                  // Adjust/update memory if necessary
  strcpy (s.str, c);                    // Else just copy new string value
  return s;                             // Return CoolString reference
}


// strcpy -- CoolString copy of one CoolString object to another. 
// Input:    Two CoolString references
// Output:   Updated CoolString object 

CoolString& strcpy (CoolString& s1, const CoolString& s2) {
  s1.length = s2.length;                // Determine length of character string
  if (s1.size > s2.length &&            // If string fits in allocated memory
      s1.str != Empty_String_g)         // and s1 has memory allocated
    strcpy (s1.str, s2.str);            // Copy string value
  else {
    if (s1.str != Empty_String_g)       // When memory allocated
      delete s1.str;                    // Delete block
    if (s2.length == 0) {
      s1.str = Empty_String_g;          // Don't allocate when empty
      s1.size = 0;
    }
    else {
      s1.size = s2.length+1;            // Set new block size
      s1.str = new char[s1.size];       // Allocate new block of memory
      strcpy (s1.str, s2.str);          // Copy string value
    }
  }
  return s1;                            // Return string reference
}

// strcat -- Concatenate a single character to a CoolString object
// Input:    CoolString reference and a character
// Output:   CoolString object concatenated with character 

CoolString& strcat (CoolString& s, char c) {
  s.length += 1;                        // Determine length of new string
  if (s.size <= s.length)               // If not enough allocated memory
    update_memory (s);                  // Adjust/update memory if necessary
  s.str[s.length-1] = c;                // Append new character
  s.str[s.length] = END_OF_STRING;      // END_OF_STRING terminator
  return s;                             // Return CoolString
}


// strcat -- Concatenate a CoolString and a char*
// Input:    CoolString reference and a char*
// Output    CoolString object concatentated with character string

CoolString& strcat (CoolString& s, const char* c) {
  long start_length = s.length;         // Find initial string length
  s.length += strlen (c);               // Determine length of new string
  if (s.size <= s.length)               // If not enough allocated memory
    update_memory (s);                  // Adjust/update memory if necessary
  strcpy (s.str+start_length, c);       // Concatenate characters   
  return s;                             // Return CoolString
}


// strncat -- Concatentate a CoolString with "n" characters from char*
// Input:     CoolString reference, char*, number of characters
// Output:    CoolString object concatenedate with "n" characters

CoolString& strncat (CoolString& s, const char* c, int n) {
#if ERROR_CHECKING
  if (n < 0) {                          // If invalid length specified
    printf ("CoolString::strncat(): Negative length %d.\n", n);
    exit (1);
  }
#endif
  long start_length = s.length;         // Find initial string length
  s.length += n;                        // Determine length of new string
  if (s.size <= s.length)               // If not enough allocated memory
    update_memory (s);                  // Adjust/update memory if necessary
  strncpy (s.str+start_length, c, size_t(n));   // Concatenate characters 
  return s;                             // Return CoolString
}


// strcat -- Concatenate two CoolString objects
// Input:    Two CoolString references
// Output:   CoolString object concatenated with CoolString object

CoolString& strcat (CoolString& s1, const CoolString& s2) {
  long start_length = s1.length;
  s1.length += s2.length;               // Determine length of new string
  if (s1.size <= s1.length)             // If not enough allocated memory
    update_memory (s1);                 // Adjust/update memory if necessary
  strcpy (s1.str+start_length, s2.str); // Concat characters   
  return s1;                            // Return CoolString
}


// strncat -- Concatentate a CoolString with "n" characters from a CoolString
// Input:     Two CoolString references and number of characters
// Output:    CoolString object concatenedate with "n" characters

CoolString& strncat (CoolString& s1, const CoolString& s2, int n) {
#if ERROR_CHECKING
  if (n < 0) {                          // If invalid length specified
    printf ("CoolString::strncat(): Negative length %d.\n", n);
    exit (1);
  }
#endif
  long start_length = s1.length;        // Find initial string length
  s1.length += n;                       // Determine length of new string
  if (s1.size <= s1.length)             // If not enough allocated memory
    update_memory (s1);                 // Adjust/update memory if necessary
  strncpy (s1.str+start_length, s2.str, size_t(n)); // Concat chars 
  return s1;                            // Return CoolString
}


// reverse -- Reverse the order of the characters in CoolString object
// Input:     CoolString object
// Output:    CoolString object with character order reverse

void CoolString::reverse () {
  char c;                                       // Temporary variable
  for (long i = 0, j = this->length-1;          // Counting from front and rear
       i < this->length / 2; i++, j--) {        // until we reach the middle
    c = this->str[i];                           // Save front character
    this->str[i] = this->str[j];                // Switch with rear character
    this->str[j] = c;                           // Copy new rear character
  }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?