DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
/************************************************************************* * * $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
#include
#include
#include
#include
#include "triodef.h" #include "triostr.h" /************************************************************************* * Definitions */ #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_create TRIO_ARGS1((size), size_t size) { return (char *)TRIO_MALLOC(size); } /** Destroy string. @param string String to be freed. */ TRIO_STRING_PUBLIC void trio_destroy TRIO_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_t trio_length TRIO_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 int trio_append TRIO_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 int trio_append_max TRIO_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 int trio_contains TRIO_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 int trio_copy TRIO_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 int trio_copy_max TRIO_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 * TrioDuplicateMax TRIO_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_duplicate TRIO_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 int trio_equal TRIO_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 int trio_equal_case TRIO_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 int trio_equal_case_max TRIO_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 int trio_equal_locale TRIO_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 int trio_equal_max TRIO_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_error TRIO_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_t trio_format_date_max TRIO_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 long trio_hash TRIO_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_index TRIO_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_last TRIO_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 int trio_lower TRIO_ARGS1((target), char *target) { assert(target); return trio_span_function(target, target, trio_to_lower); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** 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. */ TRIO_STRING_PUBLIC int trio_match TRIO_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 ((trio_to_upper((int)*string) != trio_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 /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** 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. */ TRIO_STRING_PUBLIC int trio_match_case TRIO_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 /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** 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. */ TRIO_STRING_PUBLIC size_t trio_span_function TRIO_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 /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** 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. */ TRIO_STRING_PUBLIC char * trio_substring TRIO_ARGS2((string, substring), TRIO_CONST char *string, TRIO_CONST char *substring) { assert(string); assert(substring); return strstr(string, substring); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** 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. */ TRIO_STRING_PUBLIC char * trio_substring_max TRIO_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 /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** Tokenize string. @param string String to be tokenized. @param tokens String containing list of delimiting characters. @return Start of new token. @warning @p string will be destroyed. */ TRIO_STRING_PUBLIC char * trio_tokenize TRIO_ARGS2((string, delimiters), char *string, TRIO_CONST char *delimiters) { assert(delimiters); return strtok(string, delimiters); } #endif /* !defined(TRIO_MINIMAL) */ /** 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 ::= [
] (
|
|
) [
[
]
] number ::= 1*(
) digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) exponential ::= ( 'e' | 'E' ) sign ::= ( '-' | '+' ) decimal_point ::= '.' @endverbatim */ /* FIXME: Add EBNF for hex-floats */ TRIO_STRING_PUBLIC trio_long_double_t trio_to_long_double TRIO_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 + (trio_to_upper((int)*source) - 'A')); source++; } if (*source == '.') { source++; while (isxdigit((int)*source)) { fracdiv /= base; fraction += fracdiv * (isdigit((int)*source) ? (*source - '0') : 10 + (trio_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 /= pow(base, (double)exponent); else value *= pow(base, (double)exponent); } if (isNegative) value = -value; if (endp) *endp = (char *)source; return value; #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. */ TRIO_STRING_PUBLIC double trio_to_double TRIO_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 } #if !defined(TRIO_MINIMAL) /** 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. */ TRIO_STRING_PUBLIC float trio_to_float TRIO_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 /* !defined(TRIO_MINIMAL) */ /** 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. */ TRIO_STRING_PUBLIC long trio_to_long TRIO_ARGS3((string, endp, base), TRIO_CONST char *string, char **endp, int base) { assert(string); assert((base >= 2) && (base <= 36)); return strtol(string, endp, base); } #if !defined(TRIO_MINIMAL) /** Convert one alphabetic letter to lower-case. @param source The letter to be converted. @return The converted letter. */ TRIO_STRING_PUBLIC int trio_to_lower TRIO_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 /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** 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. */ TRIO_STRING_PUBLIC unsigned long trio_to_unsigned_long TRIO_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 /* !defined(TRIO_MINIMAL) */ /** Convert one alphabetic letter to upper-case. @param source The letter to be converted. @return The converted letter. */ TRIO_STRING_PUBLIC int trio_to_upper TRIO_ARGS1((source), int source) { #if defined(USE_TOUPPER) return toupper(source); #else /* Does not handle locales or non-contiguous alphabetic characters */ return ((source >= (int)'a') && (source <= (int)'z')) ? source - 'a' + 'A' : source; #endif } #if !defined(TRIO_MINIMAL) /** 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). */ TRIO_STRING_PUBLIC int trio_upper TRIO_ARGS1((target), char *target) { assert(target); return trio_span_function(target, target, trio_to_upper); } #endif /* !defined(TRIO_MINIMAL) */ /** @} End of StaticStrings */ /************************************************************************* * Dynamic String Functions */ #if defined(TRIO_DOCUMENTATION) # include "doc/doc_dynamic.h" #endif /** @addtogroup DynamicStrings @{ */ /* * TrioStringAlloc */ TRIO_STRING_PRIVATE trio_string_t * TrioStringAlloc(TRIO_NOARGS) { trio_string_t *self; self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); if (self) { self->content = NULL; self->length = 0; self->allocated = 0; } return self; } /* * TrioStringGrow * * The size of the string will be increased by 'delta' characters. If * 'delta' is zero, the size will be doubled. */ TRIO_STRING_PRIVATE BOOLEAN_T TrioStringGrow TRIO_ARGS2((self, delta), trio_string_t *self, size_t delta) { BOOLEAN_T status = FALSE; char *new_content; size_t new_size; new_size = (delta == 0) ? ( (self->allocated == 0) ? 1 : self->allocated * 2 ) : self->allocated + delta; new_content = (char *)TRIO_REALLOC(self->content, new_size); if (new_content) { self->content = new_content; self->allocated = new_size; status = TRUE; } return status; } #if !defined(TRIO_MINIMAL) /* * TrioStringGrowTo * * The size of the string will be increased to 'length' plus one characters. * If 'length' is less than the original size, the original size will be * used (that is, the size of the string is never decreased). */ TRIO_STRING_PRIVATE BOOLEAN_T TrioStringGrowTo TRIO_ARGS2((self, length), trio_string_t *self, size_t length) { length++; /* Room for terminating zero */ return (self->allocated < length) ? TrioStringGrow(self, length - self->allocated) : TRUE; } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /** Create a new dynamic string. @param initial_size Initial size of the buffer. @return Newly allocated dynamic string, or NULL if memory allocation failed. */ TRIO_STRING_PUBLIC trio_string_t * trio_string_create TRIO_ARGS1((initial_size), int initial_size) { trio_string_t *self; self = TrioStringAlloc(); if (self) { if (TrioStringGrow(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 /* !defined(TRIO_MINIMAL) */ /** Deallocate the dynamic string and its contents. @param self Dynamic string */ TRIO_STRING_PUBLIC void trio_string_destroy TRIO_ARGS1((self), trio_string_t *self) { assert(self); if (self) { trio_destroy(self->content); TRIO_FREE(self); } } #if !defined(TRIO_MINIMAL) /** Get a pointer to the content. @param self Dynamic string. @param offset Offset into content. @return Pointer to the content. @p Offset can be zero, positive, or negative. If @p offset is zero, then the start of the content will be returned. If @p offset is positive, then a pointer to @p offset number of characters from the beginning of the content is returned. If @p offset is negative, then a pointer to @p offset number of characters from the ending of the string, starting at the terminating zero, is returned. */ TRIO_STRING_PUBLIC char * trio_string_get TRIO_ARGS2((self, offset), trio_string_t *self, int offset) { char *result = NULL; assert(self); if (self->content != NULL) { if (self->length == 0) { (void)trio_string_length(self); } if (offset >= 0) { if (offset > (int)self->length) { offset = self->length; } } else { offset += self->length + 1; if (offset < 0) { offset = 0; } } result = &(self->content[offset]); } return result; } #endif /* !defined(TRIO_MINIMAL) */ /** Extract the content. @param self Dynamic String @return Content of dynamic string. The content is removed from the dynamic string. This enables destruction of the dynamic string without deallocation of the content. */ TRIO_STRING_PUBLIC char * trio_string_extract TRIO_ARGS1((self), trio_string_t *self) { char *result; assert(self); result = self->content; /* FIXME: Allocate new empty buffer? */ self->content = NULL; self->length = self->allocated = 0; return result; } #if !defined(TRIO_MINIMAL) /** Set the content of the dynamic string. @param self Dynamic String @param buffer The new content. Sets the content of the dynamic string to a copy @p buffer. An existing content will be deallocated first, if necessary. @remark This function will make a copy of @p buffer. You are responsible for deallocating @p buffer yourself. */ TRIO_STRING_PUBLIC void trio_xstring_set TRIO_ARGS2((self, buffer), trio_string_t *self, char *buffer) { assert(self); trio_destroy(self->content); self->content = trio_duplicate(buffer); } #endif /* !defined(TRIO_MINIMAL) */ /* * trio_string_size */ TRIO_STRING_PUBLIC int trio_string_size TRIO_ARGS1((self), trio_string_t *self) { assert(self); return self->allocated; } /* * trio_string_terminate */ TRIO_STRING_PUBLIC void trio_string_terminate TRIO_ARGS1((self), trio_string_t *self) { trio_xstring_append_char(self, 0); } #if !defined(TRIO_MINIMAL) /** Append the second string to the first. @param self Dynamic string to be modified. @param other Dynamic string to copy from. @return Boolean value indicating success or failure. */ TRIO_STRING_PUBLIC int trio_string_append TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { size_t length; assert(self); assert(other); length = self->length + other->length; if (!TrioStringGrowTo(self, length)) goto error; trio_copy(&self->content[self->length], other->content); self->length = length; return TRUE; error: return FALSE; } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_append */ TRIO_STRING_PUBLIC int trio_xstring_append TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { size_t length; assert(self); assert(other); length = self->length + trio_length(other); if (!TrioStringGrowTo(self, length)) goto error; trio_copy(&self->content[self->length], other); self->length = length; return TRUE; error: return FALSE; } #endif /* !defined(TRIO_MINIMAL) */ /* * trio_xstring_append_char */ TRIO_STRING_PUBLIC int trio_xstring_append_char TRIO_ARGS2((self, character), trio_string_t *self, char character) { assert(self); if ((int)self->length >= trio_string_size(self)) { if (!TrioStringGrow(self, 0)) goto error; } self->content[self->length] = character; self->length++; return TRUE; error: return FALSE; } #if !defined(TRIO_MINIMAL) /** Search for the first occurrence of second parameter in the first. @param self Dynamic string to be modified. @param other Dynamic string to copy from. @return Boolean value indicating success or failure. */ TRIO_STRING_PUBLIC int trio_string_contains TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { assert(self); assert(other); return trio_contains(self->content, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_contains */ TRIO_STRING_PUBLIC int trio_xstring_contains TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { assert(self); assert(other); return trio_contains(self->content, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_copy */ TRIO_STRING_PUBLIC int trio_string_copy TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { assert(self); assert(other); self->length = 0; return trio_string_append(self, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_copy */ TRIO_STRING_PUBLIC int trio_xstring_copy TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { assert(self); assert(other); self->length = 0; return trio_xstring_append(self, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_duplicate */ TRIO_STRING_PUBLIC trio_string_t * trio_string_duplicate TRIO_ARGS1((other), trio_string_t *other) { trio_string_t *self; assert(other); self = TrioStringAlloc(); if (self) { self->content = TrioDuplicateMax(other->content, other->length); if (self->content) { self->length = other->length; self->allocated = self->length + 1; } else { self->length = self->allocated = 0; } } return self; } #endif /* !defined(TRIO_MINIMAL) */ /* * trio_xstring_duplicate */ TRIO_STRING_PUBLIC trio_string_t * trio_xstring_duplicate TRIO_ARGS1((other), TRIO_CONST char *other) { trio_string_t *self; assert(other); self = TrioStringAlloc(); if (self) { self->content = TrioDuplicateMax(other, trio_length(other)); if (self->content) { self->length = trio_length(self->content); self->allocated = self->length + 1; } else { self->length = self->allocated = 0; } } return self; } #if !defined(TRIO_MINIMAL) /* * trio_string_equal */ TRIO_STRING_PUBLIC int trio_string_equal TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { assert(self); assert(other); return trio_equal(self->content, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_equal */ TRIO_STRING_PUBLIC int trio_xstring_equal TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { assert(self); assert(other); return trio_equal(self->content, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_equal_max */ TRIO_STRING_PUBLIC int trio_string_equal_max TRIO_ARGS3((self, max, other), trio_string_t *self, size_t max, trio_string_t *other) { assert(self); assert(other); return trio_equal_max(self->content, max, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_equal_max */ TRIO_STRING_PUBLIC int trio_xstring_equal_max TRIO_ARGS3((self, max, other), trio_string_t *self, size_t max, TRIO_CONST char *other) { assert(self); assert(other); return trio_equal_max(self->content, max, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_equal_case */ TRIO_STRING_PUBLIC int trio_string_equal_case TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { assert(self); assert(other); return trio_equal_case(self->content, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_equal_case */ TRIO_STRING_PUBLIC int trio_xstring_equal_case TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { assert(self); assert(other); return trio_equal_case(self->content, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_equal_case_max */ TRIO_STRING_PUBLIC int trio_string_equal_case_max TRIO_ARGS3((self, max, other), trio_string_t *self, size_t max, trio_string_t *other) { assert(self); assert(other); return trio_equal_case_max(self->content, max, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_equal_case_max */ TRIO_STRING_PUBLIC int trio_xstring_equal_case_max TRIO_ARGS3((self, max, other), trio_string_t *self, size_t max, TRIO_CONST char *other) { assert(self); assert(other); return trio_equal_case_max(self->content, max, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_format_data_max */ TRIO_STRING_PUBLIC size_t trio_string_format_date_max TRIO_ARGS4((self, max, format, datetime), trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime) { assert(self); return trio_format_date_max(self->content, max, format, datetime); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_index */ TRIO_STRING_PUBLIC char * trio_string_index TRIO_ARGS2((self, character), trio_string_t *self, int character) { assert(self); return trio_index(self->content, character); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_index_last */ TRIO_STRING_PUBLIC char * trio_string_index_last TRIO_ARGS2((self, character), trio_string_t *self, int character) { assert(self); return trio_index_last(self->content, character); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_length */ TRIO_STRING_PUBLIC int trio_string_length TRIO_ARGS1((self), trio_string_t *self) { assert(self); if (self->length == 0) { self->length = trio_length(self->content); } return self->length; } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_lower */ TRIO_STRING_PUBLIC int trio_string_lower TRIO_ARGS1((self), trio_string_t *self) { assert(self); return trio_lower(self->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_match */ TRIO_STRING_PUBLIC int trio_string_match TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { assert(self); assert(other); return trio_match(self->content, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_match */ TRIO_STRING_PUBLIC int trio_xstring_match TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { assert(self); assert(other); return trio_match(self->content, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_match_case */ TRIO_STRING_PUBLIC int trio_string_match_case TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { assert(self); assert(other); return trio_match_case(self->content, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_match_case */ TRIO_STRING_PUBLIC int trio_xstring_match_case TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { assert(self); assert(other); return trio_match_case(self->content, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_substring */ TRIO_STRING_PUBLIC char * trio_string_substring TRIO_ARGS2((self, other), trio_string_t *self, trio_string_t *other) { assert(self); assert(other); return trio_substring(self->content, other->content); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_xstring_substring */ TRIO_STRING_PUBLIC char * trio_xstring_substring TRIO_ARGS2((self, other), trio_string_t *self, TRIO_CONST char *other) { assert(self); assert(other); return trio_substring(self->content, other); } #endif /* !defined(TRIO_MINIMAL) */ #if !defined(TRIO_MINIMAL) /* * trio_string_upper */ TRIO_STRING_PUBLIC int trio_string_upper TRIO_ARGS1((self), trio_string_t *self) { assert(self); return trio_upper(self->content); } #endif /* !defined(TRIO_MINIMAL) */ /** @} End of DynamicStrings */
triostr.c
Page URL
File URL
Prev
92/114
Next
Download
( 41 KB )
Note: The DriveHQ service banners will NOT be displayed if the file owner is a paid member.
Comments
Total ratings:
0
Average rating:
Not Rated
Would you like to comment?
Join DriveHQ
for a free account, or
Logon
if you are already a member.