Annotation of embedaddon/libxml2/triostr.c, revision 1.1.1.2

1.1       misho       1: /*************************************************************************
                      2:  *
                      3:  * $Id$
                      4:  *
                      5:  * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     12:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     13:  * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
                     14:  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
                     15:  *
                     16:  ************************************************************************/
                     17: 
                     18: /*************************************************************************
                     19:  * Include files
                     20:  */
                     21: 
                     22: #include <assert.h>
                     23: #include <stdlib.h>
                     24: #include <string.h>
                     25: #include <ctype.h>
                     26: #include <math.h>
                     27: #include "triodef.h"
                     28: #include "triostr.h"
                     29: 
                     30: /*************************************************************************
                     31:  * Definitions
                     32:  */
                     33: 
                     34: #if !defined(TRIO_STRING_PUBLIC)
                     35: # define TRIO_STRING_PUBLIC TRIO_PUBLIC
                     36: #endif
                     37: #if !defined(TRIO_STRING_PRIVATE)
                     38: # define TRIO_STRING_PRIVATE TRIO_PRIVATE
                     39: #endif
                     40: 
                     41: #if !defined(NULL)
                     42: # define NULL 0
                     43: #endif
                     44: #if !defined(NIL)
                     45: # define NIL ((char)0)
                     46: #endif
                     47: #if !defined(FALSE)
                     48: # define FALSE (1 == 0)
                     49: # define TRUE (! FALSE)
                     50: #endif
                     51: #if !defined(BOOLEAN_T)
                     52: # define BOOLEAN_T int
                     53: #endif
                     54: 
                     55: #if defined(TRIO_COMPILER_SUPPORTS_C99)
                     56: # define USE_STRTOD
                     57: # define USE_STRTOF
                     58: #elif defined(TRIO_COMPILER_MSVC)
                     59: # define USE_STRTOD
                     60: #endif
                     61: 
                     62: #if defined(TRIO_PLATFORM_UNIX)
                     63: # define USE_STRCASECMP
                     64: # define USE_STRNCASECMP
                     65: # if defined(TRIO_PLATFORM_SUNOS)
                     66: #  define USE_SYS_ERRLIST
                     67: # else
                     68: #  define USE_STRERROR
                     69: # endif
                     70: # if defined(TRIO_PLATFORM_QNX)
                     71: #  define strcasecmp(x,y) stricmp(x,y)
                     72: #  define strncasecmp(x,y,n) strnicmp(x,y,n)
                     73: # endif
                     74: #elif defined(TRIO_PLATFORM_WIN32)
                     75: # define USE_STRCASECMP
                     76: # if defined(_WIN32_WCE)
                     77: #  define strcasecmp(x,y) _stricmp(x,y)
                     78: # else
                     79: #  define strcasecmp(x,y) strcmpi(x,y)
                     80: # endif
                     81: #endif
                     82: 
                     83: #if !(defined(TRIO_PLATFORM_SUNOS))
                     84: # define USE_TOLOWER
                     85: # define USE_TOUPPER
                     86: #endif
                     87: 
                     88: /*************************************************************************
                     89:  * Structures
                     90:  */
                     91: 
                     92: struct _trio_string_t
                     93: {
                     94:   char *content;
                     95:   size_t length;
                     96:   size_t allocated;
                     97: };
                     98: 
                     99: /*************************************************************************
                    100:  * Constants
                    101:  */
                    102: 
                    103: #if !defined(TRIO_MINIMAL)
                    104: static TRIO_CONST char rcsid[] = "@(#)$Id$";
                    105: #endif
                    106: 
                    107: /*************************************************************************
                    108:  * Static String Functions
                    109:  */
                    110: 
                    111: #if defined(TRIO_DOCUMENTATION)
                    112: # include "doc/doc_static.h"
                    113: #endif
                    114: /** @addtogroup StaticStrings
                    115:     @{
                    116: */
                    117: 
                    118: /**
                    119:    Create new string.
                    120: 
                    121:    @param size Size of new string.
                    122:    @return Pointer to string, or NULL if allocation failed.
                    123: */
                    124: TRIO_STRING_PUBLIC char *
                    125: trio_create
                    126: TRIO_ARGS1((size),
                    127:           size_t size)
                    128: {
                    129:   return (char *)TRIO_MALLOC(size);
                    130: }
                    131: 
                    132: 
                    133: /**
                    134:    Destroy string.
                    135: 
                    136:    @param string String to be freed.
                    137: */
                    138: TRIO_STRING_PUBLIC void
                    139: trio_destroy
                    140: TRIO_ARGS1((string),
                    141:           char *string)
                    142: {
                    143:   if (string)
                    144:     {
                    145:       TRIO_FREE(string);
                    146:     }
                    147: }
                    148: 
                    149: 
                    150: /**
                    151:    Count the number of characters in a string.
                    152: 
                    153:    @param string String to measure.
                    154:    @return Number of characters in @string.
                    155: */
                    156: TRIO_STRING_PUBLIC size_t
                    157: trio_length
                    158: TRIO_ARGS1((string),
                    159:           TRIO_CONST char *string)
                    160: {
                    161:   return strlen(string);
                    162: }
                    163: 
                    164: 
                    165: #if !defined(TRIO_MINIMAL)
                    166: /**
                    167:    Append @p source at the end of @p target.
1.1.1.2 ! misho     168: 
1.1       misho     169:    @param target Target string.
                    170:    @param source Source string.
                    171:    @return Boolean value indicating success or failure.
1.1.1.2 ! misho     172: 
1.1       misho     173:    @pre @p target must point to a memory chunk with sufficient room to
                    174:    contain the @p target string and @p source string.
                    175:    @pre No boundary checking is performed, so insufficient memory will
                    176:    result in a buffer overrun.
                    177:    @post @p target will be zero terminated.
                    178: */
                    179: TRIO_STRING_PUBLIC int
                    180: trio_append
                    181: TRIO_ARGS2((target, source),
                    182:           char *target,
                    183:           TRIO_CONST char *source)
                    184: {
                    185:   assert(target);
                    186:   assert(source);
1.1.1.2 ! misho     187: 
1.1       misho     188:   return (strcat(target, source) != NULL);
                    189: }
                    190: #endif /* !defined(TRIO_MINIMAL) */
                    191: 
                    192: #if !defined(TRIO_MINIMAL)
                    193: /**
                    194:    Append at most @p max characters from @p source to @p target.
1.1.1.2 ! misho     195: 
1.1       misho     196:    @param target Target string.
                    197:    @param max Maximum number of characters to append.
                    198:    @param source Source string.
                    199:    @return Boolean value indicating success or failure.
1.1.1.2 ! misho     200: 
1.1       misho     201:    @pre @p target must point to a memory chuck with sufficient room to
                    202:    contain the @p target string and the @p source string (at most @p max
                    203:    characters).
                    204:    @pre No boundary checking is performed, so insufficient memory will
                    205:    result in a buffer overrun.
                    206:    @post @p target will be zero terminated.
                    207: */
                    208: TRIO_STRING_PUBLIC int
                    209: trio_append_max
                    210: TRIO_ARGS3((target, max, source),
                    211:           char *target,
                    212:           size_t max,
                    213:           TRIO_CONST char *source)
                    214: {
                    215:   size_t length;
1.1.1.2 ! misho     216: 
1.1       misho     217:   assert(target);
                    218:   assert(source);
                    219: 
                    220:   length = trio_length(target);
1.1.1.2 ! misho     221: 
1.1       misho     222:   if (max > length)
                    223:     {
                    224:       strncat(target, source, max - length - 1);
                    225:     }
                    226:   return TRUE;
                    227: }
                    228: #endif /* !defined(TRIO_MINIMAL) */
                    229: 
                    230: 
                    231: #if !defined(TRIO_MINIMAL)
                    232: /**
                    233:    Determine if a string contains a substring.
                    234: 
                    235:    @param string String to be searched.
                    236:    @param substring String to be found.
                    237:    @return Boolean value indicating success or failure.
                    238: */
                    239: TRIO_STRING_PUBLIC int
                    240: trio_contains
                    241: TRIO_ARGS2((string, substring),
                    242:           TRIO_CONST char *string,
                    243:           TRIO_CONST char *substring)
                    244: {
                    245:   assert(string);
                    246:   assert(substring);
1.1.1.2 ! misho     247: 
1.1       misho     248:   return (0 != strstr(string, substring));
                    249: }
                    250: #endif /* !defined(TRIO_MINIMAL) */
                    251: 
                    252: 
                    253: #if !defined(TRIO_MINIMAL)
                    254: /**
                    255:    Copy @p source to @p target.
1.1.1.2 ! misho     256: 
1.1       misho     257:    @param target Target string.
                    258:    @param source Source string.
                    259:    @return Boolean value indicating success or failure.
1.1.1.2 ! misho     260: 
1.1       misho     261:    @pre @p target must point to a memory chunk with sufficient room to
                    262:    contain the @p source string.
                    263:    @pre No boundary checking is performed, so insufficient memory will
                    264:    result in a buffer overrun.
                    265:    @post @p target will be zero terminated.
                    266: */
                    267: TRIO_STRING_PUBLIC int
                    268: trio_copy
                    269: TRIO_ARGS2((target, source),
                    270:           char *target,
                    271:           TRIO_CONST char *source)
                    272: {
                    273:   assert(target);
                    274:   assert(source);
1.1.1.2 ! misho     275: 
1.1       misho     276:   (void)strcpy(target, source);
                    277:   return TRUE;
                    278: }
                    279: #endif /* !defined(TRIO_MINIMAL) */
                    280: 
                    281: 
                    282: /**
                    283:    Copy at most @p max characters from @p source to @p target.
1.1.1.2 ! misho     284: 
1.1       misho     285:    @param target Target string.
                    286:    @param max Maximum number of characters to append.
                    287:    @param source Source string.
                    288:    @return Boolean value indicating success or failure.
1.1.1.2 ! misho     289: 
1.1       misho     290:    @pre @p target must point to a memory chunk with sufficient room to
                    291:    contain the @p source string (at most @p max characters).
                    292:    @pre No boundary checking is performed, so insufficient memory will
                    293:    result in a buffer overrun.
                    294:    @post @p target will be zero terminated.
                    295: */
                    296: TRIO_STRING_PUBLIC int
                    297: trio_copy_max
                    298: TRIO_ARGS3((target, max, source),
                    299:           char *target,
                    300:           size_t max,
                    301:           TRIO_CONST char *source)
                    302: {
                    303:   assert(target);
                    304:   assert(source);
                    305:   assert(max > 0); /* Includes != 0 */
                    306: 
                    307:   (void)strncpy(target, source, max - 1);
                    308:   target[max - 1] = (char)0;
                    309:   return TRUE;
                    310: }
                    311: 
                    312: 
                    313: /*
                    314:  * TrioDuplicateMax
                    315:  */
                    316: TRIO_STRING_PRIVATE char *
                    317: TrioDuplicateMax
                    318: TRIO_ARGS2((source, size),
                    319:           TRIO_CONST char *source,
                    320:           size_t size)
                    321: {
                    322:   char *target;
                    323: 
                    324:   assert(source);
                    325: 
                    326:   /* Make room for string plus a terminating zero */
                    327:   size++;
                    328:   target = trio_create(size);
                    329:   if (target)
                    330:     {
                    331:       trio_copy_max(target, size, source);
                    332:     }
                    333:   return target;
                    334: }
                    335: 
                    336: 
                    337: /**
                    338:    Duplicate @p source.
1.1.1.2 ! misho     339: 
1.1       misho     340:    @param source Source string.
                    341:    @return A copy of the @p source string.
1.1.1.2 ! misho     342: 
1.1       misho     343:    @post @p target will be zero terminated.
                    344: */
                    345: TRIO_STRING_PUBLIC char *
                    346: trio_duplicate
                    347: TRIO_ARGS1((source),
                    348:           TRIO_CONST char *source)
                    349: {
                    350:   return TrioDuplicateMax(source, trio_length(source));
                    351: }
                    352: 
                    353: 
                    354: #if !defined(TRIO_MINIMAL)
                    355: /**
                    356:    Duplicate at most @p max characters of @p source.
1.1.1.2 ! misho     357: 
1.1       misho     358:    @param source Source string.
                    359:    @param max Maximum number of characters to duplicate.
                    360:    @return A copy of the @p source string.
1.1.1.2 ! misho     361: 
1.1       misho     362:    @post @p target will be zero terminated.
                    363: */
                    364: TRIO_STRING_PUBLIC char *
                    365: trio_duplicate_max TRIO_ARGS2((source, max),
                    366:                              TRIO_CONST char *source,
                    367:                              size_t max)
                    368: {
                    369:   size_t length;
                    370: 
                    371:   assert(source);
                    372:   assert(max > 0);
                    373: 
                    374:   length = trio_length(source);
                    375:   if (length > max)
                    376:     {
                    377:       length = max;
                    378:     }
                    379:   return TrioDuplicateMax(source, length);
                    380: }
                    381: #endif /* !defined(TRIO_MINIMAL) */
                    382: 
                    383: 
                    384: /**
                    385:    Compare if two strings are equal.
1.1.1.2 ! misho     386: 
1.1       misho     387:    @param first First string.
                    388:    @param second Second string.
                    389:    @return Boolean indicating whether the two strings are equal or not.
1.1.1.2 ! misho     390: 
1.1       misho     391:    Case-insensitive comparison.
                    392: */
                    393: TRIO_STRING_PUBLIC int
                    394: trio_equal
                    395: TRIO_ARGS2((first, second),
                    396:           TRIO_CONST char *first,
                    397:           TRIO_CONST char *second)
                    398: {
                    399:   assert(first);
                    400:   assert(second);
                    401: 
                    402:   if ((first != NULL) && (second != NULL))
                    403:     {
                    404: #if defined(USE_STRCASECMP)
                    405:       return (0 == strcasecmp(first, second));
                    406: #else
                    407:       while ((*first != NIL) && (*second != NIL))
                    408:        {
                    409:          if (trio_to_upper(*first) != trio_to_upper(*second))
                    410:            {
                    411:              break;
                    412:            }
                    413:          first++;
                    414:          second++;
                    415:        }
                    416:       return ((*first == NIL) && (*second == NIL));
                    417: #endif
                    418:     }
                    419:   return FALSE;
                    420: }
                    421: 
                    422: 
                    423: /**
                    424:    Compare if two strings are equal.
1.1.1.2 ! misho     425: 
1.1       misho     426:    @param first First string.
                    427:    @param second Second string.
                    428:    @return Boolean indicating whether the two strings are equal or not.
1.1.1.2 ! misho     429: 
1.1       misho     430:    Case-sensitive comparison.
                    431: */
                    432: TRIO_STRING_PUBLIC int
                    433: trio_equal_case
                    434: TRIO_ARGS2((first, second),
                    435:           TRIO_CONST char *first,
                    436:           TRIO_CONST char *second)
                    437: {
                    438:   assert(first);
                    439:   assert(second);
                    440: 
                    441:   if ((first != NULL) && (second != NULL))
                    442:     {
                    443:       return (0 == strcmp(first, second));
                    444:     }
                    445:   return FALSE;
                    446: }
                    447: 
                    448: 
                    449: #if !defined(TRIO_MINIMAL)
                    450: /**
                    451:    Compare if two strings up until the first @p max characters are equal.
1.1.1.2 ! misho     452: 
1.1       misho     453:    @param first First string.
                    454:    @param max Maximum number of characters to compare.
                    455:    @param second Second string.
                    456:    @return Boolean indicating whether the two strings are equal or not.
1.1.1.2 ! misho     457: 
1.1       misho     458:    Case-sensitive comparison.
                    459: */
                    460: TRIO_STRING_PUBLIC int
                    461: trio_equal_case_max
                    462: TRIO_ARGS3((first, max, second),
                    463:           TRIO_CONST char *first,
                    464:           size_t max,
                    465:           TRIO_CONST char *second)
                    466: {
                    467:   assert(first);
                    468:   assert(second);
                    469: 
                    470:   if ((first != NULL) && (second != NULL))
                    471:     {
                    472:       return (0 == strncmp(first, second, max));
                    473:     }
                    474:   return FALSE;
                    475: }
                    476: #endif /* !defined(TRIO_MINIMAL) */
                    477: 
                    478: 
                    479: /**
                    480:    Compare if two strings are equal.
1.1.1.2 ! misho     481: 
1.1       misho     482:    @param first First string.
                    483:    @param second Second string.
                    484:    @return Boolean indicating whether the two strings are equal or not.
                    485: 
                    486:    Collating characters are considered equal.
                    487: */
                    488: TRIO_STRING_PUBLIC int
                    489: trio_equal_locale
                    490: TRIO_ARGS2((first, second),
                    491:           TRIO_CONST char *first,
                    492:           TRIO_CONST char *second)
                    493: {
                    494:   assert(first);
                    495:   assert(second);
                    496: 
                    497: #if defined(LC_COLLATE)
                    498:   return (strcoll(first, second) == 0);
                    499: #else
                    500:   return trio_equal(first, second);
                    501: #endif
                    502: }
                    503: 
                    504: 
                    505: /**
                    506:    Compare if two strings up until the first @p max characters are equal.
1.1.1.2 ! misho     507: 
1.1       misho     508:    @param first First string.
                    509:    @param max Maximum number of characters to compare.
                    510:    @param second Second string.
                    511:    @return Boolean indicating whether the two strings are equal or not.
1.1.1.2 ! misho     512: 
1.1       misho     513:    Case-insensitive comparison.
                    514: */
                    515: TRIO_STRING_PUBLIC int
                    516: trio_equal_max
                    517: TRIO_ARGS3((first, max, second),
                    518:           TRIO_CONST char *first,
                    519:           size_t max,
                    520:           TRIO_CONST char *second)
                    521: {
                    522:   assert(first);
                    523:   assert(second);
                    524: 
                    525:   if ((first != NULL) && (second != NULL))
                    526:     {
                    527: #if defined(USE_STRNCASECMP)
                    528:       return (0 == strncasecmp(first, second, max));
                    529: #else
                    530:       /* Not adequately tested yet */
                    531:       size_t cnt = 0;
                    532:       while ((*first != NIL) && (*second != NIL) && (cnt <= max))
                    533:        {
                    534:          if (trio_to_upper(*first) != trio_to_upper(*second))
                    535:            {
                    536:              break;
                    537:            }
                    538:          first++;
                    539:          second++;
                    540:          cnt++;
                    541:        }
                    542:       return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
                    543: #endif
                    544:     }
                    545:   return FALSE;
                    546: }
                    547: 
                    548: 
                    549: /**
                    550:    Provide a textual description of an error code (errno).
                    551: 
                    552:    @param error_number Error number.
                    553:    @return Textual description of @p error_number.
                    554: */
                    555: TRIO_STRING_PUBLIC TRIO_CONST char *
                    556: trio_error
                    557: TRIO_ARGS1((error_number),
                    558:           int error_number)
                    559: {
                    560: #if defined(USE_STRERROR)
1.1.1.2 ! misho     561: 
1.1       misho     562:   return strerror(error_number);
                    563: 
                    564: #elif defined(USE_SYS_ERRLIST)
                    565: 
                    566:   extern char *sys_errlist[];
                    567:   extern int sys_nerr;
                    568: 
                    569:   return ((error_number < 0) || (error_number >= sys_nerr))
                    570:     ? "unknown"
                    571:     : sys_errlist[error_number];
1.1.1.2 ! misho     572: 
1.1       misho     573: #else
1.1.1.2 ! misho     574: 
1.1       misho     575:   return "unknown";
1.1.1.2 ! misho     576: 
1.1       misho     577: #endif
                    578: }
                    579: 
                    580: 
                    581: #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
                    582: /**
                    583:    Format the date/time according to @p format.
                    584: 
                    585:    @param target Target string.
                    586:    @param max Maximum number of characters to format.
                    587:    @param format Formatting string.
                    588:    @param datetime Date/time structure.
                    589:    @return Number of formatted characters.
                    590: 
                    591:    The formatting string accepts the same specifiers as the standard C
                    592:    function strftime.
                    593: */
                    594: TRIO_STRING_PUBLIC size_t
                    595: trio_format_date_max
                    596: TRIO_ARGS4((target, max, format, datetime),
                    597:           char *target,
                    598:           size_t max,
                    599:           TRIO_CONST char *format,
                    600:           TRIO_CONST struct tm *datetime)
                    601: {
                    602:   assert(target);
                    603:   assert(format);
                    604:   assert(datetime);
                    605:   assert(max > 0);
1.1.1.2 ! misho     606: 
1.1       misho     607:   return strftime(target, max, format, datetime);
                    608: }
                    609: #endif /* !defined(TRIO_MINIMAL) */
                    610: 
                    611: 
                    612: #if !defined(TRIO_MINIMAL)
                    613: /**
                    614:    Calculate a hash value for a string.
                    615: 
                    616:    @param string String to be calculated on.
                    617:    @param type Hash function.
                    618:    @return Calculated hash value.
                    619: 
                    620:    @p type can be one of the following
                    621:    @li @c TRIO_HASH_PLAIN Plain hash function.
                    622: */
                    623: TRIO_STRING_PUBLIC unsigned long
                    624: trio_hash
                    625: TRIO_ARGS2((string, type),
                    626:           TRIO_CONST char *string,
                    627:           int type)
                    628: {
                    629:   unsigned long value = 0L;
                    630:   char ch;
                    631: 
                    632:   assert(string);
1.1.1.2 ! misho     633: 
1.1       misho     634:   switch (type)
                    635:     {
                    636:     case TRIO_HASH_PLAIN:
                    637:       while ( (ch = *string++) != NIL )
                    638:        {
                    639:          value *= 31;
                    640:          value += (unsigned long)ch;
                    641:        }
                    642:       break;
                    643:     default:
                    644:       assert(FALSE);
                    645:       break;
                    646:     }
                    647:   return value;
                    648: }
                    649: #endif /* !defined(TRIO_MINIMAL) */
                    650: 
                    651: 
                    652: #if !defined(TRIO_MINIMAL)
                    653: /**
                    654:    Find first occurrence of a character in a string.
                    655: 
                    656:    @param string String to be searched.
                    657:    @param character Character to be found.
                    658:    @param A pointer to the found character, or NULL if character was not found.
                    659:  */
                    660: TRIO_STRING_PUBLIC char *
                    661: trio_index
                    662: TRIO_ARGS2((string, character),
                    663:           TRIO_CONST char *string,
                    664:           int character)
                    665: {
                    666:   assert(string);
                    667: 
                    668:   return strchr(string, character);
                    669: }
                    670: #endif /* !defined(TRIO_MINIMAL) */
                    671: 
                    672: 
                    673: #if !defined(TRIO_MINIMAL)
                    674: /**
                    675:    Find last occurrence of a character in a string.
                    676: 
                    677:    @param string String to be searched.
                    678:    @param character Character to be found.
                    679:    @param A pointer to the found character, or NULL if character was not found.
                    680:  */
                    681: TRIO_STRING_PUBLIC char *
                    682: trio_index_last
                    683: TRIO_ARGS2((string, character),
                    684:           TRIO_CONST char *string,
                    685:           int character)
                    686: {
                    687:   assert(string);
                    688: 
                    689:   return strchr(string, character);
                    690: }
                    691: #endif /* !defined(TRIO_MINIMAL) */
                    692: 
                    693: 
                    694: #if !defined(TRIO_MINIMAL)
                    695: /**
                    696:    Convert the alphabetic letters in the string to lower-case.
                    697: 
                    698:    @param target String to be converted.
                    699:    @return Number of processed characters (converted or not).
                    700: */
                    701: TRIO_STRING_PUBLIC int
                    702: trio_lower
                    703: TRIO_ARGS1((target),
                    704:           char *target)
                    705: {
                    706:   assert(target);
                    707: 
                    708:   return trio_span_function(target, target, trio_to_lower);
                    709: }
                    710: #endif /* !defined(TRIO_MINIMAL) */
                    711: 
                    712: 
                    713: #if !defined(TRIO_MINIMAL)
                    714: /**
                    715:    Compare two strings using wildcards.
                    716: 
                    717:    @param string String to be searched.
                    718:    @param pattern Pattern, including wildcards, to search for.
                    719:    @return Boolean value indicating success or failure.
                    720: 
                    721:    Case-insensitive comparison.
1.1.1.2 ! misho     722: 
1.1       misho     723:    The following wildcards can be used
                    724:    @li @c * Match any number of characters.
                    725:    @li @c ? Match a single character.
                    726: */
                    727: TRIO_STRING_PUBLIC int
                    728: trio_match
                    729: TRIO_ARGS2((string, pattern),
                    730:           TRIO_CONST char *string,
                    731:           TRIO_CONST char *pattern)
                    732: {
                    733:   assert(string);
                    734:   assert(pattern);
1.1.1.2 ! misho     735: 
1.1       misho     736:   for (; ('*' != *pattern); ++pattern, ++string)
                    737:     {
                    738:       if (NIL == *string)
                    739:        {
                    740:          return (NIL == *pattern);
                    741:        }
                    742:       if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
                    743:          && ('?' != *pattern))
                    744:        {
                    745:          return FALSE;
                    746:        }
                    747:     }
                    748:   /* two-line patch to prevent *too* much recursiveness: */
                    749:   while ('*' == pattern[1])
                    750:     pattern++;
                    751: 
                    752:   do
                    753:     {
                    754:       if ( trio_match(string, &pattern[1]) )
                    755:        {
                    756:          return TRUE;
                    757:        }
                    758:     }
                    759:   while (*string++);
1.1.1.2 ! misho     760: 
1.1       misho     761:   return FALSE;
                    762: }
                    763: #endif /* !defined(TRIO_MINIMAL) */
                    764: 
                    765: 
                    766: #if !defined(TRIO_MINIMAL)
                    767: /**
                    768:    Compare two strings using wildcards.
                    769: 
                    770:    @param string String to be searched.
                    771:    @param pattern Pattern, including wildcards, to search for.
                    772:    @return Boolean value indicating success or failure.
                    773: 
                    774:    Case-sensitive comparison.
1.1.1.2 ! misho     775: 
1.1       misho     776:    The following wildcards can be used
                    777:    @li @c * Match any number of characters.
                    778:    @li @c ? Match a single character.
                    779: */
                    780: TRIO_STRING_PUBLIC int
                    781: trio_match_case
                    782: TRIO_ARGS2((string, pattern),
                    783:           TRIO_CONST char *string,
                    784:           TRIO_CONST char *pattern)
                    785: {
                    786:   assert(string);
                    787:   assert(pattern);
1.1.1.2 ! misho     788: 
1.1       misho     789:   for (; ('*' != *pattern); ++pattern, ++string)
                    790:     {
                    791:       if (NIL == *string)
                    792:        {
                    793:          return (NIL == *pattern);
                    794:        }
                    795:       if ((*string != *pattern)
                    796:          && ('?' != *pattern))
                    797:        {
                    798:          return FALSE;
                    799:        }
                    800:     }
                    801:   /* two-line patch to prevent *too* much recursiveness: */
                    802:   while ('*' == pattern[1])
                    803:     pattern++;
                    804: 
                    805:   do
                    806:     {
                    807:       if ( trio_match_case(string, &pattern[1]) )
                    808:        {
                    809:          return TRUE;
                    810:        }
                    811:     }
                    812:   while (*string++);
1.1.1.2 ! misho     813: 
1.1       misho     814:   return FALSE;
                    815: }
                    816: #endif /* !defined(TRIO_MINIMAL) */
                    817: 
                    818: 
                    819: #if !defined(TRIO_MINIMAL)
                    820: /**
                    821:    Execute a function on each character in string.
                    822: 
                    823:    @param target Target string.
                    824:    @param source Source string.
                    825:    @param Function Function to be executed.
                    826:    @return Number of processed characters.
                    827: */
                    828: TRIO_STRING_PUBLIC size_t
                    829: trio_span_function
                    830: TRIO_ARGS3((target, source, Function),
                    831:           char *target,
                    832:           TRIO_CONST char *source,
                    833:           int (*Function) TRIO_PROTO((int)))
                    834: {
                    835:   size_t count = 0;
                    836: 
                    837:   assert(target);
                    838:   assert(source);
                    839:   assert(Function);
1.1.1.2 ! misho     840: 
1.1       misho     841:   while (*source != NIL)
                    842:     {
                    843:       *target++ = Function(*source++);
                    844:       count++;
                    845:     }
                    846:   return count;
                    847: }
                    848: #endif /* !defined(TRIO_MINIMAL) */
                    849: 
                    850: 
                    851: #if !defined(TRIO_MINIMAL)
                    852: /**
                    853:    Search for a substring in a string.
                    854: 
                    855:    @param string String to be searched.
                    856:    @param substring String to be found.
                    857:    @return Pointer to first occurrence of @p substring in @p string, or NULL
                    858:    if no match was found.
                    859: */
                    860: TRIO_STRING_PUBLIC char *
                    861: trio_substring
                    862: TRIO_ARGS2((string, substring),
                    863:           TRIO_CONST char *string,
                    864:           TRIO_CONST char *substring)
                    865: {
                    866:   assert(string);
                    867:   assert(substring);
                    868: 
                    869:   return strstr(string, substring);
                    870: }
                    871: #endif /* !defined(TRIO_MINIMAL) */
                    872: 
                    873: 
                    874: #if !defined(TRIO_MINIMAL)
                    875: /**
                    876:    Search for a substring in the first @p max characters of a string.
                    877: 
                    878:    @param string String to be searched.
                    879:    @param max Maximum characters to be searched.
                    880:    @param substring String to be found.
                    881:    @return Pointer to first occurrence of @p substring in @p string, or NULL
                    882:    if no match was found.
                    883: */
                    884: TRIO_STRING_PUBLIC char *
                    885: trio_substring_max
                    886: TRIO_ARGS3((string, max, substring),
                    887:           TRIO_CONST char *string,
                    888:           size_t max,
                    889:           TRIO_CONST char *substring)
                    890: {
                    891:   size_t count;
                    892:   size_t size;
                    893:   char *result = NULL;
                    894: 
                    895:   assert(string);
                    896:   assert(substring);
1.1.1.2 ! misho     897: 
1.1       misho     898:   size = trio_length(substring);
                    899:   if (size <= max)
                    900:     {
                    901:       for (count = 0; count <= max - size; count++)
                    902:        {
                    903:          if (trio_equal_max(substring, size, &string[count]))
                    904:            {
                    905:              result = (char *)&string[count];
                    906:              break;
                    907:            }
                    908:        }
                    909:     }
                    910:   return result;
                    911: }
                    912: #endif /* !defined(TRIO_MINIMAL) */
                    913: 
                    914: 
                    915: #if !defined(TRIO_MINIMAL)
                    916: /**
                    917:    Tokenize string.
                    918: 
                    919:    @param string String to be tokenized.
                    920:    @param tokens String containing list of delimiting characters.
                    921:    @return Start of new token.
                    922: 
                    923:    @warning @p string will be destroyed.
                    924: */
                    925: TRIO_STRING_PUBLIC char *
                    926: trio_tokenize
                    927: TRIO_ARGS2((string, delimiters),
                    928:           char *string,
                    929:           TRIO_CONST char *delimiters)
                    930: {
                    931:   assert(delimiters);
1.1.1.2 ! misho     932: 
1.1       misho     933:   return strtok(string, delimiters);
                    934: }
                    935: #endif /* !defined(TRIO_MINIMAL) */
                    936: 
                    937: 
                    938: /**
                    939:    Convert string to floating-point number.
                    940: 
                    941:    @param source String to be converted.
                    942:    @param endp Pointer to end of the converted string.
                    943:    @return A floating-point number.
                    944: 
                    945:    The following Extended Backus-Naur form is used
                    946:    @verbatim
                    947:    double        ::= [ <sign> ]
                    948:                      ( <number> |
                    949:                        <number> <decimal_point> <number> |
                    950:                        <decimal_point> <number> )
                    951:                      [ <exponential> [ <sign> ] <number> ]
                    952:    number        ::= 1*( <digit> )
                    953:    digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
                    954:    exponential   ::= ( 'e' | 'E' )
                    955:    sign          ::= ( '-' | '+' )
                    956:    decimal_point ::= '.'
                    957:    @endverbatim
                    958: */
                    959: /* FIXME: Add EBNF for hex-floats */
                    960: TRIO_STRING_PUBLIC trio_long_double_t
                    961: trio_to_long_double
                    962: TRIO_ARGS2((source, endp),
                    963:           TRIO_CONST char *source,
                    964:           char **endp)
                    965: {
                    966: #if defined(USE_STRTOLD)
                    967:   return strtold(source, endp);
                    968: #else
                    969:   int isNegative = FALSE;
                    970:   int isExponentNegative = FALSE;
                    971:   trio_long_double_t integer = 0.0;
                    972:   trio_long_double_t fraction = 0.0;
                    973:   unsigned long exponent = 0;
                    974:   trio_long_double_t base;
                    975:   trio_long_double_t fracdiv = 1.0;
                    976:   trio_long_double_t value = 0.0;
                    977: 
                    978:   /* First try hex-floats */
                    979:   if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
                    980:     {
                    981:       base = 16.0;
                    982:       source += 2;
                    983:       while (isxdigit((int)*source))
                    984:        {
                    985:          integer *= base;
                    986:          integer += (isdigit((int)*source)
                    987:                      ? (*source - '0')
                    988:                      : 10 + (trio_to_upper((int)*source) - 'A'));
                    989:          source++;
                    990:        }
                    991:       if (*source == '.')
                    992:        {
                    993:          source++;
                    994:          while (isxdigit((int)*source))
                    995:            {
                    996:              fracdiv /= base;
                    997:              fraction += fracdiv * (isdigit((int)*source)
                    998:                                     ? (*source - '0')
                    999:                                     : 10 + (trio_to_upper((int)*source) - 'A'));
                   1000:              source++;
                   1001:            }
                   1002:          if ((*source == 'p') || (*source == 'P'))
                   1003:            {
                   1004:              source++;
                   1005:              if ((*source == '+') || (*source == '-'))
                   1006:                {
                   1007:                  isExponentNegative = (*source == '-');
                   1008:                  source++;
                   1009:                }
                   1010:              while (isdigit((int)*source))
                   1011:                {
                   1012:                  exponent *= 10;
                   1013:                  exponent += (*source - '0');
                   1014:                  source++;
                   1015:                }
                   1016:            }
                   1017:        }
                   1018:       /* For later use with exponent */
                   1019:       base = 2.0;
                   1020:     }
                   1021:   else /* Then try normal decimal floats */
                   1022:     {
                   1023:       base = 10.0;
                   1024:       isNegative = (*source == '-');
                   1025:       /* Skip sign */
                   1026:       if ((*source == '+') || (*source == '-'))
                   1027:        source++;
                   1028: 
                   1029:       /* Integer part */
                   1030:       while (isdigit((int)*source))
                   1031:        {
                   1032:          integer *= base;
                   1033:          integer += (*source - '0');
                   1034:          source++;
                   1035:        }
                   1036: 
                   1037:       if (*source == '.')
                   1038:        {
                   1039:          source++; /* skip decimal point */
                   1040:          while (isdigit((int)*source))
                   1041:            {
                   1042:              fracdiv /= base;
                   1043:              fraction += (*source - '0') * fracdiv;
                   1044:              source++;
                   1045:            }
                   1046:        }
                   1047:       if ((*source == 'e')
                   1048:          || (*source == 'E')
                   1049: #if TRIO_MICROSOFT
                   1050:          || (*source == 'd')
                   1051:          || (*source == 'D')
                   1052: #endif
                   1053:          )
                   1054:        {
                   1055:          source++; /* Skip exponential indicator */
                   1056:          isExponentNegative = (*source == '-');
                   1057:          if ((*source == '+') || (*source == '-'))
                   1058:            source++;
                   1059:          while (isdigit((int)*source))
                   1060:            {
                   1061:              exponent *= (int)base;
                   1062:              exponent += (*source - '0');
                   1063:              source++;
                   1064:            }
                   1065:        }
                   1066:     }
1.1.1.2 ! misho    1067: 
1.1       misho    1068:   value = integer + fraction;
                   1069:   if (exponent != 0)
                   1070:     {
                   1071:       if (isExponentNegative)
                   1072:        value /= pow(base, (double)exponent);
                   1073:       else
                   1074:        value *= pow(base, (double)exponent);
                   1075:     }
                   1076:   if (isNegative)
                   1077:     value = -value;
                   1078: 
                   1079:   if (endp)
                   1080:     *endp = (char *)source;
                   1081:   return value;
                   1082: #endif
                   1083: }
                   1084: 
                   1085: 
                   1086: /**
                   1087:    Convert string to floating-point number.
                   1088: 
                   1089:    @param source String to be converted.
                   1090:    @param endp Pointer to end of the converted string.
                   1091:    @return A floating-point number.
                   1092: 
                   1093:    See @ref trio_to_long_double.
                   1094: */
                   1095: TRIO_STRING_PUBLIC double
                   1096: trio_to_double
                   1097: TRIO_ARGS2((source, endp),
                   1098:           TRIO_CONST char *source,
                   1099:           char **endp)
                   1100: {
                   1101: #if defined(USE_STRTOD)
                   1102:   return strtod(source, endp);
                   1103: #else
                   1104:   return (double)trio_to_long_double(source, endp);
                   1105: #endif
                   1106: }
                   1107: 
                   1108: #if !defined(TRIO_MINIMAL)
                   1109: /**
                   1110:    Convert string to floating-point number.
                   1111: 
                   1112:    @param source String to be converted.
                   1113:    @param endp Pointer to end of the converted string.
                   1114:    @return A floating-point number.
                   1115: 
                   1116:    See @ref trio_to_long_double.
                   1117: */
                   1118: TRIO_STRING_PUBLIC float
                   1119: trio_to_float
                   1120: TRIO_ARGS2((source, endp),
                   1121:           TRIO_CONST char *source,
                   1122:           char **endp)
                   1123: {
                   1124: #if defined(USE_STRTOF)
                   1125:   return strtof(source, endp);
                   1126: #else
                   1127:   return (float)trio_to_long_double(source, endp);
                   1128: #endif
                   1129: }
                   1130: #endif /* !defined(TRIO_MINIMAL) */
                   1131: 
                   1132: 
                   1133: /**
                   1134:    Convert string to signed integer.
                   1135: 
                   1136:    @param string String to be converted.
                   1137:    @param endp Pointer to end of converted string.
                   1138:    @param base Radix number of number.
                   1139: */
                   1140: TRIO_STRING_PUBLIC long
                   1141: trio_to_long
                   1142: TRIO_ARGS3((string, endp, base),
                   1143:           TRIO_CONST char *string,
                   1144:           char **endp,
                   1145:           int base)
                   1146: {
                   1147:   assert(string);
                   1148:   assert((base >= 2) && (base <= 36));
1.1.1.2 ! misho    1149: 
1.1       misho    1150:   return strtol(string, endp, base);
                   1151: }
                   1152: 
                   1153: 
                   1154: #if !defined(TRIO_MINIMAL)
                   1155: /**
                   1156:    Convert one alphabetic letter to lower-case.
                   1157: 
                   1158:    @param source The letter to be converted.
                   1159:    @return The converted letter.
                   1160: */
                   1161: TRIO_STRING_PUBLIC int
                   1162: trio_to_lower
                   1163: TRIO_ARGS1((source),
                   1164:           int source)
                   1165: {
                   1166: #if defined(USE_TOLOWER)
1.1.1.2 ! misho    1167: 
1.1       misho    1168:   return tolower(source);
1.1.1.2 ! misho    1169: 
1.1       misho    1170: #else
                   1171: 
                   1172:   /* Does not handle locales or non-contiguous alphabetic characters */
                   1173:   return ((source >= (int)'A') && (source <= (int)'Z'))
                   1174:     ? source - 'A' + 'a'
                   1175:     : source;
1.1.1.2 ! misho    1176: 
1.1       misho    1177: #endif
                   1178: }
                   1179: #endif /* !defined(TRIO_MINIMAL) */
                   1180: 
                   1181: #if !defined(TRIO_MINIMAL)
                   1182: /**
                   1183:    Convert string to unsigned integer.
                   1184: 
                   1185:    @param string String to be converted.
                   1186:    @param endp Pointer to end of converted string.
                   1187:    @param base Radix number of number.
                   1188: */
                   1189: TRIO_STRING_PUBLIC unsigned long
                   1190: trio_to_unsigned_long
                   1191: TRIO_ARGS3((string, endp, base),
                   1192:           TRIO_CONST char *string,
                   1193:           char **endp,
                   1194:           int base)
                   1195: {
                   1196:   assert(string);
                   1197:   assert((base >= 2) && (base <= 36));
1.1.1.2 ! misho    1198: 
1.1       misho    1199:   return strtoul(string, endp, base);
                   1200: }
                   1201: #endif /* !defined(TRIO_MINIMAL) */
                   1202: 
                   1203: 
                   1204: /**
                   1205:    Convert one alphabetic letter to upper-case.
                   1206: 
                   1207:    @param source The letter to be converted.
                   1208:    @return The converted letter.
                   1209: */
                   1210: TRIO_STRING_PUBLIC int
                   1211: trio_to_upper
                   1212: TRIO_ARGS1((source),
                   1213:           int source)
                   1214: {
                   1215: #if defined(USE_TOUPPER)
1.1.1.2 ! misho    1216: 
1.1       misho    1217:   return toupper(source);
1.1.1.2 ! misho    1218: 
1.1       misho    1219: #else
                   1220: 
                   1221:   /* Does not handle locales or non-contiguous alphabetic characters */
                   1222:   return ((source >= (int)'a') && (source <= (int)'z'))
                   1223:     ? source - 'a' + 'A'
                   1224:     : source;
1.1.1.2 ! misho    1225: 
1.1       misho    1226: #endif
                   1227: }
                   1228: 
                   1229: #if !defined(TRIO_MINIMAL)
                   1230: /**
                   1231:    Convert the alphabetic letters in the string to upper-case.
                   1232: 
                   1233:    @param target The string to be converted.
                   1234:    @return The number of processed characters (converted or not).
                   1235: */
                   1236: TRIO_STRING_PUBLIC int
                   1237: trio_upper
                   1238: TRIO_ARGS1((target),
                   1239:           char *target)
                   1240: {
                   1241:   assert(target);
                   1242: 
                   1243:   return trio_span_function(target, target, trio_to_upper);
                   1244: }
                   1245: #endif /* !defined(TRIO_MINIMAL) */
                   1246: 
                   1247: 
                   1248: /** @} End of StaticStrings */
                   1249: 
                   1250: 
                   1251: /*************************************************************************
                   1252:  * Dynamic String Functions
                   1253:  */
                   1254: 
                   1255: #if defined(TRIO_DOCUMENTATION)
                   1256: # include "doc/doc_dynamic.h"
                   1257: #endif
                   1258: /** @addtogroup DynamicStrings
                   1259:     @{
                   1260: */
                   1261: 
                   1262: /*
                   1263:  * TrioStringAlloc
                   1264:  */
                   1265: TRIO_STRING_PRIVATE trio_string_t *
                   1266: TrioStringAlloc(TRIO_NOARGS)
                   1267: {
                   1268:   trio_string_t *self;
1.1.1.2 ! misho    1269: 
1.1       misho    1270:   self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
                   1271:   if (self)
                   1272:     {
                   1273:       self->content = NULL;
                   1274:       self->length = 0;
                   1275:       self->allocated = 0;
                   1276:     }
                   1277:   return self;
                   1278: }
                   1279: 
                   1280: 
                   1281: /*
                   1282:  * TrioStringGrow
                   1283:  *
                   1284:  * The size of the string will be increased by 'delta' characters. If
                   1285:  * 'delta' is zero, the size will be doubled.
                   1286:  */
                   1287: TRIO_STRING_PRIVATE BOOLEAN_T
                   1288: TrioStringGrow
                   1289: TRIO_ARGS2((self, delta),
                   1290:           trio_string_t *self,
                   1291:           size_t delta)
                   1292: {
                   1293:   BOOLEAN_T status = FALSE;
                   1294:   char *new_content;
                   1295:   size_t new_size;
                   1296: 
                   1297:   new_size = (delta == 0)
                   1298:     ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
                   1299:     : self->allocated + delta;
1.1.1.2 ! misho    1300: 
1.1       misho    1301:   new_content = (char *)TRIO_REALLOC(self->content, new_size);
                   1302:   if (new_content)
                   1303:     {
                   1304:       self->content = new_content;
                   1305:       self->allocated = new_size;
                   1306:       status = TRUE;
                   1307:     }
                   1308:   return status;
                   1309: }
                   1310: 
                   1311: 
                   1312: #if !defined(TRIO_MINIMAL)
                   1313: /*
                   1314:  * TrioStringGrowTo
                   1315:  *
                   1316:  * The size of the string will be increased to 'length' plus one characters.
                   1317:  * If 'length' is less than the original size, the original size will be
                   1318:  * used (that is, the size of the string is never decreased).
                   1319:  */
                   1320: TRIO_STRING_PRIVATE BOOLEAN_T
                   1321: TrioStringGrowTo
                   1322: TRIO_ARGS2((self, length),
                   1323:           trio_string_t *self,
                   1324:           size_t length)
                   1325: {
                   1326:   length++; /* Room for terminating zero */
                   1327:   return (self->allocated < length)
                   1328:     ? TrioStringGrow(self, length - self->allocated)
                   1329:     : TRUE;
                   1330: }
                   1331: #endif /* !defined(TRIO_MINIMAL) */
                   1332: 
                   1333: 
                   1334: #if !defined(TRIO_MINIMAL)
                   1335: /**
                   1336:    Create a new dynamic string.
1.1.1.2 ! misho    1337: 
1.1       misho    1338:    @param initial_size Initial size of the buffer.
                   1339:    @return Newly allocated dynamic string, or NULL if memory allocation failed.
                   1340: */
                   1341: TRIO_STRING_PUBLIC trio_string_t *
                   1342: trio_string_create
                   1343: TRIO_ARGS1((initial_size),
                   1344:           int initial_size)
                   1345: {
                   1346:   trio_string_t *self;
                   1347: 
                   1348:   self = TrioStringAlloc();
                   1349:   if (self)
                   1350:     {
                   1351:       if (TrioStringGrow(self,
                   1352:                         (size_t)((initial_size > 0) ? initial_size : 1)))
                   1353:        {
                   1354:          self->content[0] = (char)0;
                   1355:          self->allocated = initial_size;
                   1356:        }
                   1357:       else
                   1358:        {
                   1359:          trio_string_destroy(self);
                   1360:          self = NULL;
                   1361:        }
                   1362:     }
                   1363:   return self;
                   1364: }
                   1365: #endif /* !defined(TRIO_MINIMAL) */
                   1366: 
                   1367: 
                   1368: /**
                   1369:    Deallocate the dynamic string and its contents.
1.1.1.2 ! misho    1370: 
1.1       misho    1371:    @param self Dynamic string
                   1372: */
                   1373: TRIO_STRING_PUBLIC void
                   1374: trio_string_destroy
                   1375: TRIO_ARGS1((self),
                   1376:           trio_string_t *self)
                   1377: {
                   1378:   assert(self);
1.1.1.2 ! misho    1379: 
1.1       misho    1380:   if (self)
                   1381:     {
                   1382:       trio_destroy(self->content);
                   1383:       TRIO_FREE(self);
                   1384:     }
                   1385: }
                   1386: 
                   1387: 
                   1388: #if !defined(TRIO_MINIMAL)
                   1389: /**
                   1390:    Get a pointer to the content.
1.1.1.2 ! misho    1391: 
1.1       misho    1392:    @param self Dynamic string.
                   1393:    @param offset Offset into content.
                   1394:    @return Pointer to the content.
1.1.1.2 ! misho    1395: 
1.1       misho    1396:    @p Offset can be zero, positive, or negative. If @p offset is zero,
                   1397:    then the start of the content will be returned. If @p offset is positive,
                   1398:    then a pointer to @p offset number of characters from the beginning of the
                   1399:    content is returned. If @p offset is negative, then a pointer to @p offset
                   1400:    number of characters from the ending of the string, starting at the
                   1401:    terminating zero, is returned.
                   1402: */
                   1403: TRIO_STRING_PUBLIC char *
                   1404: trio_string_get
                   1405: TRIO_ARGS2((self, offset),
                   1406:           trio_string_t *self,
                   1407:           int offset)
                   1408: {
                   1409:   char *result = NULL;
1.1.1.2 ! misho    1410: 
1.1       misho    1411:   assert(self);
                   1412: 
                   1413:   if (self->content != NULL)
                   1414:     {
                   1415:       if (self->length == 0)
                   1416:        {
                   1417:          (void)trio_string_length(self);
                   1418:        }
                   1419:       if (offset >= 0)
                   1420:        {
                   1421:          if (offset > (int)self->length)
                   1422:            {
                   1423:              offset = self->length;
                   1424:            }
                   1425:        }
                   1426:       else
                   1427:        {
                   1428:          offset += self->length + 1;
                   1429:          if (offset < 0)
                   1430:            {
                   1431:              offset = 0;
                   1432:            }
                   1433:        }
                   1434:       result = &(self->content[offset]);
                   1435:     }
                   1436:   return result;
                   1437: }
                   1438: #endif /* !defined(TRIO_MINIMAL) */
                   1439: 
                   1440: 
                   1441: /**
                   1442:    Extract the content.
1.1.1.2 ! misho    1443: 
1.1       misho    1444:    @param self Dynamic String
                   1445:    @return Content of dynamic string.
1.1.1.2 ! misho    1446: 
1.1       misho    1447:    The content is removed from the dynamic string. This enables destruction
                   1448:    of the dynamic string without deallocation of the content.
                   1449: */
                   1450: TRIO_STRING_PUBLIC char *
                   1451: trio_string_extract
                   1452: TRIO_ARGS1((self),
                   1453:           trio_string_t *self)
                   1454: {
                   1455:   char *result;
1.1.1.2 ! misho    1456: 
1.1       misho    1457:   assert(self);
                   1458: 
                   1459:   result = self->content;
                   1460:   /* FIXME: Allocate new empty buffer? */
                   1461:   self->content = NULL;
                   1462:   self->length = self->allocated = 0;
                   1463:   return result;
                   1464: }
                   1465: 
                   1466: 
                   1467: #if !defined(TRIO_MINIMAL)
                   1468: /**
                   1469:    Set the content of the dynamic string.
1.1.1.2 ! misho    1470: 
1.1       misho    1471:    @param self Dynamic String
                   1472:    @param buffer The new content.
1.1.1.2 ! misho    1473: 
1.1       misho    1474:    Sets the content of the dynamic string to a copy @p buffer.
                   1475:    An existing content will be deallocated first, if necessary.
1.1.1.2 ! misho    1476: 
1.1       misho    1477:    @remark
                   1478:    This function will make a copy of @p buffer.
                   1479:    You are responsible for deallocating @p buffer yourself.
                   1480: */
                   1481: TRIO_STRING_PUBLIC void
                   1482: trio_xstring_set
                   1483: TRIO_ARGS2((self, buffer),
                   1484:           trio_string_t *self,
                   1485:           char *buffer)
                   1486: {
                   1487:   assert(self);
                   1488: 
                   1489:   trio_destroy(self->content);
                   1490:   self->content = trio_duplicate(buffer);
                   1491: }
                   1492: #endif /* !defined(TRIO_MINIMAL) */
                   1493: 
                   1494: 
                   1495: /*
                   1496:  * trio_string_size
                   1497:  */
                   1498: TRIO_STRING_PUBLIC int
                   1499: trio_string_size
                   1500: TRIO_ARGS1((self),
                   1501:           trio_string_t *self)
                   1502: {
                   1503:   assert(self);
                   1504: 
                   1505:   return self->allocated;
                   1506: }
                   1507: 
                   1508: 
                   1509: /*
                   1510:  * trio_string_terminate
                   1511:  */
                   1512: TRIO_STRING_PUBLIC void
                   1513: trio_string_terminate
                   1514: TRIO_ARGS1((self),
                   1515:           trio_string_t *self)
                   1516: {
                   1517:   trio_xstring_append_char(self, 0);
                   1518: }
                   1519: 
                   1520: 
                   1521: #if !defined(TRIO_MINIMAL)
                   1522: /**
                   1523:    Append the second string to the first.
1.1.1.2 ! misho    1524: 
1.1       misho    1525:    @param self Dynamic string to be modified.
                   1526:    @param other Dynamic string to copy from.
                   1527:    @return Boolean value indicating success or failure.
                   1528: */
                   1529: TRIO_STRING_PUBLIC int
                   1530: trio_string_append
                   1531: TRIO_ARGS2((self, other),
                   1532:           trio_string_t *self,
                   1533:           trio_string_t *other)
                   1534: {
                   1535:   size_t length;
1.1.1.2 ! misho    1536: 
1.1       misho    1537:   assert(self);
                   1538:   assert(other);
                   1539: 
                   1540:   length = self->length + other->length;
                   1541:   if (!TrioStringGrowTo(self, length))
                   1542:     goto error;
                   1543:   trio_copy(&self->content[self->length], other->content);
                   1544:   self->length = length;
                   1545:   return TRUE;
1.1.1.2 ! misho    1546: 
1.1       misho    1547:  error:
                   1548:   return FALSE;
                   1549: }
                   1550: #endif /* !defined(TRIO_MINIMAL) */
                   1551: 
                   1552: 
                   1553: #if !defined(TRIO_MINIMAL)
                   1554: /*
                   1555:  * trio_xstring_append
                   1556:  */
                   1557: TRIO_STRING_PUBLIC int
                   1558: trio_xstring_append
                   1559: TRIO_ARGS2((self, other),
                   1560:           trio_string_t *self,
                   1561:           TRIO_CONST char *other)
                   1562: {
                   1563:   size_t length;
1.1.1.2 ! misho    1564: 
1.1       misho    1565:   assert(self);
                   1566:   assert(other);
                   1567: 
                   1568:   length = self->length + trio_length(other);
                   1569:   if (!TrioStringGrowTo(self, length))
                   1570:     goto error;
                   1571:   trio_copy(&self->content[self->length], other);
                   1572:   self->length = length;
                   1573:   return TRUE;
1.1.1.2 ! misho    1574: 
1.1       misho    1575:  error:
                   1576:   return FALSE;
                   1577: }
                   1578: #endif /* !defined(TRIO_MINIMAL) */
                   1579: 
                   1580: 
                   1581: /*
                   1582:  * trio_xstring_append_char
                   1583:  */
                   1584: TRIO_STRING_PUBLIC int
                   1585: trio_xstring_append_char
                   1586: TRIO_ARGS2((self, character),
                   1587:           trio_string_t *self,
                   1588:           char character)
                   1589: {
                   1590:   assert(self);
                   1591: 
                   1592:   if ((int)self->length >= trio_string_size(self))
                   1593:     {
                   1594:       if (!TrioStringGrow(self, 0))
                   1595:        goto error;
                   1596:     }
                   1597:   self->content[self->length] = character;
                   1598:   self->length++;
                   1599:   return TRUE;
1.1.1.2 ! misho    1600: 
1.1       misho    1601:  error:
                   1602:   return FALSE;
                   1603: }
                   1604: 
                   1605: 
                   1606: #if !defined(TRIO_MINIMAL)
                   1607: /**
                   1608:    Search for the first occurrence of second parameter in the first.
1.1.1.2 ! misho    1609: 
1.1       misho    1610:    @param self Dynamic string to be modified.
                   1611:    @param other Dynamic string to copy from.
                   1612:    @return Boolean value indicating success or failure.
                   1613: */
                   1614: TRIO_STRING_PUBLIC int
                   1615: trio_string_contains
                   1616: TRIO_ARGS2((self, other),
                   1617:           trio_string_t *self,
                   1618:           trio_string_t *other)
                   1619: {
                   1620:   assert(self);
                   1621:   assert(other);
                   1622: 
                   1623:   return trio_contains(self->content, other->content);
                   1624: }
                   1625: #endif /* !defined(TRIO_MINIMAL) */
                   1626: 
                   1627: 
                   1628: #if !defined(TRIO_MINIMAL)
                   1629: /*
                   1630:  * trio_xstring_contains
                   1631:  */
                   1632: TRIO_STRING_PUBLIC int
                   1633: trio_xstring_contains
                   1634: TRIO_ARGS2((self, other),
                   1635:           trio_string_t *self,
                   1636:           TRIO_CONST char *other)
                   1637: {
                   1638:   assert(self);
                   1639:   assert(other);
                   1640: 
                   1641:   return trio_contains(self->content, other);
                   1642: }
                   1643: #endif /* !defined(TRIO_MINIMAL) */
                   1644: 
                   1645: 
                   1646: #if !defined(TRIO_MINIMAL)
                   1647: /*
                   1648:  * trio_string_copy
                   1649:  */
                   1650: TRIO_STRING_PUBLIC int
                   1651: trio_string_copy
                   1652: TRIO_ARGS2((self, other),
                   1653:           trio_string_t *self,
                   1654:           trio_string_t *other)
                   1655: {
                   1656:   assert(self);
                   1657:   assert(other);
                   1658: 
                   1659:   self->length = 0;
                   1660:   return trio_string_append(self, other);
                   1661: }
                   1662: #endif /* !defined(TRIO_MINIMAL) */
                   1663: 
                   1664: 
                   1665: #if !defined(TRIO_MINIMAL)
                   1666: /*
                   1667:  * trio_xstring_copy
                   1668:  */
                   1669: TRIO_STRING_PUBLIC int
                   1670: trio_xstring_copy
                   1671: TRIO_ARGS2((self, other),
                   1672:           trio_string_t *self,
                   1673:           TRIO_CONST char *other)
                   1674: {
                   1675:   assert(self);
                   1676:   assert(other);
                   1677: 
                   1678:   self->length = 0;
                   1679:   return trio_xstring_append(self, other);
                   1680: }
                   1681: #endif /* !defined(TRIO_MINIMAL) */
                   1682: 
                   1683: 
                   1684: #if !defined(TRIO_MINIMAL)
                   1685: /*
                   1686:  * trio_string_duplicate
                   1687:  */
                   1688: TRIO_STRING_PUBLIC trio_string_t *
                   1689: trio_string_duplicate
                   1690: TRIO_ARGS1((other),
                   1691:           trio_string_t *other)
                   1692: {
                   1693:   trio_string_t *self;
1.1.1.2 ! misho    1694: 
1.1       misho    1695:   assert(other);
                   1696: 
                   1697:   self = TrioStringAlloc();
                   1698:   if (self)
                   1699:     {
                   1700:       self->content = TrioDuplicateMax(other->content, other->length);
                   1701:       if (self->content)
                   1702:        {
                   1703:          self->length = other->length;
                   1704:          self->allocated = self->length + 1;
                   1705:        }
                   1706:       else
                   1707:        {
                   1708:          self->length = self->allocated = 0;
                   1709:        }
                   1710:     }
                   1711:   return self;
                   1712: }
                   1713: #endif /* !defined(TRIO_MINIMAL) */
                   1714: 
                   1715: 
                   1716: /*
                   1717:  * trio_xstring_duplicate
                   1718:  */
                   1719: TRIO_STRING_PUBLIC trio_string_t *
                   1720: trio_xstring_duplicate
                   1721: TRIO_ARGS1((other),
                   1722:           TRIO_CONST char *other)
                   1723: {
                   1724:   trio_string_t *self;
1.1.1.2 ! misho    1725: 
1.1       misho    1726:   assert(other);
                   1727: 
                   1728:   self = TrioStringAlloc();
                   1729:   if (self)
                   1730:     {
                   1731:       self->content = TrioDuplicateMax(other, trio_length(other));
                   1732:       if (self->content)
                   1733:        {
                   1734:          self->length = trio_length(self->content);
                   1735:          self->allocated = self->length + 1;
                   1736:        }
                   1737:       else
                   1738:        {
                   1739:          self->length = self->allocated = 0;
                   1740:        }
                   1741:     }
                   1742:   return self;
                   1743: }
                   1744: 
                   1745: 
                   1746: #if !defined(TRIO_MINIMAL)
                   1747: /*
                   1748:  * trio_string_equal
                   1749:  */
                   1750: TRIO_STRING_PUBLIC int
                   1751: trio_string_equal
                   1752: TRIO_ARGS2((self, other),
                   1753:           trio_string_t *self,
                   1754:           trio_string_t *other)
                   1755: {
                   1756:   assert(self);
                   1757:   assert(other);
                   1758: 
                   1759:   return trio_equal(self->content, other->content);
                   1760: }
                   1761: #endif /* !defined(TRIO_MINIMAL) */
                   1762: 
                   1763: 
                   1764: #if !defined(TRIO_MINIMAL)
                   1765: /*
                   1766:  * trio_xstring_equal
                   1767:  */
                   1768: TRIO_STRING_PUBLIC int
                   1769: trio_xstring_equal
                   1770: TRIO_ARGS2((self, other),
                   1771:           trio_string_t *self,
                   1772:           TRIO_CONST char *other)
                   1773: {
                   1774:   assert(self);
                   1775:   assert(other);
                   1776: 
                   1777:   return trio_equal(self->content, other);
                   1778: }
                   1779: #endif /* !defined(TRIO_MINIMAL) */
                   1780: 
                   1781: 
                   1782: #if !defined(TRIO_MINIMAL)
                   1783: /*
                   1784:  * trio_string_equal_max
                   1785:  */
                   1786: TRIO_STRING_PUBLIC int
                   1787: trio_string_equal_max
                   1788: TRIO_ARGS3((self, max, other),
                   1789:           trio_string_t *self,
                   1790:           size_t max,
                   1791:           trio_string_t *other)
                   1792: {
                   1793:   assert(self);
                   1794:   assert(other);
                   1795: 
                   1796:   return trio_equal_max(self->content, max, other->content);
                   1797: }
                   1798: #endif /* !defined(TRIO_MINIMAL) */
                   1799: 
                   1800: 
                   1801: #if !defined(TRIO_MINIMAL)
                   1802: /*
                   1803:  * trio_xstring_equal_max
                   1804:  */
                   1805: TRIO_STRING_PUBLIC int
                   1806: trio_xstring_equal_max
                   1807: TRIO_ARGS3((self, max, other),
                   1808:           trio_string_t *self,
                   1809:           size_t max,
                   1810:           TRIO_CONST char *other)
                   1811: {
                   1812:   assert(self);
                   1813:   assert(other);
                   1814: 
                   1815:   return trio_equal_max(self->content, max, other);
                   1816: }
                   1817: #endif /* !defined(TRIO_MINIMAL) */
                   1818: 
                   1819: 
                   1820: #if !defined(TRIO_MINIMAL)
                   1821: /*
                   1822:  * trio_string_equal_case
                   1823:  */
                   1824: TRIO_STRING_PUBLIC int
                   1825: trio_string_equal_case
                   1826: TRIO_ARGS2((self, other),
                   1827:           trio_string_t *self,
                   1828:           trio_string_t *other)
                   1829: {
                   1830:   assert(self);
                   1831:   assert(other);
                   1832: 
                   1833:   return trio_equal_case(self->content, other->content);
                   1834: }
                   1835: #endif /* !defined(TRIO_MINIMAL) */
                   1836: 
                   1837: 
                   1838: #if !defined(TRIO_MINIMAL)
                   1839: /*
                   1840:  * trio_xstring_equal_case
                   1841:  */
                   1842: TRIO_STRING_PUBLIC int
                   1843: trio_xstring_equal_case
                   1844: TRIO_ARGS2((self, other),
                   1845:           trio_string_t *self,
                   1846:           TRIO_CONST char *other)
                   1847: {
                   1848:   assert(self);
                   1849:   assert(other);
                   1850: 
                   1851:   return trio_equal_case(self->content, other);
                   1852: }
                   1853: #endif /* !defined(TRIO_MINIMAL) */
                   1854: 
                   1855: 
                   1856: #if !defined(TRIO_MINIMAL)
                   1857: /*
                   1858:  * trio_string_equal_case_max
                   1859:  */
                   1860: TRIO_STRING_PUBLIC int
                   1861: trio_string_equal_case_max
                   1862: TRIO_ARGS3((self, max, other),
                   1863:           trio_string_t *self,
                   1864:           size_t max,
                   1865:           trio_string_t *other)
                   1866: {
                   1867:   assert(self);
                   1868:   assert(other);
                   1869: 
                   1870:   return trio_equal_case_max(self->content, max, other->content);
                   1871: }
                   1872: #endif /* !defined(TRIO_MINIMAL) */
                   1873: 
                   1874: 
                   1875: #if !defined(TRIO_MINIMAL)
                   1876: /*
                   1877:  * trio_xstring_equal_case_max
                   1878:  */
                   1879: TRIO_STRING_PUBLIC int
                   1880: trio_xstring_equal_case_max
                   1881: TRIO_ARGS3((self, max, other),
                   1882:           trio_string_t *self,
                   1883:           size_t max,
                   1884:           TRIO_CONST char *other)
                   1885: {
                   1886:   assert(self);
                   1887:   assert(other);
                   1888: 
                   1889:   return trio_equal_case_max(self->content, max, other);
                   1890: }
                   1891: #endif /* !defined(TRIO_MINIMAL) */
                   1892: 
                   1893: 
                   1894: #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
                   1895: /*
                   1896:  * trio_string_format_data_max
                   1897:  */
                   1898: TRIO_STRING_PUBLIC size_t
                   1899: trio_string_format_date_max
                   1900: TRIO_ARGS4((self, max, format, datetime),
                   1901:           trio_string_t *self,
                   1902:           size_t max,
                   1903:           TRIO_CONST char *format,
                   1904:           TRIO_CONST struct tm *datetime)
                   1905: {
                   1906:   assert(self);
                   1907: 
                   1908:   return trio_format_date_max(self->content, max, format, datetime);
                   1909: }
                   1910: #endif /* !defined(TRIO_MINIMAL) */
                   1911: 
                   1912: 
                   1913: #if !defined(TRIO_MINIMAL)
                   1914: /*
                   1915:  * trio_string_index
                   1916:  */
                   1917: TRIO_STRING_PUBLIC char *
                   1918: trio_string_index
                   1919: TRIO_ARGS2((self, character),
                   1920:           trio_string_t *self,
                   1921:           int character)
                   1922: {
                   1923:   assert(self);
                   1924: 
                   1925:   return trio_index(self->content, character);
                   1926: }
                   1927: #endif /* !defined(TRIO_MINIMAL) */
                   1928: 
                   1929: 
                   1930: #if !defined(TRIO_MINIMAL)
                   1931: /*
                   1932:  * trio_string_index_last
                   1933:  */
                   1934: TRIO_STRING_PUBLIC char *
                   1935: trio_string_index_last
                   1936: TRIO_ARGS2((self, character),
                   1937:           trio_string_t *self,
                   1938:           int character)
                   1939: {
                   1940:   assert(self);
                   1941: 
                   1942:   return trio_index_last(self->content, character);
                   1943: }
                   1944: #endif /* !defined(TRIO_MINIMAL) */
                   1945: 
                   1946: 
                   1947: #if !defined(TRIO_MINIMAL)
                   1948: /*
                   1949:  * trio_string_length
                   1950:  */
                   1951: TRIO_STRING_PUBLIC int
                   1952: trio_string_length
                   1953: TRIO_ARGS1((self),
                   1954:           trio_string_t *self)
                   1955: {
                   1956:   assert(self);
                   1957: 
                   1958:   if (self->length == 0)
                   1959:     {
                   1960:       self->length = trio_length(self->content);
                   1961:     }
                   1962:   return self->length;
                   1963: }
                   1964: #endif /* !defined(TRIO_MINIMAL) */
                   1965: 
                   1966: 
                   1967: #if !defined(TRIO_MINIMAL)
                   1968: /*
                   1969:  * trio_string_lower
                   1970:  */
                   1971: TRIO_STRING_PUBLIC int
                   1972: trio_string_lower
                   1973: TRIO_ARGS1((self),
                   1974:           trio_string_t *self)
                   1975: {
                   1976:   assert(self);
                   1977: 
                   1978:   return trio_lower(self->content);
                   1979: }
                   1980: #endif /* !defined(TRIO_MINIMAL) */
                   1981: 
                   1982: 
                   1983: #if !defined(TRIO_MINIMAL)
                   1984: /*
                   1985:  * trio_string_match
                   1986:  */
                   1987: TRIO_STRING_PUBLIC int
                   1988: trio_string_match
                   1989: TRIO_ARGS2((self, other),
                   1990:           trio_string_t *self,
                   1991:           trio_string_t *other)
                   1992: {
                   1993:   assert(self);
                   1994:   assert(other);
                   1995: 
                   1996:   return trio_match(self->content, other->content);
                   1997: }
                   1998: #endif /* !defined(TRIO_MINIMAL) */
                   1999: 
                   2000: 
                   2001: #if !defined(TRIO_MINIMAL)
                   2002: /*
                   2003:  * trio_xstring_match
                   2004:  */
                   2005: TRIO_STRING_PUBLIC int
                   2006: trio_xstring_match
                   2007: TRIO_ARGS2((self, other),
                   2008:           trio_string_t *self,
                   2009:           TRIO_CONST char *other)
                   2010: {
                   2011:   assert(self);
                   2012:   assert(other);
                   2013: 
                   2014:   return trio_match(self->content, other);
                   2015: }
                   2016: #endif /* !defined(TRIO_MINIMAL) */
                   2017: 
                   2018: 
                   2019: #if !defined(TRIO_MINIMAL)
                   2020: /*
                   2021:  * trio_string_match_case
                   2022:  */
                   2023: TRIO_STRING_PUBLIC int
                   2024: trio_string_match_case
                   2025: TRIO_ARGS2((self, other),
                   2026:           trio_string_t *self,
                   2027:           trio_string_t *other)
                   2028: {
                   2029:   assert(self);
                   2030:   assert(other);
                   2031: 
                   2032:   return trio_match_case(self->content, other->content);
                   2033: }
                   2034: #endif /* !defined(TRIO_MINIMAL) */
                   2035: 
                   2036: 
                   2037: #if !defined(TRIO_MINIMAL)
                   2038: /*
                   2039:  * trio_xstring_match_case
                   2040:  */
                   2041: TRIO_STRING_PUBLIC int
                   2042: trio_xstring_match_case
                   2043: TRIO_ARGS2((self, other),
                   2044:           trio_string_t *self,
                   2045:           TRIO_CONST char *other)
                   2046: {
                   2047:   assert(self);
                   2048:   assert(other);
                   2049: 
                   2050:   return trio_match_case(self->content, other);
                   2051: }
                   2052: #endif /* !defined(TRIO_MINIMAL) */
                   2053: 
                   2054: 
                   2055: #if !defined(TRIO_MINIMAL)
                   2056: /*
                   2057:  * trio_string_substring
                   2058:  */
                   2059: TRIO_STRING_PUBLIC char *
                   2060: trio_string_substring
                   2061: TRIO_ARGS2((self, other),
                   2062:           trio_string_t *self,
                   2063:           trio_string_t *other)
                   2064: {
                   2065:   assert(self);
                   2066:   assert(other);
                   2067: 
                   2068:   return trio_substring(self->content, other->content);
                   2069: }
                   2070: #endif /* !defined(TRIO_MINIMAL) */
                   2071: 
                   2072: 
                   2073: #if !defined(TRIO_MINIMAL)
                   2074: /*
                   2075:  * trio_xstring_substring
                   2076:  */
                   2077: TRIO_STRING_PUBLIC char *
                   2078: trio_xstring_substring
                   2079: TRIO_ARGS2((self, other),
                   2080:           trio_string_t *self,
                   2081:           TRIO_CONST char *other)
                   2082: {
                   2083:   assert(self);
                   2084:   assert(other);
                   2085: 
                   2086:   return trio_substring(self->content, other);
                   2087: }
                   2088: #endif /* !defined(TRIO_MINIMAL) */
                   2089: 
                   2090: 
                   2091: #if !defined(TRIO_MINIMAL)
                   2092: /*
                   2093:  * trio_string_upper
                   2094:  */
                   2095: TRIO_STRING_PUBLIC int
                   2096: trio_string_upper
                   2097: TRIO_ARGS1((self),
                   2098:           trio_string_t *self)
                   2099: {
                   2100:   assert(self);
                   2101: 
                   2102:   return trio_upper(self->content);
                   2103: }
                   2104: #endif /* !defined(TRIO_MINIMAL) */
                   2105: 
                   2106: /** @} End of DynamicStrings */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>