Select Git revision
s-string.h 11.46 KiB
/*
* s-string.h
* Our own string type. Definition of string type,
* and functions to manipulate these strings.
*
*
* Copyright (C) 1990 Lysator Computer Club,
* 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>
#include <stddef.h>
#include <misc-types.h>
#include "s-collat-tabs.h"
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 */
#define EMPTY_STRING_i ((String) { 0, NULL })
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
s_mem_crea_str (String * dest_string,
const unsigned char * buffer,
String_size length);
/*
* 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
* it's parameter. Note that normally String variables should be set
* by s_crea_str(), to deallocate the memory used by it.
*/
extern String
s_fcrea_str (const unsigned char * c_string);
/*
* 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,
char ch,
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,
char ch,
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__ */