LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/langtag/liblangtag - lt-string.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 80 108 74.1 %
Date: 2012-12-17 Functions: 12 15 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
       2             : /* 
       3             :  * lt-string.c
       4             :  * Copyright (C) 2011-2012 Akira TAGOH
       5             :  * 
       6             :  * Authors:
       7             :  *   Akira TAGOH  <akira@tagoh.org>
       8             :  * 
       9             :  * You may distribute under the terms of either the GNU
      10             :  * Lesser General Public License or the Mozilla Public
      11             :  * License, as specified in the README file.
      12             :  */
      13             : #ifdef HAVE_CONFIG_H
      14             : #include "config.h"
      15             : #endif
      16             : 
      17             : #include <stdlib.h>
      18             : #include <string.h>
      19             : #include "lt-mem.h"
      20             : #include "lt-messages.h"
      21             : #include "lt-utils.h"
      22             : #include "lt-string.h"
      23             : 
      24             : #define LT_STRING_SIZE  128
      25             : 
      26             : /**
      27             :  * SECTION: lt-string
      28             :  * @Short_Description: text buffers which grow automatically as text is added
      29             :  * @Title: Strings
      30             :  *
      31             :  * A #lt_string_t is an object that handles the memory management of a C
      32             :  * string.
      33             :  */
      34             : struct _lt_string_t {
      35             :         lt_mem_t  parent;
      36             :         char     *string;
      37             :         size_t    len;
      38             :         size_t    allocated_len;
      39             : };
      40             : 
      41             : lt_bool_t _lt_string_expand(lt_string_t *string,
      42             :                             size_t       size);
      43             : 
      44             : /*< private >*/
      45             : lt_bool_t
      46           0 : _lt_string_expand(lt_string_t *string,
      47             :                   size_t       size)
      48             : {
      49           0 :         string->allocated_len += LT_ALIGNED_TO_POINTER (size + LT_STRING_SIZE);
      50           0 :         lt_mem_remove_ref(&string->parent, string->string);
      51           0 :         string->string = realloc(string->string, string->allocated_len);
      52           0 :         if (!string->string) {
      53           0 :                 string->len = 0;
      54           0 :                 string->allocated_len = 0;
      55             : 
      56           0 :                 return FALSE;
      57             :         }
      58           0 :         lt_mem_add_ref(&string->parent, string->string, free);
      59             : 
      60           0 :         return TRUE;
      61             : }
      62             : 
      63             : /*< protected >*/
      64             : 
      65             : /*< public >*/
      66             : 
      67             : /**
      68             :  * lt_string_new:
      69             :  * @string: an initial string to set
      70             :  *
      71             :  * Creates an instance of #lt_string_t with @string.
      72             :  *
      73             :  * Returns: a new instance of #lt_string_t.
      74             :  */
      75             : lt_string_t *
      76         170 : lt_string_new(const char *string)
      77             : {
      78         170 :         lt_string_t *retval = lt_mem_alloc_object(sizeof (lt_string_t));
      79             : 
      80         170 :         if (retval) {
      81         170 :                 retval->len = string ? strlen(string) : 0;
      82         170 :                 retval->allocated_len = LT_ALIGNED_TO_POINTER (retval->len + LT_STRING_SIZE);
      83         170 :                 retval->string = malloc(retval->allocated_len);
      84         170 :                 if (!retval->string) {
      85           0 :                         lt_mem_unref(&retval->parent);
      86           0 :                         return NULL;
      87             :                 }
      88         170 :                 if (string)
      89           0 :                         strcpy(retval->string, string);
      90             :                 else
      91         170 :                         retval->string[retval->len] = 0;
      92         170 :                 lt_mem_add_ref(&retval->parent, retval->string, free);
      93             :         }
      94             : 
      95         170 :         return retval;
      96             : }
      97             : 
      98             : /**
      99             :  * lt_string_ref:
     100             :  * @string: a #lt_string_t
     101             :  *
     102             :  * Increases the reference count of @string.
     103             :  *
     104             :  * Returns: (transfer none): the same @string object.
     105             :  */
     106             : lt_string_t *
     107           0 : lt_string_ref(lt_string_t *string)
     108             : {
     109           0 :         lt_return_val_if_fail (string != NULL, NULL);
     110             : 
     111           0 :         return lt_mem_ref(&string->parent);
     112             : }
     113             : 
     114             : /**
     115             :  * lt_string_unref:
     116             :  * @string: a #lt_string_t
     117             :  *
     118             :  * Decreases the reference count of @string. when its reference count
     119             :  * drops to 0, the object is finalized (i.e. its memory is freed).
     120             :  */
     121             : void
     122         170 : lt_string_unref(lt_string_t *string)
     123             : {
     124         170 :         if (string)
     125         170 :                 lt_mem_unref(&string->parent);
     126         170 : }
     127             : 
     128             : /**
     129             :  * lt_string_free:
     130             :  * @string: a #lt_string_t
     131             :  * @free_segment: if %TRUE, the actual character data is freed as well
     132             :  *
     133             :  * Frees the memory allocated for the #lt_string_t.
     134             :  * If @free_segment is %TRUE it also frees the character data.  If
     135             :  * it's %FALSE, the caller gains ownership of the buffer and must
     136             :  * free it after use with free().
     137             :  *
     138             :  * Returns: the character data of @string
     139             :  *          (i.e. %NULL if @free_segment is %TRUE)
     140             :  */
     141             : char *
     142          60 : lt_string_free(lt_string_t *string,
     143             :                lt_bool_t    free_segment)
     144             : {
     145          60 :         char *retval = NULL;
     146             : 
     147          60 :         if (!free_segment) {
     148          60 :                 lt_mem_remove_ref(&string->parent, string->string);
     149          60 :                 retval = string->string;
     150             :         }
     151          60 :         lt_string_unref(string);
     152             : 
     153          60 :         return retval;
     154             : }
     155             : 
     156             : /**
     157             :  * lt_string_length:
     158             :  * @string: a #lt_string_t
     159             :  *
     160             :  * Returns the number of characters in buffer for @string.
     161             :  *
     162             :  * Returns: the number of characters
     163             :  */
     164             : size_t
     165         384 : lt_string_length(const lt_string_t *string)
     166             : {
     167         384 :         lt_return_val_if_fail (string != NULL, 0);
     168             : 
     169         384 :         return string->len;
     170             : }
     171             : 
     172             : /**
     173             :  * lt_string_value:
     174             :  * @string: a #lt_string_t
     175             :  *
     176             :  * Returns the buffer in @string.
     177             :  *
     178             :  * Returns: a string which @string has.
     179             :  */
     180             : const char *
     181          66 : lt_string_value(const lt_string_t *string)
     182             : {
     183          66 :         lt_return_val_if_fail (string != NULL, NULL);
     184             : 
     185          66 :         return string->string;
     186             : }
     187             : 
     188             : /**
     189             :  * lt_string_truncate:
     190             :  * @string: a #lt_string_t
     191             :  * @len: the number of characters to be truncated from the buffer.
     192             :  *
     193             :  * Truncates the characters in the buffer according to @len. if @len is
     194             :  * a negative, how many characters is truncated will be calculated from
     195             :  * current size. i.e. if the buffer contains "abc", and @len is -1,
     196             :  * the buffer will be "ab" after this call.
     197             :  *
     198             :  * Returns: (transfer none): the same @string object.
     199             :  */
     200             : lt_string_t *
     201          24 : lt_string_truncate(lt_string_t *string,
     202             :                    ssize_t      len)
     203             : {
     204          24 :         lt_return_val_if_fail (string != NULL, NULL);
     205             : 
     206          24 :         if (len < 0)
     207           0 :                 len = string->len + len;
     208          24 :         len = LT_MAX (len, 0);
     209          24 :         string->len = LT_MIN (len, string->len);
     210          24 :         string->string[string->len] = 0;
     211             : 
     212          24 :         return string;
     213             : }
     214             : 
     215             : /**
     216             :  * lt_string_clear:
     217             :  * @string: a #lt_string_t
     218             :  *
     219             :  * Clean up the buffer in @string.
     220             :  */
     221             : void
     222          24 : lt_string_clear(lt_string_t *string)
     223             : {
     224          24 :         lt_string_truncate(string, 0);
     225          24 : }
     226             : 
     227             : /**
     228             :  * lt_string_append_c:
     229             :  * @string: a #lt_string_t
     230             :  * @c: the byte to append onto the end of @string
     231             :  *
     232             :  * Adds a byte onto the end of a #lt_string_t, expanding
     233             :  * it if necessary.
     234             :  *
     235             :  * Returns: (transfer none): the same @string object.
     236             :  */
     237             : lt_string_t *
     238         126 : lt_string_append_c(lt_string_t *string,
     239             :                    char         c)
     240             : {
     241         126 :         lt_return_val_if_fail (string != NULL, NULL);
     242             : 
     243         126 :         if ((string->len + 2) >= string->allocated_len) {
     244           0 :                 if (!_lt_string_expand(string, 1))
     245           0 :                         return string;
     246             :         }
     247         126 :         string->string[string->len++] = c;
     248         126 :         string->string[string->len] = 0;
     249             : 
     250         126 :         return string;
     251             : }
     252             : 
     253             : /**
     254             :  * lt_string_append:
     255             :  * @string: a #lt_string_t
     256             :  * @str: the string to append onto the end of @string
     257             :  *
     258             :  * Adds a string onto the end of a #lt_string_t, expanding
     259             :  * it if necessary.
     260             :  *
     261             :  * Returns: (transfer none): the same @string object
     262             :  */
     263             : lt_string_t *
     264         410 : lt_string_append(lt_string_t *string,
     265             :                  const char  *str)
     266             : {
     267             :         size_t len;
     268             : 
     269         410 :         lt_return_val_if_fail (string != NULL, NULL);
     270         410 :         lt_return_val_if_fail (str != NULL, string);
     271             : 
     272         410 :         len = strlen(str);
     273         410 :         if ((string->len + len + 1) >= string->allocated_len) {
     274           0 :                 if (!_lt_string_expand(string, len))
     275           0 :                         return string;
     276             :         }
     277         410 :         strncpy(&string->string[string->len], str, len);
     278         410 :         string->len += len;
     279         410 :         string->string[string->len] = 0;
     280             : 
     281         410 :         return string;
     282             : }
     283             : 
     284             : /**
     285             :  * lt_string_append_filename:
     286             :  * @string: a #lt_string_t
     287             :  * @path: the string to append onto the end of @string as a file path
     288             :  * @...: a %NULL-terminated list of strings to append onto the end of @string as a file path
     289             :  *
     290             :  * Adds a string onto the end of a #lt_string_t as a file path.
     291             :  *
     292             :  * Returns: (transfer none): the same @string object
     293             :  */
     294             : lt_string_t *
     295          52 : lt_string_append_filename(lt_string_t *string,
     296             :                           const char  *path,
     297             :                           ...)
     298             : {
     299             :         va_list ap;
     300             :         const char *p;
     301             : 
     302          52 :         lt_return_val_if_fail (string != NULL, NULL);
     303          52 :         lt_return_val_if_fail (path != NULL, string);
     304             : 
     305             : #ifndef _WIN32
     306          52 :         if (lt_string_length(string) == 0 && path[0] != LT_DIR_SEPARATOR)
     307           0 :                 lt_string_append(string, LT_DIR_SEPARATOR_S);
     308             : #endif
     309             : 
     310          52 :         va_start(ap, path);
     311          52 :         p = path;
     312         304 :         while (p) {
     313         200 :                 if (lt_string_length(string) > 0 && lt_string_at(string, -1) != LT_DIR_SEPARATOR)
     314         148 :                         lt_string_append(string, LT_DIR_SEPARATOR_S);
     315         200 :                 lt_string_append(string, p);
     316         200 :                 p = (const char *)va_arg(ap, const char *);
     317             :         }
     318             : 
     319          52 :         return string;
     320             : }
     321             : 
     322             : /**
     323             :  * lt_string_append_printf:
     324             :  * @string: a #lt_string_t
     325             :  * @format: the string format. See the printf() documentation
     326             :  * @...: the parameters to insert into the format string
     327             :  *
     328             :  * Appends a formatted string onto the end of a #lt_string_t.
     329             :  * This is similar to the standard sprintf() function,
     330             :  * except that the text is appended to the #lt_string_t.
     331             :  */
     332             : void
     333           6 : lt_string_append_printf(lt_string_t *string,
     334             :                         const char  *format,
     335             :                         ...)
     336             : {
     337             :         va_list ap;
     338             :         char *str;
     339             : 
     340           6 :         lt_return_if_fail (string != NULL);
     341           6 :         lt_return_if_fail (format != NULL);
     342             : 
     343           6 :         va_start(ap, format);
     344           6 :         str = lt_strdup_vprintf(format, ap);
     345           6 :         lt_string_append(string, str);
     346           6 :         free(str);
     347             : 
     348           6 :         va_end(ap);
     349             : }
     350             : 
     351             : /**
     352             :  * lt_string_replace_c:
     353             :  * @string: a #lt_string_t
     354             :  * @pos: position in @string where replacement should happen
     355             :  * @c: the byte to replace
     356             :  *
     357             :  * Replaces a character in @string at @pos.
     358             :  *
     359             :  * Returns: (transfer none): the same @string object
     360             :  */
     361             : lt_string_t *
     362           0 : lt_string_replace_c(lt_string_t *string,
     363             :                     size_t       pos,
     364             :                     char         c)
     365             : {
     366           0 :         lt_return_val_if_fail (string != NULL, NULL);
     367           0 :         lt_return_val_if_fail (pos < string->len, string);
     368           0 :         lt_return_val_if_fail (pos > 0, string);
     369             : 
     370           0 :         string->string[pos] = c;
     371             : 
     372           0 :         return string;
     373             : }
     374             : 
     375             : /**
     376             :  * lt_string_at:
     377             :  * @string: a #lt_string_t
     378             :  * @pos: position in @string where to obtain the byte
     379             :  *
     380             :  * Obtain a byte in a #lt_string_t at @pos. If @pos is a negative,
     381             :  * the position is calculated from current size. i.e. if the buffer
     382             :  * contains "abc", and @pos is -1, this will returns 'c' then.
     383             :  *
     384             :  * Returns: the byte in @string at @pos
     385             :  */
     386             : char
     387         148 : lt_string_at(lt_string_t *string,
     388             :              ssize_t      pos)
     389             : {
     390         148 :         lt_return_val_if_fail (string != NULL, 0);
     391             : 
     392         148 :         if (pos < 0)
     393         148 :                 pos = string->len + pos;
     394         148 :         pos = LT_MAX (pos, 0);
     395         148 :         pos = LT_MIN (pos, string->len);
     396             : 
     397         148 :         return string->string[pos];
     398             : }

Generated by: LCOV version 1.10