Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentriostr.c
Go to the documentation of this file.
00001 /************************************************************************* 00002 * 00003 * $Id$ 00004 * 00005 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. 00006 * 00007 * Permission to use, copy, modify, and distribute this software for any 00008 * purpose with or without fee is hereby granted, provided that the above 00009 * copyright notice and this permission notice appear in all copies. 00010 * 00011 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 00012 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 00013 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND 00014 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. 00015 * 00016 ************************************************************************/ 00017 00018 /************************************************************************* 00019 * Include files 00020 */ 00021 00022 #include <assert.h> 00023 #include <stdlib.h> 00024 #include <string.h> 00025 #include <ctype.h> 00026 #include <math.h> 00027 #include "triodef.h" 00028 #include "triostr.h" 00029 00030 /************************************************************************* 00031 * Definitions 00032 */ 00033 00034 #if !defined(TRIO_STRING_PUBLIC) 00035 # define TRIO_STRING_PUBLIC TRIO_PUBLIC 00036 #endif 00037 #if !defined(TRIO_STRING_PRIVATE) 00038 # define TRIO_STRING_PRIVATE TRIO_PRIVATE 00039 #endif 00040 00041 #if !defined(NULL) 00042 # define NULL 0 00043 #endif 00044 #if !defined(NIL) 00045 # define NIL ((char)0) 00046 #endif 00047 #if !defined(FALSE) 00048 # define FALSE (1 == 0) 00049 # define TRUE (! FALSE) 00050 #endif 00051 #if !defined(BOOLEAN_T) 00052 # define BOOLEAN_T int 00053 #endif 00054 00055 #if defined(TRIO_COMPILER_SUPPORTS_C99) 00056 # define USE_STRTOD 00057 # define USE_STRTOF 00058 #elif defined(TRIO_COMPILER_MSVC) 00059 # define USE_STRTOD 00060 #endif 00061 00062 #if defined(TRIO_PLATFORM_UNIX) 00063 # define USE_STRCASECMP 00064 # define USE_STRNCASECMP 00065 # if defined(TRIO_PLATFORM_SUNOS) 00066 # define USE_SYS_ERRLIST 00067 # else 00068 # define USE_STRERROR 00069 # endif 00070 # if defined(TRIO_PLATFORM_QNX) 00071 # define strcasecmp(x,y) stricmp(x,y) 00072 # define strncasecmp(x,y,n) strnicmp(x,y,n) 00073 # endif 00074 #elif defined(TRIO_PLATFORM_WIN32) 00075 # define USE_STRCASECMP 00076 # if defined(_WIN32_WCE) 00077 # define strcasecmp(x,y) _stricmp(x,y) 00078 # else 00079 # define strcasecmp(x,y) strcmpi(x,y) 00080 # endif 00081 #endif 00082 00083 #if !(defined(TRIO_PLATFORM_SUNOS)) 00084 # define USE_TOLOWER 00085 # define USE_TOUPPER 00086 #endif 00087 00088 /************************************************************************* 00089 * Structures 00090 */ 00091 00092 struct _trio_string_t 00093 { 00094 char *content; 00095 size_t length; 00096 size_t allocated; 00097 }; 00098 00099 /************************************************************************* 00100 * Constants 00101 */ 00102 00103 #if !defined(TRIO_MINIMAL) 00104 static TRIO_CONST char rcsid[] = "@(#)$Id$"; 00105 #endif 00106 00107 /************************************************************************* 00108 * Static String Functions 00109 */ 00110 00111 #if defined(TRIO_DOCUMENTATION) 00112 # include "doc/doc_static.h" 00113 #endif 00114 00124 TRIO_STRING_PUBLIC char * 00125 trio_create 00126 TRIO_ARGS1((size), 00127 size_t size) 00128 { 00129 return (char *)TRIO_MALLOC(size); 00130 } 00131 00132 00138 TRIO_STRING_PUBLIC void 00139 trio_destroy 00140 TRIO_ARGS1((string), 00141 char *string) 00142 { 00143 if (string) 00144 { 00145 TRIO_FREE(string); 00146 } 00147 } 00148 00149 00156 TRIO_STRING_PUBLIC size_t 00157 trio_length 00158 TRIO_ARGS1((string), 00159 TRIO_CONST char *string) 00160 { 00161 return strlen(string); 00162 } 00163 00164 00165 #if !defined(TRIO_MINIMAL) 00166 00179 TRIO_STRING_PUBLIC int 00180 trio_append 00181 TRIO_ARGS2((target, source), 00182 char *target, 00183 TRIO_CONST char *source) 00184 { 00185 assert(target); 00186 assert(source); 00187 00188 return (strcat(target, source) != NULL); 00189 } 00190 #endif /* !defined(TRIO_MINIMAL) */ 00191 00192 #if !defined(TRIO_MINIMAL) 00193 00208 TRIO_STRING_PUBLIC int 00209 trio_append_max 00210 TRIO_ARGS3((target, max, source), 00211 char *target, 00212 size_t max, 00213 TRIO_CONST char *source) 00214 { 00215 size_t length; 00216 00217 assert(target); 00218 assert(source); 00219 00220 length = trio_length(target); 00221 00222 if (max > length) 00223 { 00224 strncat(target, source, max - length - 1); 00225 } 00226 return TRUE; 00227 } 00228 #endif /* !defined(TRIO_MINIMAL) */ 00229 00230 00231 #if !defined(TRIO_MINIMAL) 00232 00239 TRIO_STRING_PUBLIC int 00240 trio_contains 00241 TRIO_ARGS2((string, substring), 00242 TRIO_CONST char *string, 00243 TRIO_CONST char *substring) 00244 { 00245 assert(string); 00246 assert(substring); 00247 00248 return (0 != strstr(string, substring)); 00249 } 00250 #endif /* !defined(TRIO_MINIMAL) */ 00251 00252 00253 #if !defined(TRIO_MINIMAL) 00254 00267 TRIO_STRING_PUBLIC int 00268 trio_copy 00269 TRIO_ARGS2((target, source), 00270 char *target, 00271 TRIO_CONST char *source) 00272 { 00273 assert(target); 00274 assert(source); 00275 00276 (void)strcpy(target, source); 00277 return TRUE; 00278 } 00279 #endif /* !defined(TRIO_MINIMAL) */ 00280 00281 00296 TRIO_STRING_PUBLIC int 00297 trio_copy_max 00298 TRIO_ARGS3((target, max, source), 00299 char *target, 00300 size_t max, 00301 TRIO_CONST char *source) 00302 { 00303 assert(target); 00304 assert(source); 00305 assert(max > 0); /* Includes != 0 */ 00306 00307 (void)strncpy(target, source, max - 1); 00308 target[max - 1] = (char)0; 00309 return TRUE; 00310 } 00311 00312 00313 /* 00314 * TrioDuplicateMax 00315 */ 00316 TRIO_STRING_PRIVATE char * 00317 TrioDuplicateMax 00318 TRIO_ARGS2((source, size), 00319 TRIO_CONST char *source, 00320 size_t size) 00321 { 00322 char *target; 00323 00324 assert(source); 00325 00326 /* Make room for string plus a terminating zero */ 00327 size++; 00328 target = trio_create(size); 00329 if (target) 00330 { 00331 trio_copy_max(target, size, source); 00332 } 00333 return target; 00334 } 00335 00336 00345 TRIO_STRING_PUBLIC char * 00346 trio_duplicate 00347 TRIO_ARGS1((source), 00348 TRIO_CONST char *source) 00349 { 00350 return TrioDuplicateMax(source, trio_length(source)); 00351 } 00352 00353 00354 #if !defined(TRIO_MINIMAL) 00355 00364 TRIO_STRING_PUBLIC char * 00365 trio_duplicate_max TRIO_ARGS2((source, max), 00366 TRIO_CONST char *source, 00367 size_t max) 00368 { 00369 size_t length; 00370 00371 assert(source); 00372 assert(max > 0); 00373 00374 length = trio_length(source); 00375 if (length > max) 00376 { 00377 length = max; 00378 } 00379 return TrioDuplicateMax(source, length); 00380 } 00381 #endif /* !defined(TRIO_MINIMAL) */ 00382 00383 00393 TRIO_STRING_PUBLIC int 00394 trio_equal 00395 TRIO_ARGS2((first, second), 00396 TRIO_CONST char *first, 00397 TRIO_CONST char *second) 00398 { 00399 assert(first); 00400 assert(second); 00401 00402 if ((first != NULL) && (second != NULL)) 00403 { 00404 #if defined(USE_STRCASECMP) 00405 return (0 == strcasecmp(first, second)); 00406 #else 00407 while ((*first != NIL) && (*second != NIL)) 00408 { 00409 if (trio_to_upper(*first) != trio_to_upper(*second)) 00410 { 00411 break; 00412 } 00413 first++; 00414 second++; 00415 } 00416 return ((*first == NIL) && (*second == NIL)); 00417 #endif 00418 } 00419 return FALSE; 00420 } 00421 00422 00432 TRIO_STRING_PUBLIC int 00433 trio_equal_case 00434 TRIO_ARGS2((first, second), 00435 TRIO_CONST char *first, 00436 TRIO_CONST char *second) 00437 { 00438 assert(first); 00439 assert(second); 00440 00441 if ((first != NULL) && (second != NULL)) 00442 { 00443 return (0 == strcmp(first, second)); 00444 } 00445 return FALSE; 00446 } 00447 00448 00449 #if !defined(TRIO_MINIMAL) 00450 00460 TRIO_STRING_PUBLIC int 00461 trio_equal_case_max 00462 TRIO_ARGS3((first, max, second), 00463 TRIO_CONST char *first, 00464 size_t max, 00465 TRIO_CONST char *second) 00466 { 00467 assert(first); 00468 assert(second); 00469 00470 if ((first != NULL) && (second != NULL)) 00471 { 00472 return (0 == strncmp(first, second, max)); 00473 } 00474 return FALSE; 00475 } 00476 #endif /* !defined(TRIO_MINIMAL) */ 00477 00478 00488 TRIO_STRING_PUBLIC int 00489 trio_equal_locale 00490 TRIO_ARGS2((first, second), 00491 TRIO_CONST char *first, 00492 TRIO_CONST char *second) 00493 { 00494 assert(first); 00495 assert(second); 00496 00497 #if defined(LC_COLLATE) 00498 return (strcoll(first, second) == 0); 00499 #else 00500 return trio_equal(first, second); 00501 #endif 00502 } 00503 00504 00515 TRIO_STRING_PUBLIC int 00516 trio_equal_max 00517 TRIO_ARGS3((first, max, second), 00518 TRIO_CONST char *first, 00519 size_t max, 00520 TRIO_CONST char *second) 00521 { 00522 assert(first); 00523 assert(second); 00524 00525 if ((first != NULL) && (second != NULL)) 00526 { 00527 #if defined(USE_STRNCASECMP) 00528 return (0 == strncasecmp(first, second, max)); 00529 #else 00530 /* Not adequately tested yet */ 00531 size_t cnt = 0; 00532 while ((*first != NIL) && (*second != NIL) && (cnt <= max)) 00533 { 00534 if (trio_to_upper(*first) != trio_to_upper(*second)) 00535 { 00536 break; 00537 } 00538 first++; 00539 second++; 00540 cnt++; 00541 } 00542 return ((cnt == max) || ((*first == NIL) && (*second == NIL))); 00543 #endif 00544 } 00545 return FALSE; 00546 } 00547 00548 00555 TRIO_STRING_PUBLIC TRIO_CONST char * 00556 trio_error 00557 TRIO_ARGS1((error_number), 00558 int error_number) 00559 { 00560 #if defined(USE_STRERROR) 00561 00562 return strerror(error_number); 00563 00564 #elif defined(USE_SYS_ERRLIST) 00565 00566 extern char *sys_errlist[]; 00567 extern int sys_nerr; 00568 00569 return ((error_number < 0) || (error_number >= sys_nerr)) 00570 ? "unknown" 00571 : sys_errlist[error_number]; 00572 00573 #else 00574 00575 return "unknown"; 00576 00577 #endif 00578 } 00579 00580 00581 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE) 00582 00594 TRIO_STRING_PUBLIC size_t 00595 trio_format_date_max 00596 TRIO_ARGS4((target, max, format, datetime), 00597 char *target, 00598 size_t max, 00599 TRIO_CONST char *format, 00600 TRIO_CONST struct tm *datetime) 00601 { 00602 assert(target); 00603 assert(format); 00604 assert(datetime); 00605 assert(max > 0); 00606 00607 return strftime(target, max, format, datetime); 00608 } 00609 #endif /* !defined(TRIO_MINIMAL) */ 00610 00611 00612 #if !defined(TRIO_MINIMAL) 00613 00623 TRIO_STRING_PUBLIC unsigned long 00624 trio_hash 00625 TRIO_ARGS2((string, type), 00626 TRIO_CONST char *string, 00627 int type) 00628 { 00629 unsigned long value = 0L; 00630 char ch; 00631 00632 assert(string); 00633 00634 switch (type) 00635 { 00636 case TRIO_HASH_PLAIN: 00637 while ( (ch = *string++) != NIL ) 00638 { 00639 value *= 31; 00640 value += (unsigned long)ch; 00641 } 00642 break; 00643 default: 00644 assert(FALSE); 00645 break; 00646 } 00647 return value; 00648 } 00649 #endif /* !defined(TRIO_MINIMAL) */ 00650 00651 00652 #if !defined(TRIO_MINIMAL) 00653 00660 TRIO_STRING_PUBLIC char * 00661 trio_index 00662 TRIO_ARGS2((string, character), 00663 TRIO_CONST char *string, 00664 int character) 00665 { 00666 assert(string); 00667 00668 return strchr(string, character); 00669 } 00670 #endif /* !defined(TRIO_MINIMAL) */ 00671 00672 00673 #if !defined(TRIO_MINIMAL) 00674 00681 TRIO_STRING_PUBLIC char * 00682 trio_index_last 00683 TRIO_ARGS2((string, character), 00684 TRIO_CONST char *string, 00685 int character) 00686 { 00687 assert(string); 00688 00689 return strchr(string, character); 00690 } 00691 #endif /* !defined(TRIO_MINIMAL) */ 00692 00693 00694 #if !defined(TRIO_MINIMAL) 00695 00701 TRIO_STRING_PUBLIC int 00702 trio_lower 00703 TRIO_ARGS1((target), 00704 char *target) 00705 { 00706 assert(target); 00707 00708 return trio_span_function(target, target, trio_to_lower); 00709 } 00710 #endif /* !defined(TRIO_MINIMAL) */ 00711 00712 00713 #if !defined(TRIO_MINIMAL) 00714 00727 TRIO_STRING_PUBLIC int 00728 trio_match 00729 TRIO_ARGS2((string, pattern), 00730 TRIO_CONST char *string, 00731 TRIO_CONST char *pattern) 00732 { 00733 assert(string); 00734 assert(pattern); 00735 00736 for (; ('*' != *pattern); ++pattern, ++string) 00737 { 00738 if (NIL == *string) 00739 { 00740 return (NIL == *pattern); 00741 } 00742 if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern)) 00743 && ('?' != *pattern)) 00744 { 00745 return FALSE; 00746 } 00747 } 00748 /* two-line patch to prevent *too* much recursiveness: */ 00749 while ('*' == pattern[1]) 00750 pattern++; 00751 00752 do 00753 { 00754 if ( trio_match(string, &pattern[1]) ) 00755 { 00756 return TRUE; 00757 } 00758 } 00759 while (*string++); 00760 00761 return FALSE; 00762 } 00763 #endif /* !defined(TRIO_MINIMAL) */ 00764 00765 00766 #if !defined(TRIO_MINIMAL) 00767 00780 TRIO_STRING_PUBLIC int 00781 trio_match_case 00782 TRIO_ARGS2((string, pattern), 00783 TRIO_CONST char *string, 00784 TRIO_CONST char *pattern) 00785 { 00786 assert(string); 00787 assert(pattern); 00788 00789 for (; ('*' != *pattern); ++pattern, ++string) 00790 { 00791 if (NIL == *string) 00792 { 00793 return (NIL == *pattern); 00794 } 00795 if ((*string != *pattern) 00796 && ('?' != *pattern)) 00797 { 00798 return FALSE; 00799 } 00800 } 00801 /* two-line patch to prevent *too* much recursiveness: */ 00802 while ('*' == pattern[1]) 00803 pattern++; 00804 00805 do 00806 { 00807 if ( trio_match_case(string, &pattern[1]) ) 00808 { 00809 return TRUE; 00810 } 00811 } 00812 while (*string++); 00813 00814 return FALSE; 00815 } 00816 #endif /* !defined(TRIO_MINIMAL) */ 00817 00818 00819 #if !defined(TRIO_MINIMAL) 00820 00828 TRIO_STRING_PUBLIC size_t 00829 trio_span_function 00830 TRIO_ARGS3((target, source, Function), 00831 char *target, 00832 TRIO_CONST char *source, 00833 int (*Function) TRIO_PROTO((int))) 00834 { 00835 size_t count = 0; 00836 00837 assert(target); 00838 assert(source); 00839 assert(Function); 00840 00841 while (*source != NIL) 00842 { 00843 *target++ = Function(*source++); 00844 count++; 00845 } 00846 return count; 00847 } 00848 #endif /* !defined(TRIO_MINIMAL) */ 00849 00850 00851 #if !defined(TRIO_MINIMAL) 00852 00860 TRIO_STRING_PUBLIC char * 00861 trio_substring 00862 TRIO_ARGS2((string, substring), 00863 TRIO_CONST char *string, 00864 TRIO_CONST char *substring) 00865 { 00866 assert(string); 00867 assert(substring); 00868 00869 return strstr(string, substring); 00870 } 00871 #endif /* !defined(TRIO_MINIMAL) */ 00872 00873 00874 #if !defined(TRIO_MINIMAL) 00875 00884 TRIO_STRING_PUBLIC char * 00885 trio_substring_max 00886 TRIO_ARGS3((string, max, substring), 00887 TRIO_CONST char *string, 00888 size_t max, 00889 TRIO_CONST char *substring) 00890 { 00891 size_t count; 00892 size_t size; 00893 char *result = NULL; 00894 00895 assert(string); 00896 assert(substring); 00897 00898 size = trio_length(substring); 00899 if (size <= max) 00900 { 00901 for (count = 0; count <= max - size; count++) 00902 { 00903 if (trio_equal_max(substring, size, &string[count])) 00904 { 00905 result = (char *)&string[count]; 00906 break; 00907 } 00908 } 00909 } 00910 return result; 00911 } 00912 #endif /* !defined(TRIO_MINIMAL) */ 00913 00914 00915 #if !defined(TRIO_MINIMAL) 00916 00925 TRIO_STRING_PUBLIC char * 00926 trio_tokenize 00927 TRIO_ARGS2((string, delimiters), 00928 char *string, 00929 TRIO_CONST char *delimiters) 00930 { 00931 assert(delimiters); 00932 00933 return strtok(string, delimiters); 00934 } 00935 #endif /* !defined(TRIO_MINIMAL) */ 00936 00937 00959 /* FIXME: Add EBNF for hex-floats */ 00960 TRIO_STRING_PUBLIC trio_long_double_t 00961 trio_to_long_double 00962 TRIO_ARGS2((source, endp), 00963 TRIO_CONST char *source, 00964 char **endp) 00965 { 00966 #if defined(USE_STRTOLD) 00967 return strtold(source, endp); 00968 #else 00969 int isNegative = FALSE; 00970 int isExponentNegative = FALSE; 00971 trio_long_double_t integer = 0.0; 00972 trio_long_double_t fraction = 0.0; 00973 unsigned long exponent = 0; 00974 trio_long_double_t base; 00975 trio_long_double_t fracdiv = 1.0; 00976 trio_long_double_t value = 0.0; 00977 00978 /* First try hex-floats */ 00979 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) 00980 { 00981 base = 16.0; 00982 source += 2; 00983 while (isxdigit((int)*source)) 00984 { 00985 integer *= base; 00986 integer += (isdigit((int)*source) 00987 ? (*source - '0') 00988 : 10 + (trio_to_upper((int)*source) - 'A')); 00989 source++; 00990 } 00991 if (*source == '.') 00992 { 00993 source++; 00994 while (isxdigit((int)*source)) 00995 { 00996 fracdiv /= base; 00997 fraction += fracdiv * (isdigit((int)*source) 00998 ? (*source - '0') 00999 : 10 + (trio_to_upper((int)*source) - 'A')); 01000 source++; 01001 } 01002 if ((*source == 'p') || (*source == 'P')) 01003 { 01004 source++; 01005 if ((*source == '+') || (*source == '-')) 01006 { 01007 isExponentNegative = (*source == '-'); 01008 source++; 01009 } 01010 while (isdigit((int)*source)) 01011 { 01012 exponent *= 10; 01013 exponent += (*source - '0'); 01014 source++; 01015 } 01016 } 01017 } 01018 /* For later use with exponent */ 01019 base = 2.0; 01020 } 01021 else /* Then try normal decimal floats */ 01022 { 01023 base = 10.0; 01024 isNegative = (*source == '-'); 01025 /* Skip sign */ 01026 if ((*source == '+') || (*source == '-')) 01027 source++; 01028 01029 /* Integer part */ 01030 while (isdigit((int)*source)) 01031 { 01032 integer *= base; 01033 integer += (*source - '0'); 01034 source++; 01035 } 01036 01037 if (*source == '.') 01038 { 01039 source++; /* skip decimal point */ 01040 while (isdigit((int)*source)) 01041 { 01042 fracdiv /= base; 01043 fraction += (*source - '0') * fracdiv; 01044 source++; 01045 } 01046 } 01047 if ((*source == 'e') 01048 || (*source == 'E') 01049 #if TRIO_MICROSOFT 01050 || (*source == 'd') 01051 || (*source == 'D') 01052 #endif 01053 ) 01054 { 01055 source++; /* Skip exponential indicator */ 01056 isExponentNegative = (*source == '-'); 01057 if ((*source == '+') || (*source == '-')) 01058 source++; 01059 while (isdigit((int)*source)) 01060 { 01061 exponent *= (int)base; 01062 exponent += (*source - '0'); 01063 source++; 01064 } 01065 } 01066 } 01067 01068 value = integer + fraction; 01069 if (exponent != 0) 01070 { 01071 if (isExponentNegative) 01072 value /= pow(base, (double)exponent); 01073 else 01074 value *= pow(base, (double)exponent); 01075 } 01076 if (isNegative) 01077 value = -value; 01078 01079 if (endp) 01080 *endp = (char *)source; 01081 return value; 01082 #endif 01083 } 01084 01085 01095 TRIO_STRING_PUBLIC double 01096 trio_to_double 01097 TRIO_ARGS2((source, endp), 01098 TRIO_CONST char *source, 01099 char **endp) 01100 { 01101 #if defined(USE_STRTOD) 01102 return strtod(source, endp); 01103 #else 01104 return (double)trio_to_long_double(source, endp); 01105 #endif 01106 } 01107 01108 #if !defined(TRIO_MINIMAL) 01109 01118 TRIO_STRING_PUBLIC float 01119 trio_to_float 01120 TRIO_ARGS2((source, endp), 01121 TRIO_CONST char *source, 01122 char **endp) 01123 { 01124 #if defined(USE_STRTOF) 01125 return strtof(source, endp); 01126 #else 01127 return (float)trio_to_long_double(source, endp); 01128 #endif 01129 } 01130 #endif /* !defined(TRIO_MINIMAL) */ 01131 01132 01140 TRIO_STRING_PUBLIC long 01141 trio_to_long 01142 TRIO_ARGS3((string, endp, base), 01143 TRIO_CONST char *string, 01144 char **endp, 01145 int base) 01146 { 01147 assert(string); 01148 assert((base >= 2) && (base <= 36)); 01149 01150 return strtol(string, endp, base); 01151 } 01152 01153 01154 #if !defined(TRIO_MINIMAL) 01155 01161 TRIO_STRING_PUBLIC int 01162 trio_to_lower 01163 TRIO_ARGS1((source), 01164 int source) 01165 { 01166 #if defined(USE_TOLOWER) 01167 01168 return tolower(source); 01169 01170 #else 01171 01172 /* Does not handle locales or non-contiguous alphabetic characters */ 01173 return ((source >= (int)'A') && (source <= (int)'Z')) 01174 ? source - 'A' + 'a' 01175 : source; 01176 01177 #endif 01178 } 01179 #endif /* !defined(TRIO_MINIMAL) */ 01180 01181 #if !defined(TRIO_MINIMAL) 01182 01189 TRIO_STRING_PUBLIC unsigned long 01190 trio_to_unsigned_long 01191 TRIO_ARGS3((string, endp, base), 01192 TRIO_CONST char *string, 01193 char **endp, 01194 int base) 01195 { 01196 assert(string); 01197 assert((base >= 2) && (base <= 36)); 01198 01199 return strtoul(string, endp, base); 01200 } 01201 #endif /* !defined(TRIO_MINIMAL) */ 01202 01203 01210 TRIO_STRING_PUBLIC int 01211 trio_to_upper 01212 TRIO_ARGS1((source), 01213 int source) 01214 { 01215 #if defined(USE_TOUPPER) 01216 01217 return toupper(source); 01218 01219 #else 01220 01221 /* Does not handle locales or non-contiguous alphabetic characters */ 01222 return ((source >= (int)'a') && (source <= (int)'z')) 01223 ? source - 'a' + 'A' 01224 : source; 01225 01226 #endif 01227 } 01228 01229 #if !defined(TRIO_MINIMAL) 01230 01236 TRIO_STRING_PUBLIC int 01237 trio_upper 01238 TRIO_ARGS1((target), 01239 char *target) 01240 { 01241 assert(target); 01242 01243 return trio_span_function(target, target, trio_to_upper); 01244 } 01245 #endif /* !defined(TRIO_MINIMAL) */ 01246 01247 01251 /************************************************************************* 01252 * Dynamic String Functions 01253 */ 01254 01255 #if defined(TRIO_DOCUMENTATION) 01256 # include "doc/doc_dynamic.h" 01257 #endif 01258 01262 /* 01263 * TrioStringAlloc 01264 */ 01265 TRIO_STRING_PRIVATE trio_string_t * 01266 TrioStringAlloc(TRIO_NOARGS) 01267 { 01268 trio_string_t *self; 01269 01270 self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); 01271 if (self) 01272 { 01273 self->content = NULL; 01274 self->length = 0; 01275 self->allocated = 0; 01276 } 01277 return self; 01278 } 01279 01280 01281 /* 01282 * TrioStringGrow 01283 * 01284 * The size of the string will be increased by 'delta' characters. If 01285 * 'delta' is zero, the size will be doubled. 01286 */ 01287 TRIO_STRING_PRIVATE BOOLEAN_T 01288 TrioStringGrow 01289 TRIO_ARGS2((self, delta), 01290 trio_string_t *self, 01291 size_t delta) 01292 { 01293 BOOLEAN_T status = FALSE; 01294 char *new_content; 01295 size_t new_size; 01296 01297 new_size = (delta == 0) 01298 ? ( (self->allocated == 0) ? 1 : self->allocated * 2 ) 01299 : self->allocated + delta; 01300 01301 new_content = (char *)TRIO_REALLOC(self->content, new_size); 01302 if (new_content) 01303 { 01304 self->content = new_content; 01305 self->allocated = new_size; 01306 status = TRUE; 01307 } 01308 return status; 01309 } 01310 01311 01312 #if !defined(TRIO_MINIMAL) 01313 /* 01314 * TrioStringGrowTo 01315 * 01316 * The size of the string will be increased to 'length' plus one characters. 01317 * If 'length' is less than the original size, the original size will be 01318 * used (that is, the size of the string is never decreased). 01319 */ 01320 TRIO_STRING_PRIVATE BOOLEAN_T 01321 TrioStringGrowTo 01322 TRIO_ARGS2((self, length), 01323 trio_string_t *self, 01324 size_t length) 01325 { 01326 length++; /* Room for terminating zero */ 01327 return (self->allocated < length) 01328 ? TrioStringGrow(self, length - self->allocated) 01329 : TRUE; 01330 } 01331 #endif /* !defined(TRIO_MINIMAL) */ 01332 01333 01334 #if !defined(TRIO_MINIMAL) 01335 01341 TRIO_STRING_PUBLIC trio_string_t * 01342 trio_string_create 01343 TRIO_ARGS1((initial_size), 01344 int initial_size) 01345 { 01346 trio_string_t *self; 01347 01348 self = TrioStringAlloc(); 01349 if (self) 01350 { 01351 if (TrioStringGrow(self, 01352 (size_t)((initial_size > 0) ? initial_size : 1))) 01353 { 01354 self->content[0] = (char)0; 01355 self->allocated = initial_size; 01356 } 01357 else 01358 { 01359 trio_string_destroy(self); 01360 self = NULL; 01361 } 01362 } 01363 return self; 01364 } 01365 #endif /* !defined(TRIO_MINIMAL) */ 01366 01367 01373 TRIO_STRING_PUBLIC void 01374 trio_string_destroy 01375 TRIO_ARGS1((self), 01376 trio_string_t *self) 01377 { 01378 assert(self); 01379 01380 if (self) 01381 { 01382 trio_destroy(self->content); 01383 TRIO_FREE(self); 01384 } 01385 } 01386 01387 01388 #if !defined(TRIO_MINIMAL) 01389 01403 TRIO_STRING_PUBLIC char * 01404 trio_string_get 01405 TRIO_ARGS2((self, offset), 01406 trio_string_t *self, 01407 int offset) 01408 { 01409 char *result = NULL; 01410 01411 assert(self); 01412 01413 if (self->content != NULL) 01414 { 01415 if (self->length == 0) 01416 { 01417 (void)trio_string_length(self); 01418 } 01419 if (offset >= 0) 01420 { 01421 if (offset > (int)self->length) 01422 { 01423 offset = self->length; 01424 } 01425 } 01426 else 01427 { 01428 offset += self->length + 1; 01429 if (offset < 0) 01430 { 01431 offset = 0; 01432 } 01433 } 01434 result = &(self->content[offset]); 01435 } 01436 return result; 01437 } 01438 #endif /* !defined(TRIO_MINIMAL) */ 01439 01440 01450 TRIO_STRING_PUBLIC char * 01451 trio_string_extract 01452 TRIO_ARGS1((self), 01453 trio_string_t *self) 01454 { 01455 char *result; 01456 01457 assert(self); 01458 01459 result = self->content; 01460 /* FIXME: Allocate new empty buffer? */ 01461 self->content = NULL; 01462 self->length = self->allocated = 0; 01463 return result; 01464 } 01465 01466 01467 #if !defined(TRIO_MINIMAL) 01468 01481 TRIO_STRING_PUBLIC void 01482 trio_xstring_set 01483 TRIO_ARGS2((self, buffer), 01484 trio_string_t *self, 01485 char *buffer) 01486 { 01487 assert(self); 01488 01489 trio_destroy(self->content); 01490 self->content = trio_duplicate(buffer); 01491 } 01492 #endif /* !defined(TRIO_MINIMAL) */ 01493 01494 01495 /* 01496 * trio_string_size 01497 */ 01498 TRIO_STRING_PUBLIC int 01499 trio_string_size 01500 TRIO_ARGS1((self), 01501 trio_string_t *self) 01502 { 01503 assert(self); 01504 01505 return self->allocated; 01506 } 01507 01508 01509 /* 01510 * trio_string_terminate 01511 */ 01512 TRIO_STRING_PUBLIC void 01513 trio_string_terminate 01514 TRIO_ARGS1((self), 01515 trio_string_t *self) 01516 { 01517 trio_xstring_append_char(self, 0); 01518 } 01519 01520 01521 #if !defined(TRIO_MINIMAL) 01522 01529 TRIO_STRING_PUBLIC int 01530 trio_string_append 01531 TRIO_ARGS2((self, other), 01532 trio_string_t *self, 01533 trio_string_t *other) 01534 { 01535 size_t length; 01536 01537 assert(self); 01538 assert(other); 01539 01540 length = self->length + other->length; 01541 if (!TrioStringGrowTo(self, length)) 01542 goto error; 01543 trio_copy(&self->content[self->length], other->content); 01544 self->length = length; 01545 return TRUE; 01546 01547 error: 01548 return FALSE; 01549 } 01550 #endif /* !defined(TRIO_MINIMAL) */ 01551 01552 01553 #if !defined(TRIO_MINIMAL) 01554 /* 01555 * trio_xstring_append 01556 */ 01557 TRIO_STRING_PUBLIC int 01558 trio_xstring_append 01559 TRIO_ARGS2((self, other), 01560 trio_string_t *self, 01561 TRIO_CONST char *other) 01562 { 01563 size_t length; 01564 01565 assert(self); 01566 assert(other); 01567 01568 length = self->length + trio_length(other); 01569 if (!TrioStringGrowTo(self, length)) 01570 goto error; 01571 trio_copy(&self->content[self->length], other); 01572 self->length = length; 01573 return TRUE; 01574 01575 error: 01576 return FALSE; 01577 } 01578 #endif /* !defined(TRIO_MINIMAL) */ 01579 01580 01581 /* 01582 * trio_xstring_append_char 01583 */ 01584 TRIO_STRING_PUBLIC int 01585 trio_xstring_append_char 01586 TRIO_ARGS2((self, character), 01587 trio_string_t *self, 01588 char character) 01589 { 01590 assert(self); 01591 01592 if ((int)self->length >= trio_string_size(self)) 01593 { 01594 if (!TrioStringGrow(self, 0)) 01595 goto error; 01596 } 01597 self->content[self->length] = character; 01598 self->length++; 01599 return TRUE; 01600 01601 error: 01602 return FALSE; 01603 } 01604 01605 01606 #if !defined(TRIO_MINIMAL) 01607 01614 TRIO_STRING_PUBLIC int 01615 trio_string_contains 01616 TRIO_ARGS2((self, other), 01617 trio_string_t *self, 01618 trio_string_t *other) 01619 { 01620 assert(self); 01621 assert(other); 01622 01623 return trio_contains(self->content, other->content); 01624 } 01625 #endif /* !defined(TRIO_MINIMAL) */ 01626 01627 01628 #if !defined(TRIO_MINIMAL) 01629 /* 01630 * trio_xstring_contains 01631 */ 01632 TRIO_STRING_PUBLIC int 01633 trio_xstring_contains 01634 TRIO_ARGS2((self, other), 01635 trio_string_t *self, 01636 TRIO_CONST char *other) 01637 { 01638 assert(self); 01639 assert(other); 01640 01641 return trio_contains(self->content, other); 01642 } 01643 #endif /* !defined(TRIO_MINIMAL) */ 01644 01645 01646 #if !defined(TRIO_MINIMAL) 01647 /* 01648 * trio_string_copy 01649 */ 01650 TRIO_STRING_PUBLIC int 01651 trio_string_copy 01652 TRIO_ARGS2((self, other), 01653 trio_string_t *self, 01654 trio_string_t *other) 01655 { 01656 assert(self); 01657 assert(other); 01658 01659 self->length = 0; 01660 return trio_string_append(self, other); 01661 } 01662 #endif /* !defined(TRIO_MINIMAL) */ 01663 01664 01665 #if !defined(TRIO_MINIMAL) 01666 /* 01667 * trio_xstring_copy 01668 */ 01669 TRIO_STRING_PUBLIC int 01670 trio_xstring_copy 01671 TRIO_ARGS2((self, other), 01672 trio_string_t *self, 01673 TRIO_CONST char *other) 01674 { 01675 assert(self); 01676 assert(other); 01677 01678 self->length = 0; 01679 return trio_xstring_append(self, other); 01680 } 01681 #endif /* !defined(TRIO_MINIMAL) */ 01682 01683 01684 #if !defined(TRIO_MINIMAL) 01685 /* 01686 * trio_string_duplicate 01687 */ 01688 TRIO_STRING_PUBLIC trio_string_t * 01689 trio_string_duplicate 01690 TRIO_ARGS1((other), 01691 trio_string_t *other) 01692 { 01693 trio_string_t *self; 01694 01695 assert(other); 01696 01697 self = TrioStringAlloc(); 01698 if (self) 01699 { 01700 self->content = TrioDuplicateMax(other->content, other->length); 01701 if (self->content) 01702 { 01703 self->length = other->length; 01704 self->allocated = self->length + 1; 01705 } 01706 else 01707 { 01708 self->length = self->allocated = 0; 01709 } 01710 } 01711 return self; 01712 } 01713 #endif /* !defined(TRIO_MINIMAL) */ 01714 01715 01716 /* 01717 * trio_xstring_duplicate 01718 */ 01719 TRIO_STRING_PUBLIC trio_string_t * 01720 trio_xstring_duplicate 01721 TRIO_ARGS1((other), 01722 TRIO_CONST char *other) 01723 { 01724 trio_string_t *self; 01725 01726 assert(other); 01727 01728 self = TrioStringAlloc(); 01729 if (self) 01730 { 01731 self->content = TrioDuplicateMax(other, trio_length(other)); 01732 if (self->content) 01733 { 01734 self->length = trio_length(self->content); 01735 self->allocated = self->length + 1; 01736 } 01737 else 01738 { 01739 self->length = self->allocated = 0; 01740 } 01741 } 01742 return self; 01743 } 01744 01745 01746 #if !defined(TRIO_MINIMAL) 01747 /* 01748 * trio_string_equal 01749 */ 01750 TRIO_STRING_PUBLIC int 01751 trio_string_equal 01752 TRIO_ARGS2((self, other), 01753 trio_string_t *self, 01754 trio_string_t *other) 01755 { 01756 assert(self); 01757 assert(other); 01758 01759 return trio_equal(self->content, other->content); 01760 } 01761 #endif /* !defined(TRIO_MINIMAL) */ 01762 01763 01764 #if !defined(TRIO_MINIMAL) 01765 /* 01766 * trio_xstring_equal 01767 */ 01768 TRIO_STRING_PUBLIC int 01769 trio_xstring_equal 01770 TRIO_ARGS2((self, other), 01771 trio_string_t *self, 01772 TRIO_CONST char *other) 01773 { 01774 assert(self); 01775 assert(other); 01776 01777 return trio_equal(self->content, other); 01778 } 01779 #endif /* !defined(TRIO_MINIMAL) */ 01780 01781 01782 #if !defined(TRIO_MINIMAL) 01783 /* 01784 * trio_string_equal_max 01785 */ 01786 TRIO_STRING_PUBLIC int 01787 trio_string_equal_max 01788 TRIO_ARGS3((self, max, other), 01789 trio_string_t *self, 01790 size_t max, 01791 trio_string_t *other) 01792 { 01793 assert(self); 01794 assert(other); 01795 01796 return trio_equal_max(self->content, max, other->content); 01797 } 01798 #endif /* !defined(TRIO_MINIMAL) */ 01799 01800 01801 #if !defined(TRIO_MINIMAL) 01802 /* 01803 * trio_xstring_equal_max 01804 */ 01805 TRIO_STRING_PUBLIC int 01806 trio_xstring_equal_max 01807 TRIO_ARGS3((self, max, other), 01808 trio_string_t *self, 01809 size_t max, 01810 TRIO_CONST char *other) 01811 { 01812 assert(self); 01813 assert(other); 01814 01815 return trio_equal_max(self->content, max, other); 01816 } 01817 #endif /* !defined(TRIO_MINIMAL) */ 01818 01819 01820 #if !defined(TRIO_MINIMAL) 01821 /* 01822 * trio_string_equal_case 01823 */ 01824 TRIO_STRING_PUBLIC int 01825 trio_string_equal_case 01826 TRIO_ARGS2((self, other), 01827 trio_string_t *self, 01828 trio_string_t *other) 01829 { 01830 assert(self); 01831 assert(other); 01832 01833 return trio_equal_case(self->content, other->content); 01834 } 01835 #endif /* !defined(TRIO_MINIMAL) */ 01836 01837 01838 #if !defined(TRIO_MINIMAL) 01839 /* 01840 * trio_xstring_equal_case 01841 */ 01842 TRIO_STRING_PUBLIC int 01843 trio_xstring_equal_case 01844 TRIO_ARGS2((self, other), 01845 trio_string_t *self, 01846 TRIO_CONST char *other) 01847 { 01848 assert(self); 01849 assert(other); 01850 01851 return trio_equal_case(self->content, other); 01852 } 01853 #endif /* !defined(TRIO_MINIMAL) */ 01854 01855 01856 #if !defined(TRIO_MINIMAL) 01857 /* 01858 * trio_string_equal_case_max 01859 */ 01860 TRIO_STRING_PUBLIC int 01861 trio_string_equal_case_max 01862 TRIO_ARGS3((self, max, other), 01863 trio_string_t *self, 01864 size_t max, 01865 trio_string_t *other) 01866 { 01867 assert(self); 01868 assert(other); 01869 01870 return trio_equal_case_max(self->content, max, other->content); 01871 } 01872 #endif /* !defined(TRIO_MINIMAL) */ 01873 01874 01875 #if !defined(TRIO_MINIMAL) 01876 /* 01877 * trio_xstring_equal_case_max 01878 */ 01879 TRIO_STRING_PUBLIC int 01880 trio_xstring_equal_case_max 01881 TRIO_ARGS3((self, max, other), 01882 trio_string_t *self, 01883 size_t max, 01884 TRIO_CONST char *other) 01885 { 01886 assert(self); 01887 assert(other); 01888 01889 return trio_equal_case_max(self->content, max, other); 01890 } 01891 #endif /* !defined(TRIO_MINIMAL) */ 01892 01893 01894 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE) 01895 /* 01896 * trio_string_format_data_max 01897 */ 01898 TRIO_STRING_PUBLIC size_t 01899 trio_string_format_date_max 01900 TRIO_ARGS4((self, max, format, datetime), 01901 trio_string_t *self, 01902 size_t max, 01903 TRIO_CONST char *format, 01904 TRIO_CONST struct tm *datetime) 01905 { 01906 assert(self); 01907 01908 return trio_format_date_max(self->content, max, format, datetime); 01909 } 01910 #endif /* !defined(TRIO_MINIMAL) */ 01911 01912 01913 #if !defined(TRIO_MINIMAL) 01914 /* 01915 * trio_string_index 01916 */ 01917 TRIO_STRING_PUBLIC char * 01918 trio_string_index 01919 TRIO_ARGS2((self, character), 01920 trio_string_t *self, 01921 int character) 01922 { 01923 assert(self); 01924 01925 return trio_index(self->content, character); 01926 } 01927 #endif /* !defined(TRIO_MINIMAL) */ 01928 01929 01930 #if !defined(TRIO_MINIMAL) 01931 /* 01932 * trio_string_index_last 01933 */ 01934 TRIO_STRING_PUBLIC char * 01935 trio_string_index_last 01936 TRIO_ARGS2((self, character), 01937 trio_string_t *self, 01938 int character) 01939 { 01940 assert(self); 01941 01942 return trio_index_last(self->content, character); 01943 } 01944 #endif /* !defined(TRIO_MINIMAL) */ 01945 01946 01947 #if !defined(TRIO_MINIMAL) 01948 /* 01949 * trio_string_length 01950 */ 01951 TRIO_STRING_PUBLIC int 01952 trio_string_length 01953 TRIO_ARGS1((self), 01954 trio_string_t *self) 01955 { 01956 assert(self); 01957 01958 if (self->length == 0) 01959 { 01960 self->length = trio_length(self->content); 01961 } 01962 return self->length; 01963 } 01964 #endif /* !defined(TRIO_MINIMAL) */ 01965 01966 01967 #if !defined(TRIO_MINIMAL) 01968 /* 01969 * trio_string_lower 01970 */ 01971 TRIO_STRING_PUBLIC int 01972 trio_string_lower 01973 TRIO_ARGS1((self), 01974 trio_string_t *self) 01975 { 01976 assert(self); 01977 01978 return trio_lower(self->content); 01979 } 01980 #endif /* !defined(TRIO_MINIMAL) */ 01981 01982 01983 #if !defined(TRIO_MINIMAL) 01984 /* 01985 * trio_string_match 01986 */ 01987 TRIO_STRING_PUBLIC int 01988 trio_string_match 01989 TRIO_ARGS2((self, other), 01990 trio_string_t *self, 01991 trio_string_t *other) 01992 { 01993 assert(self); 01994 assert(other); 01995 01996 return trio_match(self->content, other->content); 01997 } 01998 #endif /* !defined(TRIO_MINIMAL) */ 01999 02000 02001 #if !defined(TRIO_MINIMAL) 02002 /* 02003 * trio_xstring_match 02004 */ 02005 TRIO_STRING_PUBLIC int 02006 trio_xstring_match 02007 TRIO_ARGS2((self, other), 02008 trio_string_t *self, 02009 TRIO_CONST char *other) 02010 { 02011 assert(self); 02012 assert(other); 02013 02014 return trio_match(self->content, other); 02015 } 02016 #endif /* !defined(TRIO_MINIMAL) */ 02017 02018 02019 #if !defined(TRIO_MINIMAL) 02020 /* 02021 * trio_string_match_case 02022 */ 02023 TRIO_STRING_PUBLIC int 02024 trio_string_match_case 02025 TRIO_ARGS2((self, other), 02026 trio_string_t *self, 02027 trio_string_t *other) 02028 { 02029 assert(self); 02030 assert(other); 02031 02032 return trio_match_case(self->content, other->content); 02033 } 02034 #endif /* !defined(TRIO_MINIMAL) */ 02035 02036 02037 #if !defined(TRIO_MINIMAL) 02038 /* 02039 * trio_xstring_match_case 02040 */ 02041 TRIO_STRING_PUBLIC int 02042 trio_xstring_match_case 02043 TRIO_ARGS2((self, other), 02044 trio_string_t *self, 02045 TRIO_CONST char *other) 02046 { 02047 assert(self); 02048 assert(other); 02049 02050 return trio_match_case(self->content, other); 02051 } 02052 #endif /* !defined(TRIO_MINIMAL) */ 02053 02054 02055 #if !defined(TRIO_MINIMAL) 02056 /* 02057 * trio_string_substring 02058 */ 02059 TRIO_STRING_PUBLIC char * 02060 trio_string_substring 02061 TRIO_ARGS2((self, other), 02062 trio_string_t *self, 02063 trio_string_t *other) 02064 { 02065 assert(self); 02066 assert(other); 02067 02068 return trio_substring(self->content, other->content); 02069 } 02070 #endif /* !defined(TRIO_MINIMAL) */ 02071 02072 02073 #if !defined(TRIO_MINIMAL) 02074 /* 02075 * trio_xstring_substring 02076 */ 02077 TRIO_STRING_PUBLIC char * 02078 trio_xstring_substring 02079 TRIO_ARGS2((self, other), 02080 trio_string_t *self, 02081 TRIO_CONST char *other) 02082 { 02083 assert(self); 02084 assert(other); 02085 02086 return trio_substring(self->content, other); 02087 } 02088 #endif /* !defined(TRIO_MINIMAL) */ 02089 02090 02091 #if !defined(TRIO_MINIMAL) 02092 /* 02093 * trio_string_upper 02094 */ 02095 TRIO_STRING_PUBLIC int 02096 trio_string_upper 02097 TRIO_ARGS1((self), 02098 trio_string_t *self) 02099 { 02100 assert(self); 02101 02102 return trio_upper(self->content); 02103 } 02104 #endif /* !defined(TRIO_MINIMAL) */ 02105 Generated on Fri May 25 2012 04:33:12 for ReactOS by
1.7.6.1
|