ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

triostr.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.