📄 triostr.c.svn-base
字号:
/************************************************************************* * * $Id: triostr.c,v 1.3 2003/04/03 15:28:28 veillard Exp $ * * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************//************************************************************************* * Include files */#include <assert.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h>#include "triodef.h"#include "triostr.h"/************************************************************************* * Definitions */extern int strcmpi (const char *s1, const char *s2);#if !defined(TRIO_STRING_PUBLIC)# define TRIO_STRING_PUBLIC TRIO_PUBLIC#endif#if !defined(TRIO_STRING_PRIVATE)# define TRIO_STRING_PRIVATE TRIO_PRIVATE#endif#if !defined(NULL)# define NULL 0#endif#if !defined(NIL)# define NIL ((char)0)#endif#if !defined(FALSE)# define FALSE (1 == 0)# define TRUE (! FALSE)#endif#if !defined(BOOLEAN_T)# define BOOLEAN_T int#endif#if defined(TRIO_COMPILER_SUPPORTS_C99)# define USE_STRTOD# define USE_STRTOF#elif defined(TRIO_COMPILER_MSVC)# define USE_STRTOD#endif#if defined(TRIO_PLATFORM_UNIX)# define USE_STRCASECMP# define USE_STRNCASECMP# if defined(TRIO_PLATFORM_SUNOS)# define USE_SYS_ERRLIST# else# define USE_STRERROR# endif# if defined(TRIO_PLATFORM_QNX)# define strcasecmp(x,y) stricmp(x,y)# define strncasecmp(x,y,n) strnicmp(x,y,n)# endif#elif defined(TRIO_PLATFORM_WIN32)# define USE_STRCASECMP# define strcasecmp(x,y) strcmpi(x,y)#endif#if !(defined(TRIO_PLATFORM_SUNOS))# define USE_TOLOWER# define USE_TOUPPER#endif/************************************************************************* * Structures */struct _trio_string_t{ char *content; size_t length; size_t allocated;};/************************************************************************* * Constants */#if !defined(TRIO_MINIMAL)static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.3 2003/04/03 15:28:28 veillard Exp $";#endif/************************************************************************* * Static String Functions */#if defined(TRIO_DOCUMENTATION)# include "doc/doc_static.h"#endif/** @addtogroup StaticStrings @{*//** Create new string. @param size Size of new string. @return Pointer to string, or NULL if allocation failed.*/TRIO_STRING_PUBLIC char *trio_createTRIO_ARGS1((size), size_t size){ return (char *)TRIO_MALLOC(size);}/** Destroy string. @param string String to be freed.*/TRIO_STRING_PUBLIC voidtrio_destroyTRIO_ARGS1((string), char *string){ if (string) { TRIO_FREE(string); }}/** Count the number of characters in a string. @param string String to measure. @return Number of characters in @string.*/TRIO_STRING_PUBLIC size_ttrio_lengthTRIO_ARGS1((string), TRIO_CONST char *string){ return strlen(string);}#if !defined(TRIO_MINIMAL)/** Append @p source at the end of @p target. @param target Target string. @param source Source string. @return Boolean value indicating success or failure. @pre @p target must point to a memory chunk with sufficient room to contain the @p target string and @p source string. @pre No boundary checking is performed, so insufficient memory will result in a buffer overrun. @post @p target will be zero terminated.*/TRIO_STRING_PUBLIC inttrio_appendTRIO_ARGS2((target, source), char *target, TRIO_CONST char *source){ assert(target); assert(source); return (strcat(target, source) != NULL);}#endif /* !defined(TRIO_MINIMAL) */#if !defined(TRIO_MINIMAL)/** Append at most @p max characters from @p source to @p target. @param target Target string. @param max Maximum number of characters to append. @param source Source string. @return Boolean value indicating success or failure. @pre @p target must point to a memory chuck with sufficient room to contain the @p target string and the @p source string (at most @p max characters). @pre No boundary checking is performed, so insufficient memory will result in a buffer overrun. @post @p target will be zero terminated.*/TRIO_STRING_PUBLIC inttrio_append_maxTRIO_ARGS3((target, max, source), char *target, size_t max, TRIO_CONST char *source){ size_t length; assert(target); assert(source); length = trio_length(target); if (max > length) { strncat(target, source, max - length - 1); } return TRUE;}#endif /* !defined(TRIO_MINIMAL) */#if !defined(TRIO_MINIMAL)/** Determine if a string contains a substring. @param string String to be searched. @param substring String to be found. @return Boolean value indicating success or failure.*/TRIO_STRING_PUBLIC inttrio_containsTRIO_ARGS2((string, substring), TRIO_CONST char *string, TRIO_CONST char *substring){ assert(string); assert(substring); return (0 != strstr(string, substring));}#endif /* !defined(TRIO_MINIMAL) */#if !defined(TRIO_MINIMAL)/** Copy @p source to @p target. @param target Target string. @param source Source string. @return Boolean value indicating success or failure. @pre @p target must point to a memory chunk with sufficient room to contain the @p source string. @pre No boundary checking is performed, so insufficient memory will result in a buffer overrun. @post @p target will be zero terminated.*/TRIO_STRING_PUBLIC inttrio_copyTRIO_ARGS2((target, source), char *target, TRIO_CONST char *source){ assert(target); assert(source); (void)strcpy(target, source); return TRUE;}#endif /* !defined(TRIO_MINIMAL) *//** Copy at most @p max characters from @p source to @p target. @param target Target string. @param max Maximum number of characters to append. @param source Source string. @return Boolean value indicating success or failure. @pre @p target must point to a memory chunk with sufficient room to contain the @p source string (at most @p max characters). @pre No boundary checking is performed, so insufficient memory will result in a buffer overrun. @post @p target will be zero terminated.*/TRIO_STRING_PUBLIC inttrio_copy_maxTRIO_ARGS3((target, max, source), char *target, size_t max, TRIO_CONST char *source){ assert(target); assert(source); assert(max > 0); /* Includes != 0 */ (void)strncpy(target, source, max - 1); target[max - 1] = (char)0; return TRUE;}/* * TrioDuplicateMax */TRIO_STRING_PRIVATE char *TrioDuplicateMaxTRIO_ARGS2((source, size), TRIO_CONST char *source, size_t size){ char *target; assert(source); /* Make room for string plus a terminating zero */ size++; target = trio_create(size); if (target) { trio_copy_max(target, size, source); } return target;}/** Duplicate @p source. @param source Source string. @return A copy of the @p source string. @post @p target will be zero terminated.*/TRIO_STRING_PUBLIC char *trio_duplicateTRIO_ARGS1((source), TRIO_CONST char *source){ return TrioDuplicateMax(source, trio_length(source));}#if !defined(TRIO_MINIMAL)/** Duplicate at most @p max characters of @p source. @param source Source string. @param max Maximum number of characters to duplicate. @return A copy of the @p source string. @post @p target will be zero terminated.*/TRIO_STRING_PUBLIC char *trio_duplicate_max TRIO_ARGS2((source, max), TRIO_CONST char *source, size_t max){ size_t length; assert(source); assert(max > 0); length = trio_length(source); if (length > max) { length = max; } return TrioDuplicateMax(source, length);}#endif /* !defined(TRIO_MINIMAL) *//** Compare if two strings are equal. @param first First string. @param second Second string. @return Boolean indicating whether the two strings are equal or not. Case-insensitive comparison.*/TRIO_STRING_PUBLIC inttrio_equalTRIO_ARGS2((first, second), TRIO_CONST char *first, TRIO_CONST char *second){ assert(first); assert(second); if ((first != NULL) && (second != NULL)) {#if defined(USE_STRCASECMP) return (0 == strcasecmp(first, second));#else while ((*first != NIL) && (*second != NIL)) { if (trio_to_upper(*first) != trio_to_upper(*second)) { break; } first++; second++; } return ((*first == NIL) && (*second == NIL));#endif } return FALSE;}/** Compare if two strings are equal. @param first First string. @param second Second string. @return Boolean indicating whether the two strings are equal or not. Case-sensitive comparison.*/TRIO_STRING_PUBLIC inttrio_equal_caseTRIO_ARGS2((first, second), TRIO_CONST char *first, TRIO_CONST char *second){ assert(first); assert(second); if ((first != NULL) && (second != NULL)) { return (0 == strcmp(first, second)); } return FALSE;}#if !defined(TRIO_MINIMAL)/** Compare if two strings up until the first @p max characters are equal. @param first First string. @param max Maximum number of characters to compare. @param second Second string. @return Boolean indicating whether the two strings are equal or not. Case-sensitive comparison.*/TRIO_STRING_PUBLIC inttrio_equal_case_maxTRIO_ARGS3((first, max, second), TRIO_CONST char *first, size_t max, TRIO_CONST char *second){ assert(first); assert(second); if ((first != NULL) && (second != NULL)) { return (0 == strncmp(first, second, max)); } return FALSE;}#endif /* !defined(TRIO_MINIMAL) *//** Compare if two strings are equal. @param first First string. @param second Second string. @return Boolean indicating whether the two strings are equal or not. Collating characters are considered equal.*/TRIO_STRING_PUBLIC inttrio_equal_localeTRIO_ARGS2((first, second), TRIO_CONST char *first, TRIO_CONST char *second){ assert(first); assert(second);#if defined(LC_COLLATE) return (strcoll(first, second) == 0);#else return trio_equal(first, second);#endif}/** Compare if two strings up until the first @p max characters are equal. @param first First string. @param max Maximum number of characters to compare. @param second Second string. @return Boolean indicating whether the two strings are equal or not. Case-insensitive comparison.*/TRIO_STRING_PUBLIC inttrio_equal_maxTRIO_ARGS3((first, max, second), TRIO_CONST char *first, size_t max, TRIO_CONST char *second){ assert(first); assert(second); if ((first != NULL) && (second != NULL)) {#if defined(USE_STRNCASECMP) return (0 == strncasecmp(first, second, max));#else /* Not adequately tested yet */ size_t cnt = 0; while ((*first != NIL) && (*second != NIL) && (cnt <= max)) { if (trio_to_upper(*first) != trio_to_upper(*second)) { break; } first++; second++; cnt++; } return ((cnt == max) || ((*first == NIL) && (*second == NIL)));#endif } return FALSE;}/** Provide a textual description of an error code (errno). @param error_number Error number. @return Textual description of @p error_number.*/TRIO_STRING_PUBLIC TRIO_CONST char *trio_errorTRIO_ARGS1((error_number), int error_number){#if defined(USE_STRERROR) return strerror(error_number);#elif defined(USE_SYS_ERRLIST) extern char *sys_errlist[]; extern int sys_nerr; return ((error_number < 0) || (error_number >= sys_nerr)) ? "unknown" : sys_errlist[error_number]; #else return "unknown"; #endif}#if !defined(TRIO_MINIMAL)/** Format the date/time according to @p format. @param target Target string. @param max Maximum number of characters to format. @param format Formatting string. @param datetime Date/time structure. @return Number of formatted characters. The formatting string accepts the same specifiers as the standard C function strftime.*/TRIO_STRING_PUBLIC size_ttrio_format_date_maxTRIO_ARGS4((target, max, format, datetime), char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime){ assert(target); assert(format); assert(datetime); assert(max > 0); return strftime(target, max, format, datetime);}#endif /* !defined(TRIO_MINIMAL) */#if !defined(TRIO_MINIMAL)/** Calculate a hash value for a string. @param string String to be calculated on. @param type Hash function. @return Calculated hash value. @p type can be one of the following @li @c TRIO_HASH_PLAIN Plain hash function.*/TRIO_STRING_PUBLIC unsigned longtrio_hashTRIO_ARGS2((string, type), TRIO_CONST char *string, int type){ unsigned long value = 0L; char ch; assert(string); switch (type) { case TRIO_HASH_PLAIN: while ( (ch = *string++) != NIL ) { value *= 31; value += (unsigned long)ch; } break; default: assert(FALSE); break; } return value;}#endif /* !defined(TRIO_MINIMAL) */#if !defined(TRIO_MINIMAL)/** Find first occurrence of a character in a string. @param string String to be searched. @param character Character to be found. @param A pointer to the found character, or NULL if character was not found. */TRIO_STRING_PUBLIC char *trio_indexTRIO_ARGS2((string, character), TRIO_CONST char *string, int character){ assert(string); return strchr(string, character);}#endif /* !defined(TRIO_MINIMAL) */#if !defined(TRIO_MINIMAL)/** Find last occurrence of a character in a string. @param string String to be searched. @param character Character to be found. @param A pointer to the found character, or NULL if character was not found. */TRIO_STRING_PUBLIC char *trio_index_lastTRIO_ARGS2((string, character), TRIO_CONST char *string, int character){ assert(string); return strchr(string, character);}#endif /* !defined(TRIO_MINIMAL) */#if !defined(TRIO_MINIMAL)/** Convert the alphabetic letters in the string to lower-case. @param target String to be converted. @return Number of processed characters (converted or not).*/TRIO_STRING_PUBLIC inttrio_lowerTRIO_ARGS1((target), char *target){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -