1 /****************************************************************************
2 **
3 ** This file is part of GAP, a system for computational discrete algebra.
4 **
5 ** Copyright of GAP belongs to its developers, whose names are too numerous
6 ** to list here. Please refer to the COPYRIGHT file for details.
7 **
8 ** SPDX-License-Identifier: GPL-2.0-or-later
9 **
10 ** This file declares the functions which mainly deal with strings.
11 **
12 ** A *string* is a list that has no holes, and whose elements are all
13 ** characters. For the full definition of strings see chapter "Strings" in
14 ** the {\GAP} manual. Read also "More about Strings" about the string flag
15 ** and the compact representation of strings.
16 **
17 ** Strings in compact representation can be accessed and handled through
18 ** the functions 'NEW_STRING', 'CHARS_STRING' (and 'CSTR_STRING'),
19 ** 'GET_LEN_STRING', 'SET_LEN_STRING', 'GROW_STRING' and more.
20 */
21
22 #ifndef GAP_STRINGOBJ_H
23 #define GAP_STRINGOBJ_H
24
25 #include "objects.h"
26
27
28 /****************************************************************************
29 **
30 *F * * * * * * * * * * * * * * character functions * * * * * * * * * * * * *
31 */
32
33
34 /****************************************************************************
35 **
36 *V ObjsChar[<chr>] . . . . . . . . . . . . . . . . table of character values
37 **
38 ** 'ObjsChar' contains all the character values. That way we do not need to
39 ** allocate new bags for new characters.
40 */
41 extern Obj ObjsChar[256];
42
43
44 /****************************************************************************
45 **
46 *F CHAR_VALUE( <charObj> )
47 */
CHAR_VALUE(Obj charObj)48 EXPORT_INLINE UChar CHAR_VALUE(Obj charObj)
49 {
50 GAP_ASSERT(TNUM_OBJ(charObj) == T_CHAR);
51 return *(const UChar *)CONST_ADDR_OBJ(charObj);
52 }
53
54
55 /****************************************************************************
56 **
57 *F SET_CHAR_VALUE( <charObj>, <c> )
58 */
SET_CHAR_VALUE(Obj charObj,UChar c)59 EXPORT_INLINE void SET_CHAR_VALUE(Obj charObj, UChar c)
60 {
61 GAP_ASSERT(TNUM_OBJ(charObj) == T_CHAR);
62 *(UChar *)ADDR_OBJ(charObj) = c;
63 }
64
65
66 /****************************************************************************
67 **
68 *F SINT_CHAR(a)
69 **
70 ** 'SINT_CHAR' converts the character a (a UInt1) into a signed (C) integer.
71 */
SINT_CHAR(UInt1 a)72 EXPORT_INLINE Int SINT_CHAR(UInt1 a)
73 {
74 return a < 128 ? (Int)a : (Int)a-256;
75 }
76
77
78 /****************************************************************************
79 **
80 *F CHAR_SINT(n)
81 **
82 ** 'CHAR_SINT' converts the signed (C) integer n into an (UInt1) character.
83 */
CHAR_SINT(Int n)84 EXPORT_INLINE UInt1 CHAR_SINT(Int n)
85 {
86 return (UInt1)(n >= 0 ? n : n+256);
87 }
88
89
90 /****************************************************************************
91 **
92 *F * * * * * * * * * * * * * * * string functions * * * * * * * * * * * * * *
93 */
94
95 /****************************************************************************
96 **
97 *F IS_STRING_REP( <list> ) . . . . . . . . check if <list> is in string rep
98 */
IS_STRING_REP(Obj list)99 EXPORT_INLINE Int IS_STRING_REP(Obj list)
100 {
101 return (T_STRING <= TNUM_OBJ(list) &&
102 TNUM_OBJ(list) <= T_STRING_SSORT + IMMUTABLE);
103 }
104
105
106 /****************************************************************************
107 **
108 *F SIZEBAG_STRINGLEN( <len> ) . . . . size of Bag for string of length <len>
109 **
110 */
SIZEBAG_STRINGLEN(UInt len)111 EXPORT_INLINE UInt SIZEBAG_STRINGLEN(UInt len)
112 {
113 return len + 1 + sizeof(UInt);
114 }
115
116 /****************************************************************************
117 **
118 *F CSTR_STRING( <list> ) . . . . . . . . . . . . . . . C string of a string
119 *F CHARS_STRING( <list> ) . . . . . . . . . . . . . . same pointer
120 **
121 ** 'CSTR_STRING' returns the (address of the) C character string of the
122 ** string <list>. 'CHARS_STRING' is the same, but returns a pointer to an
123 ** unsigned char.
124 **
125 ** Remember that GAP strings can contain embedded NULLs, so do not assume
126 ** the string stops at the first null character, instead use
127 ** GET_LEN_STRING.
128 */
129
CSTR_STRING(Obj list)130 EXPORT_INLINE Char * CSTR_STRING(Obj list)
131 {
132 GAP_ASSERT(IS_STRING_REP(list));
133 return (Char *)ADDR_OBJ(list) + sizeof(UInt);
134 }
135
CONST_CSTR_STRING(Obj list)136 EXPORT_INLINE const Char * CONST_CSTR_STRING(Obj list)
137 {
138 GAP_ASSERT(IS_STRING_REP(list));
139 return (const Char *)CONST_ADDR_OBJ(list) + sizeof(UInt);
140 }
141
CHARS_STRING(Obj list)142 EXPORT_INLINE UChar * CHARS_STRING(Obj list)
143 {
144 GAP_ASSERT(IS_STRING_REP(list));
145 return (UChar *)ADDR_OBJ(list) + sizeof(UInt);
146 }
147
CONST_CHARS_STRING(Obj list)148 EXPORT_INLINE const UChar * CONST_CHARS_STRING(Obj list)
149 {
150 GAP_ASSERT(IS_STRING_REP(list));
151 return (const UChar *)CONST_ADDR_OBJ(list) + sizeof(UInt);
152 }
153
154 /****************************************************************************
155 **
156 *F GET_LEN_STRING( <list> ) . . . . . . . . . . . . . . length of a string
157 **
158 ** 'GET_LEN_STRING' returns the length of the string <list>, as a C integer.
159 */
160
GET_LEN_STRING(Obj list)161 EXPORT_INLINE UInt GET_LEN_STRING(Obj list)
162 {
163 GAP_ASSERT(IS_STRING_REP(list));
164 return INT_INTOBJ(CONST_ADDR_OBJ(list)[0]);
165 }
166
167 /****************************************************************************
168 **
169 *F SET_LEN_STRING( <list>, <len> ) . . . . . . . . . set length of a string
170 **
171 ** 'SET_LEN_STRING' sets length of the string <list> to C integer <len>.
172 */
173
SET_LEN_STRING(Obj list,Int len)174 EXPORT_INLINE void SET_LEN_STRING(Obj list, Int len)
175 {
176 GAP_ASSERT(IS_STRING_REP(list));
177 GAP_ASSERT(len >= 0);
178 GAP_ASSERT(SIZEBAG_STRINGLEN(len) <= SIZE_OBJ(list));
179 ADDR_OBJ(list)[0] = INTOBJ_INT(len);
180 }
181
182 /****************************************************************************
183 **
184 *F NEW_STRING( <len> ) . . . . . . . . . . . . . . . . . . make a new string
185 **
186 ** 'NEW_STRING' returns a new string with room for <len> characters. It also
187 ** sets its length to len.
188 **
189 */
190 Obj NEW_STRING(Int len);
191
192 /****************************************************************************
193 **
194 *F GROW_STRING(<list>, <len>) . . . . make sure a string is large enough
195 **
196 ** 'GROW_STRING' grows the string <list> if necessary to ensure that it
197 ** has room for at least <len> elements.
198 **
199 */
200
201 Int GrowString(Obj list, UInt need);
202
GROW_STRING(Obj list,Int len)203 EXPORT_INLINE void GROW_STRING(Obj list, Int len)
204 {
205 GAP_ASSERT(IS_STRING_REP(list));
206 GAP_ASSERT(len >= 0);
207 if (SIZEBAG_STRINGLEN(len) > SIZE_OBJ(list)) {
208 GrowString(list, len);
209 }
210 }
211
212 /****************************************************************************
213 **
214 *F SHRINK_STRING(<list>) . . . . . . . . . shrink a string to minimal size
215 **
216 ** 'SHRINK_STRING' gives back not needed memory allocated by string.
217 */
SHRINK_STRING(Obj list)218 EXPORT_INLINE void SHRINK_STRING(Obj list)
219 {
220 GAP_ASSERT(IS_STRING_REP(list));
221 ResizeBag(list, SIZEBAG_STRINGLEN(GET_LEN_STRING((list))));
222 }
223
224 /****************************************************************************
225 **
226 *F COPY_CHARS( <str>, <charpnt>, <n> ) . . . copies <n> chars, starting
227 ** from character pointer <charpnt>, to beginning of string
228 **
229 ** It assumes that the data area in <str> is large enough. It does not add
230 ** a terminating null character and not change the length of the string.
231 */
COPY_CHARS(Obj str,const UChar * pnt,Int n)232 EXPORT_INLINE void COPY_CHARS(Obj str, const UChar * pnt, Int n)
233 {
234 GAP_ASSERT(IS_STRING_REP(str));
235 GAP_ASSERT(n >= 0);
236 GAP_ASSERT(SIZEBAG_STRINGLEN(n) <= SIZE_OBJ(str));
237 memcpy(CHARS_STRING(str), pnt, n);
238 }
239
240 /****************************************************************************
241 **
242 *F PrintString( <list> ) . . . . . . . . . . . . . . . . . . print a string
243 **
244 ** 'PrintString' prints the string with the handle <list>.
245 **
246 ** No linebreaks are allowed, if one must be inserted anyhow, it must be
247 ** escaped by a backslash '\', which is done in 'Pr'.
248 */
249 void PrintString(Obj list);
250
251
252 /****************************************************************************
253 **
254 *F PrintString1( <list> ) . . . . . . . . . . . print a string for 'Print'
255 **
256 ** 'PrintString1' prints the string constant in the format used by the
257 ** 'Print' and 'PrintTo' function.
258 */
259 void PrintString1(Obj list);
260
261
262 /****************************************************************************
263 **
264 *F IS_STRING( <obj> ) . . . . . . . . . . . . test if an object is a string
265 **
266 ** 'IS_STRING' returns 1 if the object <obj> is a string and 0 otherwise.
267 ** It does not change the representation of <obj>.
268 */
269 extern Int (*IsStringFuncs [LAST_REAL_TNUM+1]) ( Obj obj );
270
IS_STRING(Obj obj)271 EXPORT_INLINE Int IS_STRING(Obj obj)
272 {
273 return (*IsStringFuncs[TNUM_OBJ(obj)])(obj);
274 }
275
276
277 /****************************************************************************
278 **
279 *F IsString( <obj> ) . . . . . . . . . . . . . test if an object is a string
280 **
281 ** 'IsString' returns 1 if the object <obj> is a string and 0 otherwise. It
282 ** does not change the representation of <obj>.
283 */
284 Int IsString(Obj obj);
285
286
287 /****************************************************************************
288 **
289 *F CopyToStringRep( <string> ) . . . copy a string to string representation
290 **
291 ** 'CopyToStringRep' copies the string <string> to a new mutable string in
292 ** string representation.
293 */
294 Obj CopyToStringRep(Obj string);
295
296
297 /****************************************************************************
298 **
299 *F ImmutableString( <string> ) . . . copy to immutable string in string rep.
300 **
301 ** 'ImmutableString' returns an immutable string in string representation
302 ** equal to <string>. This may return <string> if it already satisfies these
303 ** criteria.
304 */
305 Obj ImmutableString(Obj string);
306
307
308 /****************************************************************************
309 **
310 *F ConvString( <string> ) . . . . convert a string to string representation
311 **
312 ** 'ConvString' converts the string <string> to string representation.
313 */
314 void ConvString(Obj string);
315
316
317 /****************************************************************************
318 **
319 *F IsStringConv( <obj> ) . . . . . test if an object is a string and convert
320 **
321 ** 'IsStringConv' returns 1 if the object <obj> is a string, and 0
322 ** otherwise. If <obj> is a string it changes its representation to the
323 ** string representation.
324 */
325 Int IsStringConv(Obj obj);
326
327
328 // Functions to create mutable and immutable GAP strings from C strings.
329 // MakeString and MakeImmString are inlineable so 'strlen' can be optimised
330 // away for constant strings.
331
MakeStringWithLen(const char * buf,size_t len)332 EXPORT_INLINE Obj MakeStringWithLen(const char * buf, size_t len)
333 {
334 Obj result = NEW_STRING(len);
335 memcpy(CHARS_STRING(result), buf, len);
336 return result;
337 }
338
MakeString(const char * cstr)339 EXPORT_INLINE Obj MakeString(const char * cstr)
340 {
341 return MakeStringWithLen(cstr, strlen(cstr));
342 }
343
MakeImmString(const char * cstr)344 EXPORT_INLINE Obj MakeImmString(const char * cstr)
345 {
346 Obj result = MakeString(cstr);
347 MakeImmutableNoRecurse(result);
348 return result;
349 }
350
MakeImmStringWithLen(const char * buf,size_t len)351 EXPORT_INLINE Obj MakeImmStringWithLen(const char * buf, size_t len)
352 {
353 Obj result = MakeStringWithLen(buf, len);
354 MakeImmutableNoRecurse(result);
355 return result;
356 }
357
358
359 /****************************************************************************
360 **
361 *F C_NEW_STRING( <string>, <len>, <cstring> ) . . . . . . create GAP string
362 **
363 ** This macro is deprecated and only provided for backwards compatibility
364 ** with some package kernel extensions. Use 'MakeStringWithLen' and
365 ** 'MakeImmStringWithLen' instead.
366 */
367 #define C_NEW_STRING(string,len,cstr) \
368 string = MakeStringWithLen( (cstr), (len) )
369
370
371 /****************************************************************************
372 **
373 *F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * *
374 */
375
376 /****************************************************************************
377 **
378 *F InitInfoString() . . . . . . . . . . . . . . . . table of init functions
379 */
380 StructInitInfo * InitInfoString ( void );
381
382
383 #endif // GAP_STRINGOBJ_H
384