/* * $Id: s-string.h,v 1.4 1991/09/15 10:25:23 linus Exp $ * Copyright (C) 1991 Lysator Academic Computer Association. * * 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. */ /* * $Id: s-string.h,v 1.4 1991/09/15 10:25:23 linus Exp $ * * 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 #include #include #include #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 . * 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__ */