//
// aegis - project change supervisor
// Copyright (C) 1991-1995, 1998, 1999, 2001-2006, 2008 Peter Miller
//
// This program 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 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see
// .
//
#ifndef STR_H
#define STR_H
/** \addtogroup String
* \brief String manipulation funtions
* \ingroup Common
* @{
*/
#include
#include
#include
typedef unsigned long str_hash_ty;
/**
* \struct string_ty
* The string_ty struct is used to remember information about strings.
* Users should always refer to strings as \em pointers. The only
* members within the struct that should be accessed are the str_text
* member, which is a NUL terminated array of characters, and the
* str_length member, which contains the length of the string's text
* (not including the NUL terminator).
*
* It is guaranteed that all equal strings will not only have the same
* hash, but will, if fact, be exactly the same sting. The reference
* count is how many strings currently exist with this value. Thus,
* the commonest string test, a string equality test becomes a pointer
* equality test.
*
* Thou shalt not modify any member of a string struct, or the
* forces of evil shall wreak misery in thy life.
*/
struct string_ty
{
/**
* The hash of the string. Used internally by the string table,
* users shall never access this member.
*/
str_hash_ty str_hash;
/**
* The next string in a hash bucket. Used internally by the string
* table, users shall never access this member.
*/
string_ty *str_next;
/**
* The reference count for this string. It is guaranteed that
* all equal strings will not only have the same hash, but will,
* if fact, be exactly the same sting. The reference count is how
* many strings currently exist with this value. Used internally
* by the string table, users shall never access this member.
*/
long str_references;
/**
* The length of the string (not including the terminating NUL).
* Read-only access permitted to users.
*/
size_t str_length;
/**
* The text value of the string. It's actually longer than its
* declaration when the string length is more than zero.
* Read-only access permitted to users.
*/
char str_text[1];
};
void str_release(void);
/**
* \brief
* make string from C string
*
* The str_from_c function is used to make a string from a null
* terminated C string.
*
* \param str
* The C string to be copied. Will not be modified.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_from_c(const char *str);
/**
* \brief
* make string from C string
*
* The str_n_from_c function is used to make a string from an array of
* characters. No null terminator is assumed.
*
* \param str
* The C string to be copied. Will not be modified.
* \param len
* The maximum number of characters to be used (fewer will be used
* if there is an included NUL).
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_n_from_c(const char *str, size_t len);
/**
* \brief
* make a copy of a string
*
* The str_copy function is used to make a copy of a string.
*
* \param str
* The string to be copied. Will not be modified.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_copy(string_ty *str);
/**
* \brief
* release a string
*
* The str_free function is used to indicate that a string hash
* been finished with. This is the only way to release strings.
* Do not use the free() function.
*
* \param str
* The string to be freed.
*
* \return
* void
*/
void str_free(string_ty *str);
/**
* \brief
* join two strings together
*
* The str_catenate function is used to join two strings togther to
* form a new string. The are joined in the order given.
*
* \param str1
* A string to be joined. Will not be modified.
* \param str2
* A string to be joined. Will not be modified.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_catenate(string_ty *str1, string_ty *str2);
/**
* \brief
* joing strings together
*
* The str_cat_three function is used to join three strings together
* to form a new string. The are joined in the order given.
*
* \param str1
* A string to be joined. Will not be modified.
* \param str2
* A string to be joined. Will not be modified.
* \param str3
* A string to be joined. Will not be modified.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_cat_three(string_ty *str1, string_ty *str2, string_ty *str3);
/**
* \brief
* test a boolean
*
* The str_bool function is used to test the value of a string, as if
* it contained a number. If it doesn't contain a number, it is as if
* the strings was "1".
*
* \param str
* The string to be tested. Will not be modified.
*
* \return
* Zero if the numeric value in the strings was zero, or the empty
* string. One if the numeric value in the string was non-zero,
* or the string was non-numeric.
*/
int str_bool(string_ty *str);
/**
* \brief
* convert to upper case
*
* The str_upcase function is used to create a new string where the
* lower case characters in the input string are converted to upper
* case.
*
* \param str
* The string to be converted. Will not be modified (the operation
* is not performed in situ).
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_upcase(string_ty *str);
/**
* \brief
* convert to lower case
*
* The str_downcase function is used to create a new string where the
* upper case characters in the input string are converted to lower
* case.
*
* \param str
* The string to be converted. Will not be modified (the operation
* is not performed in situ).
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_downcase(string_ty *str);
/**
* \brief
* convert to title case
*
* The str_capitalize function is used to create a new string where the
* first letter or each word of the inopuyt string are upper case, and
* the remaining letters in each word are lower case. (Sometimes called
* Title Case.)
*
* \param str
* The string to be converted. Will not be modified (the operation
* is not performed in situ).
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_capitalize(string_ty *str);
/**
* \brief
* dump the string table
*
* The str_dum function is used to dump the contents of the string
* table to the standard error. Only useful for debugging.
*
* \return
* void
*/
void str_dump(void);
/**
* \brief
* extract a field
*
* The str_field function is used to extract the \a nth field, where
* each field is separated by the \a sep string.
*
* \param str
* The string from which the field is to be extracted. Will not
* be modified (the operation not performed in situ).
* \param sep
* The string which separates each field.
* \param nth
* The number of the field to be extracted. Zero based.
* If too high, the emtry string is returned.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_field(string_ty *str, int sep, int nth);
/**
* \brief
* convert tables of strings
*
* The slow_to_fast function is used to convert tables for normal
* C strings into tables of reference countest strings. Use amlost
* exclusively by the fmtgen-generated sources.
*
* \return
* void
*/
void slow_to_fast(const char *const *, string_ty **, size_t);
/**
* \brief
* format text
*
* The str_format function is used to create a new string by interpreting
* the \a fmt string. All formats understood by the ANSI C printf(3)
* are understodd by this function (but probably not your favorite
* proprietary extension). In addition the '%S' specifier expects a
* string_ty * argument.
*
* \param fmt
* The format string to be interpreted when constructing the
* return value.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_format(const char *fmt, ...) ATTR_PRINTF(1, 2);
/**
* \brief
* format text
*
* The str_vformat function is used to create a new string by interpreting
* the \a fmt string. All formats understood by the ANSI C printf(3)
* are understodd by this function (but probably not your favorite
* proprietary extension). In addition the '%S' specifier expects a
* string_ty * argument.
*
* \param fmt
* The format string to be interpreted when constructing the
* return value.
* \param ap
* Where to obtain additional arguments required by the \a fmt string.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_vformat(const char *fmt, va_list ap);
/**
* \brief
* test string equality
*
* The str_equal function is used to test to see if two strings are
* exactly the same.
*
* \param str1
* A string to be compared. Will not be modified.
* \param str2
* A string to be compared. Will not be modified.
*
* \note
* Users shall always write code as if they did not know that a
* string equality test is a pointer equality test.
*
* \return
* Non-zero if the strings are equal,
* zero if the strings are unequal.
*/
int str_equal(string_ty *str1, string_ty *str2);
/**
* \brief
* test string equality
* \see
* str_equal()
*
* The str_equal macro is used to accellerate string equality tests.
* Users shall always write code as if they did not know that a string
* equality test is a pointer equality test.
*/
#define str_equal(s1, s2) ((s1) == (s2))
/**
* \brief
* quote shell meta-characters
*
* The str_quote_shell function is used to create a new string which
* quotes the shell meta-characters in the input string.
*
* \param str
* The string to be converted. Will not be modified (the operation
* is not performed in situ).
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_quote_shell(string_ty *str);
/**
* \brief
* remove excess white space
*
* The str_trim function is used to remove white space from the beginning
* and end of the string, and replace all other runs of one or more
* white space characters with a single space.
*
* \param str
* The string to be converted. Will not be modified (the operation
* is not performed in situ).
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with. The contents of the structure pointed to shall
* not be altered.
*/
string_ty *str_trim(string_ty *str);
/**
* \brief
* remove leading and trailing white space
*
* The str_snip function is used to remove white space from the beginning
* and end of the string. Interior white space is unchanged.
*
* \param str
* The string to be converted.
*
* \return
* a pointer to a string in dynamic memory. Use str_free() when
* finished with.
*/
string_ty *str_snip(string_ty *str);
/**
* \brief
* check is valid
*
* The str_validate function is used to confirm that the given string
* pointer, \a str, points to a valid string.
* Usually used for debugging, often in assert()s.
*
* \param str
* The string to be validated. Willnot be modified.
*
* \return
* Non-zero if valid, zero if invalid.
*/
int str_validate(const string_ty *str);
/**
* \brief
* look for a leading prefix
*
* The str_leading_prefix function is used to test whether the \a needle
* argument is a leading prefix of the \a haystack argument.
*
* \param haystack
* The large string which allegedly contains the \a needle.
* \param needle
* The substring to be tested for.
*
* \return
* Non-zero if is a leading prefix, zero if not.
*/
int str_leading_prefix(string_ty *haystack, string_ty *needle);
/**
* \brief
* look for a trailing suffix
*
* The str_trailing_suffix function is used to test whether the \a needle
* argument is a trailing suffix of the \a haystack argument.
*
* \param haystack
* The large string which allegedly contains the \a needle.
* \param needle
* The substring to be tested for.
*
* \return
* Non-zero if is a trailing suffix, zero if not.
*/
int str_trailing_suffix(string_ty *haystack, string_ty *needle);
/**
* The str_identifier function is used to generate another string,
* replaceing all non-C-identifier characters with underscore. The
* intention is to generate a valid C identifier from the string.
*
* @param str
* The string to be converted.
*/
string_ty *str_identifier(string_ty *str);
/**
* The str_replace function may be used to alter a string by replacing
* one constant substring with another.
*
* @note
* The replacement is not done in situ. The original
* \a str is unaltered.
*
* @param str
* The string to be altered.
* @param lhs
* The substring to look for within \a str
* @param rhs
* The substring to replace \a lhs if found within \a str
* @param maximum
* The maximum number of times to perform the replacement.
* Defaults to "infinity".
* @returns
* A new string with the replacements made.
*/
string_ty *str_replace(string_ty *str, string_ty *lhs, string_ty *rhs,
int maximum = -1);
/** @} */
#endif // STR_H