1 |
/* |
2 |
* Dynamic String Utilities |
3 |
* |
4 |
* Taken from the tcl collection. - September 21, 1995 |
5 |
* by Kirk Abbott, and lightly modified to suit the neeeds of |
6 |
* ASCEND. |
7 |
* |
8 |
* Version: $Revision: 1.1 $ |
9 |
* Version control file: $RCSfile: dstring.c,v $ |
10 |
* Date last modified: $Date: 1997/07/18 11:41:34 $ |
11 |
* Last modified by: $Author: mthomas $ |
12 |
* |
13 |
* This file is part of the Ascend Language Interpreter. |
14 |
* |
15 |
* Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly |
16 |
* |
17 |
* The Ascend Language Interpreter is free software; you can redistribute |
18 |
* it and/or modify it under the terms of the GNU General Public License as |
19 |
* published by the Free Software Foundation; either version 2 of the |
20 |
* License, or (at your option) any later version. |
21 |
* |
22 |
* The Ascend Language Interpreter is distributed in hope that it will be |
23 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
24 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
25 |
* General Public License for more details. |
26 |
* |
27 |
* You should have received a copy of the GNU General Public License |
28 |
* along with the program; if not, write to the Free Software Foundation, |
29 |
* Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named |
30 |
* COPYING. |
31 |
* |
32 |
*/ |
33 |
|
34 |
#include <utilities/ascConfig.h> |
35 |
#include <utilities/ascMalloc.h> |
36 |
#include <utilities/ascPanic.h> |
37 |
#include "dstring.h" |
38 |
#include "mathmacros.h" |
39 |
|
40 |
|
41 |
void Asc_DStringInit(register Asc_DString *dsPtr) |
42 |
{ |
43 |
asc_assert(NULL != dsPtr); |
44 |
dsPtr->string = dsPtr->staticSpace; |
45 |
dsPtr->length = 0; |
46 |
dsPtr->spaceAvl = ASC_DSTRING_STATIC_SIZE; |
47 |
dsPtr->staticSpace[0] = '\0'; |
48 |
} |
49 |
|
50 |
|
51 |
char *Asc_DStringSet(Asc_DString *dsPtr, CONST char *string) |
52 |
{ |
53 |
int length; |
54 |
char *newString; |
55 |
|
56 |
asc_assert(NULL != dsPtr); |
57 |
asc_assert(NULL != string); |
58 |
asc_assert((int)(MAXINT - strlen(string)) >= 0); |
59 |
|
60 |
length = (int)strlen(string); |
61 |
|
62 |
/* |
63 |
* Allocate a larger buffer for the string if the current one isn't |
64 |
* large enough. Allocate extra space in the new buffer so that there |
65 |
* will be room to grow before we have to allocate again. |
66 |
*/ |
67 |
if (length >= dsPtr->spaceAvl) { |
68 |
dsPtr->spaceAvl = length*2; |
69 |
newString = (char *) ascmalloc((size_t) dsPtr->spaceAvl); |
70 |
if (dsPtr->string != dsPtr->staticSpace) { |
71 |
ascfree(dsPtr->string); |
72 |
} |
73 |
dsPtr->string = newString; |
74 |
} |
75 |
|
76 |
/* |
77 |
* Copy the new string into the buffer |
78 |
*/ |
79 |
strncpy(dsPtr->string, string, (size_t)length); |
80 |
dsPtr->length = length; |
81 |
dsPtr->string[dsPtr->length] = '\0'; |
82 |
return dsPtr->string; |
83 |
} |
84 |
|
85 |
|
86 |
|
87 |
char *Asc_DStringAppend(register Asc_DString *dsPtr, |
88 |
CONST char *string, |
89 |
int length) |
90 |
{ |
91 |
int str_length; |
92 |
int newSize; |
93 |
char *newString; |
94 |
|
95 |
asc_assert(NULL != dsPtr); |
96 |
asc_assert(NULL != string); |
97 |
asc_assert((int)(MAXINT - strlen(string)) >= 0); |
98 |
|
99 |
str_length = (int)strlen(string); |
100 |
|
101 |
if (length < 0) { |
102 |
length = str_length; |
103 |
} |
104 |
else { |
105 |
length = MIN(length, str_length); |
106 |
} |
107 |
|
108 |
newSize = length + dsPtr->length; |
109 |
|
110 |
/* |
111 |
* Allocate a larger buffer for the string if the current one isn't |
112 |
* large enough. Allocate extra space in the new buffer so that there |
113 |
* will be room to grow before we have to allocate again. |
114 |
*/ |
115 |
if (newSize >= dsPtr->spaceAvl) { |
116 |
dsPtr->spaceAvl = newSize*2; |
117 |
newString = (char *) ascmalloc((size_t) dsPtr->spaceAvl); |
118 |
strcpy(newString, dsPtr->string); |
119 |
if (dsPtr->string != dsPtr->staticSpace) { |
120 |
ascfree(dsPtr->string); |
121 |
} |
122 |
dsPtr->string = newString; |
123 |
} |
124 |
|
125 |
/* |
126 |
* Copy the new string into the buffer at the end of the old one. |
127 |
*/ |
128 |
strncpy(dsPtr->string + dsPtr->length, string, (size_t)length); |
129 |
dsPtr->length += length; |
130 |
dsPtr->string[dsPtr->length] = '\0'; |
131 |
return dsPtr->string; |
132 |
} |
133 |
|
134 |
|
135 |
|
136 |
void Asc_DStringTrunc(register Asc_DString *dsPtr, int length) |
137 |
{ |
138 |
asc_assert(NULL != dsPtr); |
139 |
|
140 |
if (length < 0) { |
141 |
length = 0; |
142 |
} |
143 |
if (length < dsPtr->length) { |
144 |
dsPtr->length = length; |
145 |
dsPtr->string[length] = '\0'; |
146 |
} |
147 |
} |
148 |
|
149 |
|
150 |
|
151 |
void Asc_DStringFree(register Asc_DString *dsPtr) |
152 |
{ |
153 |
asc_assert(NULL != dsPtr); |
154 |
if (dsPtr->string != dsPtr->staticSpace) { |
155 |
ascfree(dsPtr->string); |
156 |
} |
157 |
dsPtr->string = dsPtr->staticSpace; |
158 |
dsPtr->length = 0; |
159 |
dsPtr->spaceAvl = ASC_DSTRING_STATIC_SIZE; |
160 |
dsPtr->staticSpace[0] = '\0'; |
161 |
} |
162 |
|
163 |
|
164 |
|
165 |
char *Asc_DStringResult(Asc_DString *dsPtr) |
166 |
{ |
167 |
register char *result; |
168 |
|
169 |
asc_assert (NULL != dsPtr); |
170 |
result = (char *)ascmalloc(strlen(dsPtr->string)+1); |
171 |
strcpy(result,dsPtr->string); |
172 |
Asc_DStringFree(dsPtr); |
173 |
return result; |
174 |
} |