gen_stri.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 812 行 · 第 1/3 页
C
812 行
//
// 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 03/17/89 -- Initial design and implementation
// Updated: MBN 04/06/89 -- Performance enhancement by changing several
// methods and friends to inline, and addition
// of two private friend functions.
// Updated: LGO 06/03/89 -- Fix string growth algorithm.
// Updated: MBN 06/06/89 -- Performance enhancement by making reference count
// and memory check/adjustment inline, addition of a
// resize method and a growth ratio data slot, and
// change of constructors to set specific object size,
// not class as a whole
// Updated: DKM 06/23/89 -- To get around a bug in the Glockenspiel translator
// we had to explicitly typecast arguments for calls
// to the overloaded unix string functions, including
// strchr, strrchr, strcpy, strcmp, strncmp, strtod,
// and strtol.
// Updated: MNF 06/27/89 -- Added the insert, remove, replace, yank, and
// sub_string public member functions.
// Updated: MBN 06/30/89 -- Updated to include support for regular expressions
// 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: LGO 10/28/89 -- Removed is_lt, is_gt, is_le, is_ge, is_equal
// and is_not_equal (use char* functions instead)
// Updated: MBN 12/15/89 -- Sprinkled "const" qualifier all over the place!
// Updated: MBN 01/02/90 -- Made find search for the first/next regexp match
// Updated: LGO 01/03/90 -- Avoid use of strncat
// Updated: LGO 01/05/90 -- Partial re-write of most everything to simplify
// and speed-up the code
// Updated: MJF 03/12/90 -- Added group names to RAISE
// Updated: MJF 05/21/90 -- Moved delete from grow_memory to validate
// Updated: DLS 03/22/91 -- New lite version
// Updated: JAM 08/14/92 -- removed DOS specifics, stdized #includes
// Updated: JAM 08/14/92 -- added static alloc_size_s def and initialization
//
// This file contains member and friend function implementation code for the
// CoolGen_String class defined in the Gen_String.h and Regexp.h header files.
// Where appropriate and possible, interfaces to, and us of, existing system
// functions has been incorporated. An overview of the structure of the
// Edit_String class, along with a synopsis of each member and friend function,
// can be found in the String.h header file.
//
#ifndef GEN_STRINGH // If class not defined
#include <cool/Gen_String.h> // Include class specification
#endif
#include <ctype.h> // Include character processing macros
// alloc_size_s -- Memory allocation growth size
int CoolGen_String::alloc_size_s = MEM_BLK_SZ; // Init allocation size
// update_ref_count -- Gives "this" it's own (unshared) copy of a string
// Input: None
// Output: None
void CoolGen_String::update_ref_count() {
this->p->ref_count--; // Decrement reference count
this->p = new String_Layout; // Allocate layout structure
this->p->ref_count = 1; // One object at the moment
this->p->size = 0; // No memory allocated yet
this->p->start = this->str; // Pointer to start of string
}
// validate -- protected method called when a string is modified
// Input: before calling, set this->length to new length.
// dont_copy - set to TRUE If you don't want the old string
// copied on a grow, or ref-count copy
// Output: None
void CoolGen_String::validate(Boolean dont_copy) {
if (this->p->ref_count > 1) { // If sharing memory with another CoolGen_String
this->update_ref_count(); // decrement reference count and
this->grow_memory(dont_copy); // allocate memory for own copy
}
else if (this->length >= this->p->size) { // If not long enough,
char* ostr = this->str; // save old string to delete later
this->grow_memory(dont_copy); // allocate memory,
if (ostr != NULL) delete ostr; // and free old memory block
}
}
// grow_memory -- Called when string isn't long enough, or to allocate memory
// after update_ref_count inside validate.
// Input: dont_copy - TRUE If you don't want the old string copied.
// Output: None
void CoolGen_String::grow_memory (Boolean dont_copy) {
char* old_chars = this->str;
long size = this->p->size;
if (this->length >= size) { // Called from validate just to allocate memory
if (this->growth_ratio != 0.0) // If a growth ratio is set
size += long(size * this->growth_ratio);
else
size += this->alloc_size_s; // Increment by allocation size
if (size < this->length) // But if still not big enough
size = this->length+1; // Grow to big enough size
this->p->size = size;
}
this->str = new char[size]; // Allocate memory for string
this->p->start = this->str; // Pointer to start of string
if (old_chars != NULL) {
if (!dont_copy)
strcpy ((char *)this->str, old_chars); // Copy initial string
}
else
*this->str = END_OF_STRING;
}
// CoolGen_String() -- Simple constructor for a CoolGen_String object. Memory is
// allocated for the layout structure and char* pointers are
// set to the "alloc_size_s" value.
// Input: None
// Output: CoolGen_String reference
CoolGen_String::CoolGen_String () {
this->growth_ratio = 0.0; // Initialize growth ratio
this->str = new char[alloc_size_s]; // Allocate block of memory
this->length = 0; // Zero characters in string
this->p = new String_Layout; // Allocate layout structure
this->p->ref_count = 1; // One String object at the moment
this->p->size = alloc_size_s; // Size of allocated block
this->p->start = str; // Pointer to start of string
*this->str = END_OF_STRING; // END_OF_STRING terminate for safety
this->rgexp = NULL; // No regular expression yet
}
// CoolGen_String(char) -- Constructor to initialize object with a char
// Input: character
// Output: CoolGen_String reference to new object
CoolGen_String::CoolGen_String (char c) {
this->growth_ratio = 0.0; // Initialize growth ratio
this->length = 1; // Length of character is 1
this->str = new char[length+1]; // Allocate memory for string
this->p = new String_Layout; // Allocate layout structure
this->p->ref_count = 1; // One String object at the moment
this->p->size = this->length+1; // Size of allocated block
this->p->start = this->str; // Pointer to start of string
*this->str = c; // Assign character
*(this->str+1) = END_OF_STRING; // END_OF_STRING terminator for string
this->rgexp = NULL; // No regular expression yet
}
// CoolGen_String(char*) -- Constructor to initialize object with a char*.
// Input: char* pointer
// Output: CoolGen_String reference to new object
CoolGen_String::CoolGen_String (const char* c) {
this->growth_ratio = 0.0; // Initialize growth ratio
this->length = strlen (c); // Determine length of character string
this->str = new char[length+1]; // Allocate memory for string
this->p = new String_Layout; // Allocate layout structure
this->p->ref_count = 1; // One String object at the moment
this->p->size = this->length+1; // Size of allocated block
this->p->start = this->str; // Pointer to start of string
strcpy ((char *)this->str, c); // Copy characters
this->rgexp = NULL; // No regular expression yet
}
// CoolGen_String(CoolGen_String&) -- Constructor to initialize object to CoolGen_String
// Note that this involves use of delayed copy via
// the reference count mechanism.
// Input: CoolGen_String reference
// Output: CoolGen_String reference to new object
CoolGen_String::CoolGen_String (const CoolGen_String& s) {
this->growth_ratio = s.growth_ratio; // Initialize growth ratio
this->length = s.length; // Determine length of character string
this->str = s.str; // Point to same string memory block
this->p = s.p; // Point to same layout structure
this->p->ref_count++; // Increment reference count
this->rgexp = NULL; // No regular expression yet
}
// CoolGen_String(char*, size) -- Constructor to initialize object with a char*
// and control initial allocation size
// Input: char* pointer and size value
// Output: CoolGen_String reference to new object
CoolGen_String::CoolGen_String (const char* c, long sz) {
this->length = strlen (c); // Determine length of character string
this->p = new String_Layout; // Allocate layout structure
if (this->length > sz) { // If initial string is larger
this->str = new char[length+1]; // Allocate memory for string
this->p->size = length+1; // Size of allocated block
}
else {
this->str = new char[sz+1]; // Allocate memory for string
this->p->size = sz+1; // Size of allocated block
}
this->p->ref_count = 1; // One String object at the moment
this->p->start = this->str; // Pointer to start of string
strcpy ((char *)this->str, c); // Copy characters
this->rgexp = NULL; // No regular expression yet
}
// CoolGen_String(CoolGen_String&, long) -- Constructor to initialize object to a
// CoolGen_String and control initial alloc size
// Input: CoolGen_String reference and size value
// Output: CoolGen_String reference to new object
CoolGen_String::CoolGen_String (const CoolGen_String& s, long sz) {
this->length = s.length; // Determine length of character string
this->p = new String_Layout; // Allocate layout structure
if (this->length > sz) { // If initial string is larger
this->str = new char[length+1]; // Allocate memory for string
this->p->size = length+1; // Size of allocated block
}
else {
this->str = new char[sz+1]; // Allocate memory for string
this->p->size = sz+1; // Size of allocated block
}
this->p->ref_count = 1; // One String object at the moment
this->p->start = this->str; // Pointer to start of string
strcpy ((char *)this->str, s.str); // Copy characters over
this->rgexp = NULL; // No regular expression yet
}
// ~CoolGen_String() -- CoolGen_String object destructor frees up allocated memory and
// decrements reference count if necessary
// Input: CoolGen_String object
// Output: None
CoolGen_String::~CoolGen_String () {
if (this->p->ref_count == 1) { // If not sharing mem with other String
delete this->str; // then delete String object
delete this->p; // Delete layout structure
} else
this->p->ref_count--; // Else decrement reference counter
delete this->rgexp; // Delete regular expression object
}
// 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 CoolGen_String::clear() {
this->length = 0; // Set new string length
if (this->rgexp) // If there is a Regexp object
this->rgexp->set_invalid(); // Invalidate compiled expression
if (this->p->ref_count == 1) // If not sharing mem with other String
*(this->str) = NULL; // Clear this String by using NULL
else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?