📄 triostr.c
字号:
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# endif}#endif/** 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.*/#if defined(TRIO_FUNC_FORMAT_DATE_MAX)TRIO_PUBLIC_STRING 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/** 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.*/#if defined(TRIO_FUNC_HASH)TRIO_PUBLIC_STRING 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/** Find first occurrence of a character in a string. @param string String to be searched. @param character Character to be found. @return A pointer to the found character, or NULL if character was not found. */#if defined(TRIO_FUNC_INDEX)TRIO_PUBLIC_STRING char *trio_indexTRIO_ARGS2((string, character), TRIO_CONST char *string, int character){ assert(string); return strchr(string, character);}#endif/** Find last occurrence of a character in a string. @param string String to be searched. @param character Character to be found. @return A pointer to the found character, or NULL if character was not found. */#if defined(TRIO_FUNC_INDEX_LAST)TRIO_PUBLIC_STRING char *trio_index_lastTRIO_ARGS2((string, character), TRIO_CONST char *string, int character){ assert(string); return strchr(string, character);}#endif/** Convert the alphabetic letters in the string to lower-case. @param target String to be converted. @return Number of processed characters (converted or not).*/#if defined(TRIO_FUNC_LOWER)TRIO_PUBLIC_STRING inttrio_lowerTRIO_ARGS1((target), char *target){ assert(target); return trio_span_function(target, target, trio_to_lower);}#endif/** Compare two strings using wildcards. @param string String to be searched. @param pattern Pattern, including wildcards, to search for. @return Boolean value indicating success or failure. Case-insensitive comparison. The following wildcards can be used @li @c * Match any number of characters. @li @c ? Match a single character.*/#if defined(TRIO_FUNC_MATCH)TRIO_PUBLIC_STRING inttrio_matchTRIO_ARGS2((string, pattern), TRIO_CONST char *string, TRIO_CONST char *pattern){ assert(string); assert(pattern); for (; ('*' != *pattern); ++pattern, ++string) { if (NIL == *string) { return (NIL == *pattern); } if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern)) && ('?' != *pattern)) { return FALSE; } } /* two-line patch to prevent *too* much recursiveness: */ while ('*' == pattern[1]) pattern++; do { if ( trio_match(string, &pattern[1]) ) { return TRUE; } } while (*string++); return FALSE;}#endif/** Compare two strings using wildcards. @param string String to be searched. @param pattern Pattern, including wildcards, to search for. @return Boolean value indicating success or failure. Case-sensitive comparison. The following wildcards can be used @li @c * Match any number of characters. @li @c ? Match a single character.*/#if defined(TRIO_FUNC_MATCH_CASE)TRIO_PUBLIC_STRING inttrio_match_caseTRIO_ARGS2((string, pattern), TRIO_CONST char *string, TRIO_CONST char *pattern){ assert(string); assert(pattern); for (; ('*' != *pattern); ++pattern, ++string) { if (NIL == *string) { return (NIL == *pattern); } if ((*string != *pattern) && ('?' != *pattern)) { return FALSE; } } /* two-line patch to prevent *too* much recursiveness: */ while ('*' == pattern[1]) pattern++; do { if ( trio_match_case(string, &pattern[1]) ) { return TRUE; } } while (*string++); return FALSE;}#endif/** Execute a function on each character in string. @param target Target string. @param source Source string. @param Function Function to be executed. @return Number of processed characters.*/#if defined(TRIO_FUNC_SPAN_FUNCTION)TRIO_PUBLIC_STRING size_ttrio_span_functionTRIO_ARGS3((target, source, Function), char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int))){ size_t count = 0; assert(target); assert(source); assert(Function); while (*source != NIL) { *target++ = Function(*source++); count++; } return count;}#endif/** Search for a substring in a string. @param string String to be searched. @param substring String to be found. @return Pointer to first occurrence of @p substring in @p string, or NULL if no match was found.*/#if defined(TRIO_FUNC_SUBSTRING)TRIO_PUBLIC_STRING char *trio_substringTRIO_ARGS2((string, substring), TRIO_CONST char *string, TRIO_CONST char *substring){ assert(string); assert(substring); return strstr(string, substring);}#endif/** Search for a substring in the first @p max characters of a string. @param string String to be searched. @param max Maximum characters to be searched. @param substring String to be found. @return Pointer to first occurrence of @p substring in @p string, or NULL if no match was found.*/#if defined(TRIO_FUNC_SUBSTRING_MAX)TRIO_PUBLIC_STRING char *trio_substring_maxTRIO_ARGS3((string, max, substring), TRIO_CONST char *string, size_t max, TRIO_CONST char *substring){ size_t count; size_t size; char *result = NULL; assert(string); assert(substring); size = trio_length(substring); if (size <= max) { for (count = 0; count <= max - size; count++) { if (trio_equal_max(substring, size, &string[count])) { result = (char *)&string[count]; break; } } } return result;}#endif/** Tokenize string. @param string String to be tokenized. @param delimiters String containing list of delimiting characters. @return Start of new token. @warning @p string will be destroyed.*/#if defined(TRIO_FUNC_TOKENIZE)TRIO_PUBLIC_STRING char *trio_tokenizeTRIO_ARGS2((string, delimiters), char *string, TRIO_CONST char *delimiters){ assert(delimiters); return strtok(string, delimiters);}#endif/** Convert string to floating-point number. @param source String to be converted. @param endp Pointer to end of the converted string. @return A floating-point number. The following Extended Backus-Naur form is used @verbatim double ::= [ <sign> ] ( <number> | <number> <decimal_point> <number> | <decimal_point> <number> ) [ <exponential> [ <sign> ] <number> ] number ::= 1*( <digit> ) digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) exponential ::= ( 'e' | 'E' ) sign ::= ( '-' | '+' ) decimal_point ::= '.' @endverbatim*/#if defined(TRIO_FUNC_TO_LONG_DOUBLE)/* FIXME: Add EBNF for hex-floats */TRIO_PUBLIC_STRING trio_long_double_ttrio_to_long_doubleTRIO_ARGS2((source, endp), TRIO_CONST char *source, char **endp){# if defined(USE_STRTOLD) return strtold(source, endp);# else int isNegative = FALSE; int isExponentNegative = FALSE; trio_long_double_t integer = 0.0; trio_long_double_t fraction = 0.0; unsigned long exponent = 0; trio_long_double_t base; trio_long_double_t fracdiv = 1.0; trio_long_double_t value = 0.0; /* First try hex-floats */ if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) { base = 16.0; source += 2; while (isxdigit((int)*source)) { integer *= base; integer += (isdigit((int)*source) ? (*source - '0') : 10 + (internal_to_upper((int)*source) - 'A')); source++; } if (*source == '.') { source++; while (isxdigit((int)*source)) { fracdiv /= base; fraction += fracdiv * (isdigit((int)*source) ? (*source - '0') : 10 + (internal_to_upper((int)*source) - 'A')); source++; } if ((*source == 'p') || (*source == 'P')) { source++; if ((*source == '+') || (*source == '-')) { isExponentNegative = (*source == '-'); source++; } while (isdigit((int)*source)) { exponent *= 10; exponent += (*source - '0'); source++; } } } /* For later use with exponent */ base = 2.0; } else /* Then try normal decimal floats */ { base = 10.0; isNegative = (*source == '-'); /* Skip sign */ if ((*source == '+') || (*source == '-')) source++; /* Integer part */ while (isdigit((int)*source)) { integer *= base; integer += (*source - '0'); source++; } if (*source == '.') { source++; /* skip decimal point */ while (isdigit((int)*source)) { fracdiv /= base; fraction += (*source - '0') * fracdiv; source++; } } if ((*source == 'e') || (*source == 'E')# if TRIO_MICROSOFT || (*source == 'd') || (*source == 'D')# endif ) { source++; /* Skip exponential indicator */ isExponentNegative = (*source == '-'); if ((*source == '+') || (*source == '-')) source++; while (isdigit((int)*source)) { exponent *= (int)base; exponent += (*source - '0'); source++; } } } value = integer + fraction; if (exponent != 0) { if (isExponentNegative) value /= trio_powl(base, (trio_long_double_t)exponent); else value *= trio_powl(base, (trio_long_double_t)exponent); } if (isNegative) value = -value; if (endp) *endp = (char *)source; return value;# endif}#endif/** Convert string to floating-point number. @param source String to be converted. @param endp Pointer to end of the converted string. @return A floating-point number. See @ref trio_to_long_double.*/#if defined(TRIO_FUNC_TO_DOUBLE)TRIO_PUBLIC_STRING doubletrio_to_doubleTRIO_ARGS2((source, endp), TRIO_CONST char *source, char **endp){#if defined(USE_STRTOD) return strtod(source, endp);#else return (double)trio_to_long_double(source, endp);#endif}#endif/** Convert string to floating-point number. @param source String to be converted. @param endp Pointer to end of the converted string. @return A floating-point number. See @ref trio_to_long_double.*/#if defined(TRIO_FUNC_TO_FLOAT)TRIO_PUBLIC_STRING floattrio_to_floatTRIO_ARGS2((source, endp), TRIO_CONST char *source, char **endp){# if defined(USE_STRTOF) return strtof(source, endp);# else return (float)trio_to_long_double(source, endp);# endif}#endif/** Convert string to signed integer. @param string String to be converted. @param endp Pointer to end of converted string. @param base Radix number of number.*/#if defined(TRIO_FUNC_TO_LONG)TRIO_PUBLIC_STRING longtrio_to_longTRIO_ARGS3((string, endp, base), TRIO_CONST char *string, char **endp, int base){ assert(string); assert((base >= 2) && (base <= 36)); return strtol(string, endp, base);}#endif/** Convert one alphabetic letter to lower-case. @param source The letter to be converted. @return The converted letter.*/#if defined(TRIO_FUNC_TO_LOWER)TRIO_PUBLIC_STRING inttrio_to_lowerTRIO_ARGS1((source), int source){# if defined(USE_TOLOWER) return tolower(source); # else /* Does not handle locales or non-contiguous alphabetic characters */ return ((source >= (int)'A') && (source <= (int)'Z')) ? source - 'A' + 'a' : source; # endif}#endif/** Convert string to unsigned integer. @param string String to be converted. @param endp Pointer to end of converted string. @param base Radix number of number.*/#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)TRIO_PUBLIC_STRING unsigned longtrio_to_unsigned_longTRIO_ARGS3((string, endp, base), TRIO_CONST char *string, char **endp, int base){ assert(string); assert((base >= 2) && (base <= 36)); return strtoul(string, endp, base);}#endif/** Convert one alphabetic letter to upper-case. @param source The letter to be converted. @return The converted letter.*/#if defined(TRIO_FUNC_TO_UPPER)TRIO_PUBLIC_STRING inttrio_to_upperTRIO_ARGS1((source), int source){ return internal_to_upper(source);}#endif/** Convert the alphabetic letters in the string to upper-case. @param target The string to be converted. @return The number of processed characters (converted or not).*/#if defined(TRIO_FUNC_UPPER)TRIO_PUBLIC_STRING inttrio_upperTRIO_ARGS1((target), char *target){ assert(target); return trio_span_function(target, target, internal_to_upper);}#endif/** @} End of StaticStrings *//************************************************************************* * Dynamic String Functions */#if defined(TRIO_DOCUMENTATION)# include "doc/doc_dynamic.h"#endif/** @addtogroup DynamicStrings @{*//** Create a new dynamic string. @param initial_size Initial size of the buffer. @return Newly allocated dynamic string, or NULL if memory allocation failed.*/#if defined(TRIO_FUNC_STRING_CREATE)TRIO_PUBLIC_STRING trio_string_t *trio_string_createTRIO_ARGS1((initial_size), int initial_size){ trio_string_t *self; self = internal_string_alloc(); if (self) { if (internal_string_grow(self, (size_t)((initial_size > 0) ? initial_size : 1))) { self->content[0] = (char)0; self->allocated = initial_size; } else { trio_string_destroy(self); self = NULL; } } return self;}#endif/** Deallocate the dynamic string and its contents. @param self Dynamic string*/#if defined(TRIO_FUNC_STRING_DESTROY)TRIO_PUBLIC_STRING voidtrio_string_destroyTRIO_ARGS1((self), trio_string_t *self){ assert(self); if (self) { trio_destroy(self->content); TRIO_FREE(self); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -