LTP GCOV extension - code coverage report
Current view: directory - src - vstr_fmt.c
Test: Vstr coverage
Date: 2005-01-10 Instrumented lines: 100
Code covered: 100.0 % Executed lines: 100

       1                 : #define VSTR_ADD_FMT_C
       2                 : /*
       3                 :  *  Copyright (C) 2002, 2003, 2004  James Antill
       4                 :  *
       5                 :  *  This library is free software; you can redistribute it and/or
       6                 :  *  modify it under the terms of the GNU Lesser General Public
       7                 :  *  License as published by the Free Software Foundation; either
       8                 :  *  version 2 of the License, or (at your option) any later version.
       9                 :  *
      10                 :  *  This library is distributed in the hope that it will be useful,
      11                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      12                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13                 :  *  Lesser General Public License for more details.
      14                 :  *
      15                 :  *  You should have received a copy of the GNU Lesser General Public
      16                 :  *  License along with this library; if not, write to the Free Software
      17                 :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      18                 :  *
      19                 :  *  email: james@and.org
      20                 :  */
      21                 : /* Registration/deregistration of custom format specifiers */
      22                 : #include "main.h"
      23                 : 
      24                 : 
      25                 : static
      26                 : Vstr__fmt_usr_name_node **
      27                 : vstr__fmt_usr_srch(Vstr_conf *conf, const char *name)
      28          350883 : {
      29          350883 :   Vstr__fmt_usr_name_node **scan = &conf->fmt_usr_names;
      30          350883 :   size_t len = strlen(name);
      31                 : 
      32        16274108 :   while (*scan)
      33                 :   {
      34        16089178 :     assert(!(*scan)->next || ((*scan)->name_len <= (*scan)->next->name_len));
      35                 : 
      36        16089178 :     if (((*scan)->name_len == len) &&
      37                 :         !vstr_wrap_memcmp((*scan)->name_str, name, len))
      38          165953 :       return (scan);
      39                 : 
      40        15923225 :     scan = &(*scan)->next;
      41                 :   }
      42                 : 
      43          184930 :   return (NULL);
      44                 : }
      45                 : 
      46                 : /* like srch, but matches in a format (Ie. not zero terminated) */
      47                 : Vstr__fmt_usr_name_node *vstr__fmt_usr_match(Vstr_conf *conf, const char *fmt)
      48          220465 : {
      49          220465 :   Vstr__fmt_usr_name_node *scan = conf->fmt_usr_names;
      50          220465 :   size_t fmt_max_len = 0;
      51                 : 
      52          220465 :   if (conf->fmt_usr_curly_braces)
      53                 :   { /* we know they follow a format of one of...
      54                 :        "{" [^}]* "}"
      55                 :        "[" [^]]* "]"
      56                 :        "<" [^>]* ">"
      57                 :        "(" [^)]* ")"
      58                 :      * so we can find the length */
      59          195515 :     char *ptr = NULL;
      60          195515 :     size_t len = 0;
      61                 : 
      62          195515 :     switch (*fmt)
      63                 :     {
      64           75743 :       case '{': ptr = strchr(fmt, '}'); break;
      65             270 :       case '[': ptr = strchr(fmt, ']'); break;
      66          119497 :       case '<': ptr = strchr(fmt, '>'); break;
      67               5 :       case '(': ptr = strchr(fmt, ')');
      68               1 :         ASSERT_NO_SWITCH_DEF();
      69                 :     }
      70                 :     
      71          195515 :     if (!ptr)
      72               4 :       return (NULL);
      73                 : 
      74          195511 :     len = (ptr - fmt) + 1;
      75        24140379 :     while (scan)
      76                 :     {
      77        24140375 :       assert(!scan->next || (scan->name_len <= scan->next->name_len));
      78                 : 
      79        24140375 :       if ((scan->name_len == len) &&
      80                 :           !vstr_wrap_memcmp(scan->name_str, fmt, len))
      81          195507 :         break;
      82                 : 
      83        23944868 :       ASSERT_RET(scan->name_len <= len, NULL);
      84                 : 
      85        23944868 :       scan = scan->next;
      86                 :     }
      87                 : 
      88          195511 :     return (scan);
      89                 :   }
      90                 : 
      91           24950 :   if (!conf->fmt_name_max)
      92                 :   {
      93            1021 :     while (scan)
      94                 :     {
      95            1016 :       if (conf->fmt_name_max < scan->name_len)
      96              85 :         conf->fmt_name_max = scan->name_len;
      97                 : 
      98            1016 :       scan = scan->next;
      99                 :     }
     100                 : 
     101               5 :     scan = conf->fmt_usr_names;
     102                 :   }
     103                 : 
     104           24950 :   fmt_max_len = strnlen(fmt, conf->fmt_name_max);
     105         1488546 :   while (scan && (fmt_max_len >= scan->name_len))
     106                 :   {
     107         1483861 :     assert(!scan->next || (scan->name_len <= scan->next->name_len));
     108                 : 
     109         1483861 :     if (!vstr_wrap_memcmp(fmt, scan->name_str, scan->name_len))
     110           20265 :       return (scan);
     111                 : 
     112         1463596 :     scan = scan->next;
     113                 :   }
     114                 : 
     115            4685 :   return (NULL);
     116                 : }
     117                 : 
     118                 : #define VSTR__FMT_ADD_Q(name, len, b1, b2) ( \
     119                 :   ((name)[0] == (b1)) && \
     120                 :   ((name)[(len) - 1] == (b2)) && \
     121                 :   (((len) == 2) || ((len) > 2)) && \
     122                 :   !memchr((name) + 1, (b1), (len) - 2) && \
     123                 :   !memchr((name) + 1, (b2), (len) - 2) \
     124                 :  )
     125                 : 
     126                 : int vstr_fmt_add(Vstr_conf *passed_conf, const char *name,
     127                 :                  int (*func)(Vstr_base *, size_t, Vstr_fmt_spec *), ...)
     128          130851 : {
     129          130851 :   Vstr_conf *conf = passed_conf ? passed_conf : vstr__options.def;
     130          130851 :   Vstr__fmt_usr_name_node **scan = &conf->fmt_usr_names;
     131          130851 :   va_list ap;
     132          130851 :   unsigned int count = 1;
     133          130851 :   unsigned int scan_type = 0;
     134          130851 :   Vstr__fmt_usr_name_node *node = NULL;
     135                 : 
     136          130851 :   if (vstr__fmt_usr_srch(conf, name))
     137               5 :     return (FALSE);
     138                 : 
     139          130846 :   node = VSTR__MK(sizeof(Vstr__fmt_usr_name_node) +
     140                 :                   (sizeof(unsigned int) * count));
     141                 : 
     142          130846 :   if (!node)
     143                 :   {
     144             201 :     conf->malloc_bad = TRUE;
     145             201 :     return (FALSE);
     146                 :   }
     147                 : 
     148          130645 :   node->name_str = name;
     149          130645 :   node->name_len = strlen(name);
     150          130645 :   node->func = func;
     151                 : 
     152          130645 :   if (conf->fmt_usr_curly_braces &&
     153                 :       !VSTR__FMT_ADD_Q(name, node->name_len, '{', '}') &&
     154                 :       !VSTR__FMT_ADD_Q(name, node->name_len, '[', ']') &&
     155                 :       !VSTR__FMT_ADD_Q(name, node->name_len, '<', '>') &&
     156                 :       !VSTR__FMT_ADD_Q(name, node->name_len, '(', ')'))
     157              20 :     conf->fmt_usr_curly_braces = FALSE;
     158                 : 
     159          130645 :   va_start(ap, func);
     160          338694 :   while ((scan_type = va_arg(ap, unsigned int)))
     161                 :   {
     162          208343 :     Vstr__fmt_usr_name_node *tmp_node = NULL;
     163                 : 
     164          208343 :     ++count;
     165          208343 :     if (!VSTR__MV(node, tmp_node, (sizeof(Vstr__fmt_usr_name_node) +
     166                 :                                    (sizeof(unsigned int) * count))))
     167                 :     {
     168             294 :       conf->malloc_bad = TRUE;
     169             294 :       VSTR__F(node);
     170             294 :       va_end(ap);
     171             294 :       return (FALSE);
     172                 :     }
     173                 : 
     174          208049 :     assert(FALSE ||
     175                 :            (scan_type == VSTR_TYPE_FMT_INT) ||
     176                 :            (scan_type == VSTR_TYPE_FMT_UINT) ||
     177                 :            (scan_type == VSTR_TYPE_FMT_LONG) ||
     178                 :            (scan_type == VSTR_TYPE_FMT_ULONG) ||
     179                 :            (scan_type == VSTR_TYPE_FMT_LONG_LONG) ||
     180                 :            (scan_type == VSTR_TYPE_FMT_ULONG_LONG) ||
     181                 :            (scan_type == VSTR_TYPE_FMT_SSIZE_T) ||
     182                 :            (scan_type == VSTR_TYPE_FMT_SIZE_T) ||
     183                 :            (scan_type == VSTR_TYPE_FMT_PTRDIFF_T) ||
     184                 :            (scan_type == VSTR_TYPE_FMT_INTMAX_T) ||
     185                 :            (scan_type == VSTR_TYPE_FMT_UINTMAX_T) ||
     186                 :            (scan_type == VSTR_TYPE_FMT_DOUBLE) ||
     187                 :            (scan_type == VSTR_TYPE_FMT_DOUBLE_LONG) ||
     188                 :            (scan_type == VSTR_TYPE_FMT_PTR_VOID) ||
     189                 :            (scan_type == VSTR_TYPE_FMT_PTR_CHAR) ||
     190                 :            (scan_type == VSTR_TYPE_FMT_PTR_WCHAR_T) ||
     191                 :            (scan_type == VSTR_TYPE_FMT_ERRNO) ||
     192                 :            (scan_type == VSTR_TYPE_FMT_PTR_SIGNED_CHAR) ||
     193                 :            (scan_type == VSTR_TYPE_FMT_PTR_SHORT) ||
     194                 :            (scan_type == VSTR_TYPE_FMT_PTR_INT) ||
     195                 :            (scan_type == VSTR_TYPE_FMT_PTR_LONG) ||
     196                 :            (scan_type == VSTR_TYPE_FMT_PTR_LONG_LONG) ||
     197                 :            (scan_type == VSTR_TYPE_FMT_PTR_SSIZE_T) ||
     198                 :            (scan_type == VSTR_TYPE_FMT_PTR_PTRDIFF_T) ||
     199                 :            (scan_type == VSTR_TYPE_FMT_PTR_INTMAX_T) ||
     200                 :            FALSE);
     201                 : 
     202          208049 :     node->types[count - 2] = scan_type;
     203                 :   }
     204          130351 :   assert(count >= 1);
     205          130351 :   node->types[count - 1] = scan_type;
     206          130351 :   node->sz = count;
     207                 : 
     208          130351 :   va_end(ap);
     209                 : 
     210          130351 :   if (!*scan || (conf->fmt_name_max && (conf->fmt_name_max < node->name_len)))
     211            6334 :     conf->fmt_name_max = node->name_len;
     212                 : 
     213         5301418 :   while (*scan)
     214                 :   {
     215         5295084 :     if ((*scan)->name_len >= node->name_len)
     216          124017 :       break;
     217                 : 
     218         5171067 :     scan = &(*scan)->next;
     219                 :   }
     220                 : 
     221          130351 :   node->next = *scan;
     222          130351 :   *scan = node;
     223                 : 
     224          130351 :   assert(vstr__fmt_usr_srch(conf, name));
     225                 : 
     226          130351 :   return (TRUE);
     227                 : }
     228                 : 
     229                 : void vstr_fmt_del(Vstr_conf *passed_conf, const char *name)
     230          155246 : {
     231          155246 :   Vstr_conf *conf = passed_conf ? passed_conf : vstr__options.def;
     232          155246 :   Vstr__fmt_usr_name_node **scan = vstr__fmt_usr_srch(conf, name);
     233                 : 
     234          155246 :   if (scan)
     235                 :   {
     236          101167 :     Vstr__fmt_usr_name_node *tmp = *scan;
     237                 : 
     238          101167 :     assert(tmp);
     239                 : 
     240          101167 :     *scan = tmp->next;
     241                 : 
     242          101167 :     if (tmp->name_len == conf->fmt_name_max)
     243             792 :       conf->fmt_name_max = 0;
     244                 : 
     245          101167 :     VSTR__F(tmp);
     246                 :   }
     247                 : }
     248                 : 
     249                 : int vstr_fmt_srch(Vstr_conf *passed_conf, const char *name)
     250              65 : {
     251              65 :   Vstr_conf *conf = passed_conf ? passed_conf : vstr__options.def;
     252              65 :   return (!!vstr__fmt_usr_srch(conf, name));
     253                 : }

Generated by: LTP GCOV extension version 1.1