s-string.h 12.5 KB
Newer Older
Per Cederqvist's avatar
Per Cederqvist committed
1
/*
2
3
 * $Id: s-string.h,v 1.14 1999/05/24 09:34:14 ceder Exp $
 * Copyright (C) 1990-1996  Lysator Academic Computer Association.
Linus Tolke's avatar
Linus Tolke committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 *
 * This file is part of the LysKOM server.
 * 
 * LysKOM is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 1, or (at your option) 
 * any later version.
 * 
 * LysKOM is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LysKOM; see the file COPYING.  If not, write to
 * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
 * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
 * MA 02139, USA.
 *
 * Please mail bug reports to bug-lyskom@lysator.liu.se. 
 */
/*
26
 * $Id: s-string.h,v 1.14 1999/05/24 09:34:14 ceder Exp $
Per Cederqvist's avatar
Per Cederqvist committed
27
 *
Per Cederqvist's avatar
Per Cederqvist committed
28
29
30
31
32
 *  s-string.h
 *		Our own string type.  Definition of string type,
 *		and functions to manipulate these strings.
 *
 *
33
 *  Copyright (C) 1990-1996	Lysator Computer Club,
Per Cederqvist's avatar
Per Cederqvist committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 *			Linkoping University,  Sweden
 *
 *  Everyone is granted permission to copy, modify and redistribute
 *  this code, provided the people they give it to can.
 *
 *
 *  Author:	Thomas Bellman
 *		Lysator Computer Club
 *		Linkoping University
 *		Sweden
 *
 *  email:	Bellman@Lysator.LiU.SE
 */



#ifndef  S_STRING_H_ALREADY_INCLUDED__
#define  S_STRING_H_ALREADY_INCLUDED__


#include <limits.h>
#include <stdio.h>

Per Cederqvist's avatar
Per Cederqvist committed
57
#include "misc-types.h"
58
#include "s-collat-tabs.h"
Per Cederqvist's avatar
Per Cederqvist committed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104


typedef 	long		String_size;
#define		END_OF_STRING	LONG_MAX


/*
 *  All objects of type String *must* be initialized to EMPTY_STRING
 *  before using any destructive function on them.  If you only use
 *  non-destructive functions (s_strlen(), s_strcmp(), ...), you can
 *  set them with
 *	str = s_fcrea_str("Hej hopp i lingonskogen");
 *  But the value of this may *not* be used in any destructive call,
 *  since str.string points to read-only memory.

 *  Note also that you need to call s_free() on any auto variables
 *  of type String before exiting the block they are declared in,
 *  since otherwise the memory they use will still be allocated.
 *  This is of course the same rules as for normal pointers.

 *  To make it possible for people to use their own storage
 *  management routines, you can set the functions to use for
 *  malloc(), realloc() and free() with the
 *  s_set_storage_management() function.  This MUST be called
 *  before using any of the other functions, even if you want to
 *  use the normal malloc(), realloc() and free().

 *  Terminology:
 *  --	A "separate" String is an object that points to some memory
 *	that is somehow obtained from malloc() or its cousins.  This
 *	means that it is legal to free() or realloc() it.
 */


typedef struct {
	String_size	  len;
	unsigned char	* string;
} String;

/*
 *  Note that the first character is String.string[0], and the last
 *  character is String.string[String.len-1]
 */


/*  This is the representation of the empty String  */
Per Cederqvist's avatar
Per Cederqvist committed
105
#define			EMPTY_STRING_i		{ 0, NULL }
Per Cederqvist's avatar
Per Cederqvist committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
extern  const String	EMPTY_STRING;



/*
 *  Functions to manipulate strings of type 'String'.
 *  All these functions return a value of type Success, which is
 *  an enum of OK an FAILURE (do NOT trust the order of these!).
 *
 *  All functions automatically allocates (and deallocates) any
 *  necessary storage.
 */



typedef void	(*free_function) (void *);
typedef void  * (*malloc_function) (size_t);
typedef void  * (*realloc_function) (void *, size_t);

/*
 *  Set the functions to use for storage management.  These must
 *  be call compatible with the normal functions malloc(),
 *  realloc() and free().
 */
extern  void
s_set_storage_management (malloc_function	new_malloc,
			  realloc_function	new_realloc,
			  free_function		new_free);


/*
 *  Returns the number of characters in a String
 */
#define s_strlen(str)	((str).len)



/*
 *  Create an object of type String from an ordinary C string.
 */
extern  Success
s_crea_str (String	* dest_string,
	    const char	* c_string    );


/*
 * Create a string from a buffer. The contents of the buffer
 * are copied into the new string.
 */

extern  Success
157
158
159
s_mem_crea_str (String	    	     * dest_string,
	    	const unsigned char  * buffer,
	    	String_size   	       length);
Per Cederqvist's avatar
Per Cederqvist committed
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

/*
 * Create a string of a given size. The contents of the string
 * are unspecified. The LysKOM-server uses this to get a string
 * of a fixed size into which it can fread() data. This is probably
 * not a good idea since it relies heavily on the implementation
 * of strings. However, by using this function, those places are
 * easy to identify if the implementation should be done differently.
 */

extern  Success
s_size_crea_str(String      *result,
		String_size length);

/*
 *  Return a temporary String from a C string, i e return a struct
 *  pointing to the actual C string.  Suitable for sending a 'String'
 *  object as parameter to a function (IF that function does not modify
Per Cederqvist's avatar
Per Cederqvist committed
178
 *  its parameter).  Note that normally String variables should be set
Per Cederqvist's avatar
Per Cederqvist committed
179
180
181
 *  by s_crea_str(), to deallocate the memory used by it.
 */
extern  String
182
s_fcrea_str (const char  * c_string);
Per Cederqvist's avatar
Per Cederqvist committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354



/*
 *  Free's the space used by a String object.  The object is
 *  set to EMPTY_STRING.
 */
extern  void
s_clear (String   * str);


/*
 * Create an ordinary C string from a String.
 * The pointer returned will point to a '\0'-terminated character
 * array which is obtained with the malloc-function supplied to
 * s_set_storage_management(). It should be freed by the caller.
 * NULL is returned if there is an error. The String may contain
 * '\0's, but the resulting string will be truncated at the first
 * '\n'. Thou shalt not depend on this behaviour. Later versions
 * might substitute "foobar" for '\0's.
 */


extern  char *
s_crea_c_str(const String  source);



/*
 *  Copy SOURCE_STRING to DEST_STRING.  Old value of DEST_STRING is
 *  retained if an error was encountered.  Note that it is never
 *  legal to do 's_strcpy(&foo, foo)', since the string 'foo' is
 *  pointing to is reallocated before it is read.
 */
extern  Success
s_strcpy (String	* dest_string,
	  const String	  source_string);



/*
 *  In String STR remove the characters starting with number FIRST
 *  and ending with number LAST, inclusive.  If FIRST > LAST, then
 *  no characters are removed.
 */
extern  Success
s_strdel (String	* str,
	  String_size	  first,
	  String_size	  last );



/*
 *  Append SOURCE_STRING to the end of DEST_STRING.  DEST_STRING is not
 *  changed if an error is encountered.
 */
extern  Success
s_strcat (String	* dest_string,
	  const String	  source_string);



/*
 *  Extract a substring from SOURCE_STRING, starting with char no
 *  START_CHAR and ending with char no END_CHAR.  First character
 *  is character no 0.  If END_CHAR < START_CHAR, then DEST_STRING
 *  is set to 'EMPTY_STRING'.  If END_CHAR is equal to the macro
 *  'END_OF_STRING', then the substring reaches to the last character
 *  in SOURCE_STRING.
 */
extern  Success
s_substr (String	* dest_string,
	  const String	  source_string,
	  String_size	  start_char,
	  String_size	  end_char);



/*
 *  Fast extraction of a substring.  Returns an object of type
 *  String wich points into SOURCE_STRING.  Thus you should NEVER
 *  modify the result of this function.  (Raw character modifying
 *  is OK if you know what you are doing, but never use anything
 *  that might call free or realloc on it.)  If END_CHAR is equal
 *  to the macro 'END_OF_STRING', then the substring reaches to
 *  the last character in SOURCE_STRING.
 */
extern  String
s_fsubstr (const String	  source_string,
	   String_size	  start_char,
	   String_size	  end_char	);



/*  Check if a string is the empty string. Returns TRUE or FALSE.
 */
#define s_empty(str) (((str).len == 0) ? TRUE : FALSE)


/*  Check if two strings are equal.
 */
#define s_streq(str1, str2)	(s_strcmp(str1, str2) == 0)
#define s_usr_streq(str1, str2, collat_tab)	\
	(s_usr_strcmp(str1, str2, collat_tab) == 0)



/*
 *  Compares two strings.  Returns -1 if STR1 is lexically less
 *  than STR2, +1 if STR1 is greater than STR2, and 0 if they are
 *  equal.
 */
extern  int
s_strcmp (String   str1,
	  String   str2);



/*
 *  Compares two strings with user specified collation order.
 *  Returns the same values as s_strcmp().
 *  COLLAT_TAB is a table of collating values for every char.
 */
extern  int
s_usr_strcmp (String	str1,
	      String	str2,
	      char	collat_tab [ COLLAT_TAB_SIZE ]);



/*
 *  Checks if STR1 is the exact beginning of STR2, e g if STR1
 *  is "foobar" and STR2 is "foobarf" then the result is TRUE.
 */
extern  Bool
s_strhead (String	str1,
	   String	str2);



/*
 *  Checks if STR1 is the exact beginning of STR2, but uses a
 *  user specified collating sequence for comparison (as in
 *  s_usr_strcmp()).
 */
extern  Bool
s_usr_strhead (String	str1,
	       String	str2,
	       char	collat_tab [ COLLAT_TAB_SIZE ]);



/*
 *  From STR strip all trailing characters that can be found
 *  in STRIP_STRING.  STR isn't altered in any way.  The returned
 *  object points to the same string as STR, but with a possibly
 *  shorter length.  The pointer is unchanged *even* if the length
 *  should be 0, which means you don't "lose" the storage but can
 *  free it with s_free().
 */
extern  String
s_strip_trailing (String	  str,
		  const String	  strip_string);



/*
 *  Returns the index of the first occurrence in the String STR
 *  of the character CH.  Returns -1 if no occurrence.
 */
extern  String_size
s_strchr (const String	  str,
Per Cederqvist's avatar
Per Cederqvist committed
355
	  unsigned char	  ch,
Per Cederqvist's avatar
Per Cederqvist committed
356
357
358
359
360
361
362
363
364
365
	  String_size	  start_pos);



/*
 *  Returns the index of the last occurrence in the String STR
 *  of the character CH.  Returns -1 if no occurrence.
 */
extern  String_size
s_strrchr (const String	  str,
Per Cederqvist's avatar
Per Cederqvist committed
366
	   unsigned char  ch,
Per Cederqvist's avatar
Per Cederqvist committed
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
	   String_size	  start_pos);



/*
 *  Return the index of the first occurrence in the String LOOK_IN
 *  of any of the characters in the String SEARCH_FOR, or -1 if none.
 */
extern  String_size
s_strpbrk (const String	  look_in,
	   const String	  search_for);



/*
 *  Find the first character in LOOK_IN that *is* present in
 *  SEARCH_FOR, and return its index, or the length of LOOK_IN if
 *  it contains only characters that are not present in SEARCH_FOR.
 */
extern  String_size
s_strcspn (const String	  look_in,
	   const String	  search_for);



/*
 *  Find the first character in LOOK_IN that is *not* present in
 *  SKLIP_CHARS, and return its index, or the length of LOOK_IN if
 *  it contains only characters that are present in SKIP_CHARS.
 */
extern  String_size
s_strspn (const String	  look_in,
	  const String	  skip_chars);



/*
 *  Pick out the first token from SOURCE separated by one or more
 *  of the characters in SEPARATORS, starting in position START_POS.
 *
 *  More specifically: start in position START_POS and skip over
 *  separator characters (any of those present in SEPARATORS).
 *  Extract the substring starting with the first non-separator,
 *  and ending the character immediately before the first separator
 *  following.  *start_pos will be the index of the first separator
 *  character after the token.
 *
 *  Note that the return value actually points into SOURCE.  It
 *  is not separately allocated.
 */
extern  String
s_strtok (const String	  source,
	  String_size	* start_pos,
	  const String	  separators);




/****************************************************
 *	Misc. routines using our String type.	    *
 ****************************************************/


/*
 *  Convert the String STR to a long, using the base BASE.
 *  Leading blanks are skipped according to isblank() in <ctype.h>.
 *  The index of the first character that couldn't be used to form
 *  the number is returned in *FIRST_ILL_CHAR.  Returns -1 in
 *  *first_ill_char if there was an error in the parameters.
 *  BASE may be in the range 2..36
 */
extern  long
s_strtol (const String	  str,
	  String_size	* first_ill_char,
	  const int	  base		);




/************************************************
 *	Input/Output routines for String	*
 ************************************************/



/*
 *  Outputs the string STR on the stream STREAM.  No information
 *  about the length of the string is output.
 */
extern Success
s_fputs (FILE		* stream,
	 const String	  str);



/*
 *  Outputs the string STR on stdout.  No information
 *  about the length of the string is output.
 */
#define s_puts(str) s_fputs(stdout, str)


#endif  /*  _S_STRING_H_ALREADY_INCLUDED__  */