LTP GCOV extension - code coverage report
Current view: directory - work/ustr - ustr-cntl-code.h
Test: Ustr coverage
Date: 2008-02-26 Instrumented lines: 215
Code covered: 100.0 % Executed lines: 215

       1                 : /* Copyright (c) 2007 James Antill -- See LICENSE file for terms. */
       2                 : 
       3                 : #ifndef USTR_MAIN_H
       4                 : #error " You should have already included ustr-main.h, or just include ustr.h."
       5                 : #endif
       6                 : 
       7                 : /* not sure of the version */
       8                 : #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && (__GNUC__ > 3) && \
       9                 :     USTR_CONF_COMPILE_USE_ATTRIBUTES
      10                 : # define USTR__COMPILE_ATTR_H() __attribute__((visibility("hidden")))
      11                 : #else
      12                 : # define USTR__COMPILE_ATTR_H()
      13                 : #endif
      14                 : 
      15                 : #include <stdarg.h> /* va_list for va_arg() functionality */
      16                 : 
      17                 : /* second set of defaults... *sigh* */
      18                 : struct Ustr_opts USTR__COMPILE_ATTR_H() ustr__opts[1] = {
      19                 :  {1, /* ref bytes */
      20                 :   {ustr__cntl_mc_setup_malloc, /* malloc be called first */
      21                 :    realloc,
      22                 :    free}, /* Ustr_cntl_mem */
      23                 :   {vsnprintf, vsnprintf}, /* fmt */
      24                 :   USTR_FALSE,   /* has_size */
      25                 :   USTR_FALSE,   /* exact_bytes */
      26                 :   USTR_FALSE,   /* scrub on malloc */
      27                 :   USTR_FALSE,   /* scrub on free */
      28                 :   USTR_FALSE    /* scrub on realloc */
      29                 :  }};
      30                 : 
      31                 : /* not namespaced because this must be in a C-file. */
      32                 : #ifndef USE_MALLOC_CHECK
      33                 : #define USE_MALLOC_CHECK 1
      34                 : #endif
      35                 : #define MALLOC_CHECK_API_M_SCRUB ustr__opts->mc_m_scrub
      36                 : #define MALLOC_CHECK_API_F_SCRUB ustr__opts->mc_f_scrub
      37                 : #define MALLOC_CHECK_API_R_SCRUB ustr__opts->mc_r_scrub
      38                 : #define MALLOC_CHECK_SCOPE_EXTERN 0
      39                 : #include "malloc-check.h"
      40                 : 
      41                 : MALLOC_CHECK_DECL();
      42                 : 
      43                 : typedef struct Ustr__cntl_mc_ptrs
      44                 : {
      45                 :  const char *file;
      46                 :  unsigned int line;
      47                 :  const char *func;
      48                 : } Ustr__cntl_mc_ptrs;
      49                 : Ustr__cntl_mc_ptrs USTR__COMPILE_ATTR_H() *ustr__cntl_mc_ptr = 0;
      50                 : size_t             USTR__COMPILE_ATTR_H()  ustr__cntl_mc_num = 0;
      51                 : size_t             USTR__COMPILE_ATTR_H()  ustr__cntl_mc_sz  = 0;
      52                 : 
      53                 : #define USTR__STREQ(x, y) !strcmp(x, y)
      54                 : 
      55                 : USTR_CONF_i_PROTO int   ustr__cntl_mc_setup_env2bool(const char *key, int def)
      56              10 : {
      57              10 :   const char *ptr = getenv(key);
      58                 : 
      59              10 :   if (!ptr)                    return (!!def);
      60                 : 
      61              10 :   if (USTR__STREQ(ptr, "1"))   return (USTR_TRUE);
      62              10 :   if (USTR__STREQ(ptr, "on"))  return (USTR_TRUE);
      63              10 :   if (USTR__STREQ(ptr, "yes")) return (USTR_TRUE);
      64                 : 
      65               8 :   if (USTR__STREQ(ptr, "0"))   return (USTR_FALSE);
      66               8 :   if (USTR__STREQ(ptr, "off")) return (USTR_FALSE);
      67               8 :   if (USTR__STREQ(ptr, "no"))  return (USTR_FALSE);
      68                 : 
      69               1 :                                return (!!def);
      70                 : }
      71                 : 
      72                 : USTR_CONF_i_PROTO void  ustr__cntl_mc_setup_main(void)
      73               4 : {
      74               4 :   int val = 0;
      75                 :   
      76               4 :   if (!ustr__cntl_mc_setup_env2bool("USTR_CNTL_MC", USTR_CONF_USE_ASSERT))
      77                 :   {
      78               2 :     ustr__opts->umem.sys_malloc  = malloc;
      79               2 :     ustr__opts->umem.sys_realloc = realloc;
      80               2 :     ustr__opts->umem.sys_free    = free;
      81                 :     
      82               2 :     return;
      83                 :   }
      84                 : 
      85               2 :   val = ustr__opts->mc_m_scrub;
      86               2 :   val = ustr__cntl_mc_setup_env2bool("USTR_CNTL_MC_M_SCRUB", val);
      87               2 :   ustr__opts->mc_m_scrub = val;
      88                 : 
      89               2 :   val = ustr__opts->mc_f_scrub;
      90               2 :   val = ustr__cntl_mc_setup_env2bool("USTR_CNTL_MC_F_SCRUB", val);
      91               2 :   ustr__opts->mc_f_scrub = val;
      92                 :   
      93               2 :   val = ustr__opts->mc_r_scrub;
      94               2 :   val = ustr__cntl_mc_setup_env2bool("USTR_CNTL_MC_R_SCRUB", val);
      95               2 :   ustr__opts->mc_r_scrub = val;
      96                 : 
      97               2 :   USTR_CNTL_MALLOC_CHECK_BEG(USTR_TRUE);
      98                 : }
      99                 : 
     100                 : USTR_CONF_i_PROTO void *ustr__cntl_mc_setup_malloc(size_t x)
     101               4 : { /* again, it's not possible to call anything but malloc() or free(NULL).
     102                 :    * So just doing setup here is fine. */
     103               4 :   ustr__cntl_mc_setup_main();
     104               4 :   return (ustr__opts->umem.sys_malloc(x));
     105                 : }
     106                 : 
     107                 : USTR_CONF_i_PROTO void *ustr__cntl_mc_malloc(size_t x)
     108            1602 : {
     109            1602 :   struct Ustr__cntl_mc_ptrs *ptr = ustr__cntl_mc_ptr;
     110            1602 :   size_t num = ustr__cntl_mc_num;
     111                 :   
     112            1602 :   return (malloc_check_malloc(x, ptr[num].file, ptr[num].line, ptr[num].func));
     113                 : }
     114                 : USTR_CONF_i_PROTO void *ustr__cntl_mc_realloc(void *p, size_t x)
     115             521 : {
     116             521 :   struct Ustr__cntl_mc_ptrs *ptr = ustr__cntl_mc_ptr;
     117             521 :   size_t num = ustr__cntl_mc_num;
     118                 :   
     119             521 :   return (malloc_check_realloc(p,x, ptr[num].file,ptr[num].line,ptr[num].func));
     120                 : }
     121                 : USTR_CONF_i_PROTO void  ustr__cntl_mc_free(void *x)
     122            1488 : {
     123            1488 :   struct Ustr__cntl_mc_ptrs *ptr = ustr__cntl_mc_ptr;
     124            1488 :   size_t num = ustr__cntl_mc_num;
     125                 :   
     126            1488 :   malloc_check_free(x, ptr[num].file, ptr[num].line, ptr[num].func);
     127            1488 : }
     128                 : 
     129                 : USTR_CONF_I_PROTO int ustr_cntl_opt(int option, ...)
     130          416760 : {
     131          416760 :   int ret = USTR_FALSE;
     132                 :   va_list ap;
     133                 : 
     134          416760 :   va_start(ap, option);
     135                 : 
     136          416760 :   switch (option)
     137                 :   {
     138                 :     case USTR_CNTL_OPT_GET_REF_BYTES:
     139                 :     {
     140              42 :       size_t *val = va_arg(ap, size_t *);
     141                 : 
     142              42 :       *val = ustr__opts->ref_bytes;
     143                 :       
     144              42 :       ret = USTR_TRUE;
     145                 :     }
     146              42 :     break;
     147                 :     
     148                 :     case USTR_CNTL_OPT_SET_REF_BYTES:
     149                 :     {
     150              10 :       size_t rbytes = va_arg(ap, size_t);
     151                 : 
     152              10 :       USTR_ASSERT_RET((rbytes == 0) ||
     153                 :                       (rbytes == 1) || (rbytes == 2) || (rbytes == 4) ||
     154                 :                       (USTR_CONF_HAVE_64bit_SIZE_MAX && (rbytes == 8)),
     155                 :                       USTR_FALSE);
     156                 : 
     157              10 :       ustr__opts->ref_bytes = rbytes;
     158                 :       
     159              10 :       ret = USTR_TRUE;
     160                 :     }
     161              10 :     break;
     162                 : 
     163                 :     case USTR_CNTL_OPT_GET_HAS_SIZE:
     164                 :     {
     165              44 :       int *val = va_arg(ap, int *);
     166                 : 
     167              44 :       *val = ustr__opts->has_size;
     168                 :       
     169              44 :       ret = USTR_TRUE;
     170                 :     }
     171              44 :     break;
     172                 :     
     173                 :     case USTR_CNTL_OPT_SET_HAS_SIZE:
     174                 :     {
     175               6 :       int val = va_arg(ap, int);
     176                 : 
     177               6 :       USTR_ASSERT_RET((val == !!val), USTR_FALSE);
     178                 : 
     179               6 :       ustr__opts->has_size = val;
     180                 :       
     181               6 :       ret = USTR_TRUE;
     182                 :     }
     183               6 :     break;
     184                 : 
     185                 :     case USTR_CNTL_OPT_GET_EXACT_BYTES:
     186                 :     {
     187              44 :       int *val = va_arg(ap, int *);
     188                 : 
     189              44 :       *val = ustr__opts->exact_bytes;
     190                 :       
     191              44 :       ret = USTR_TRUE;
     192                 :     }
     193              44 :     break;
     194                 :     
     195                 :     case USTR_CNTL_OPT_SET_EXACT_BYTES:
     196                 :     {
     197               2 :       int val = va_arg(ap, int);
     198                 : 
     199               2 :       USTR_ASSERT_RET((val == !!val), USTR_FALSE);
     200                 : 
     201               2 :       ustr__opts->exact_bytes = val;
     202                 :       
     203               2 :       ret = USTR_TRUE;
     204                 :     }
     205               2 :     break;
     206                 : 
     207                 :     /* call backs */
     208                 :     
     209                 :     case USTR_CNTL_OPT_GET_MEM:
     210                 :     {
     211               8 :       struct Ustr_cntl_mem *val = va_arg(ap, struct Ustr_cntl_mem *);
     212                 : 
     213               8 :       val->sys_malloc  = ustr__opts->umem.sys_malloc;
     214               8 :       val->sys_realloc = ustr__opts->umem.sys_realloc;
     215               8 :       val->sys_free    = ustr__opts->umem.sys_free;
     216                 :       
     217               8 :       ret = USTR_TRUE;
     218                 :     }
     219               8 :     break;
     220                 :     
     221                 :     case USTR_CNTL_OPT_SET_MEM:
     222                 :     {
     223              44 :       const struct Ustr_cntl_mem *val = va_arg(ap, struct Ustr_cntl_mem *);
     224                 : 
     225              44 :       ustr__opts->umem.sys_malloc  = val->sys_malloc;
     226              44 :       ustr__opts->umem.sys_realloc = val->sys_realloc;
     227              44 :       ustr__opts->umem.sys_free    = val->sys_free;
     228                 :       
     229              44 :       ret = USTR_TRUE;
     230                 :     }
     231              44 :     break;
     232                 : 
     233                 :     case USTR_CNTL_OPT_GET_MC_M_SCRUB:
     234                 :     {
     235               8 :       int *val = va_arg(ap, int *);
     236                 : 
     237               8 :       *val = ustr__opts->mc_m_scrub;
     238                 :       
     239               8 :       ret = USTR_TRUE;
     240                 :     }
     241               8 :     break;
     242                 :     
     243                 :     case USTR_CNTL_OPT_SET_MC_M_SCRUB:
     244                 :     {
     245               2 :       int val = va_arg(ap, int);
     246                 :       
     247               2 :       USTR_ASSERT_RET((val == !!val), USTR_FALSE);
     248                 :       
     249               2 :       ustr__opts->mc_m_scrub = val;
     250                 :       
     251               2 :       ret = USTR_TRUE;
     252                 :     }
     253               2 :     break;
     254                 :     
     255                 :     case USTR_CNTL_OPT_GET_MC_F_SCRUB:
     256                 :     {
     257               8 :       int *val = va_arg(ap, int *);
     258                 : 
     259               8 :       *val = ustr__opts->mc_f_scrub;
     260                 :       
     261               8 :       ret = USTR_TRUE;
     262                 :     }
     263               8 :     break;
     264                 :     
     265                 :     case USTR_CNTL_OPT_SET_MC_F_SCRUB:
     266                 :     {
     267               2 :       int val = va_arg(ap, int);
     268                 :       
     269               2 :       USTR_ASSERT_RET((val == !!val), USTR_FALSE);
     270                 :       
     271               2 :       ustr__opts->mc_f_scrub = val;
     272                 :       
     273               2 :       ret = USTR_TRUE;
     274                 :     }
     275               2 :     break;
     276                 :     
     277                 :     case USTR_CNTL_OPT_GET_MC_R_SCRUB:
     278                 :     {
     279               8 :       int *val = va_arg(ap, int *);
     280                 : 
     281               8 :       *val = ustr__opts->mc_r_scrub;
     282                 :       
     283               8 :       ret = USTR_TRUE;
     284                 :     }
     285               8 :     break;
     286                 :     
     287                 :     case USTR_CNTL_OPT_SET_MC_R_SCRUB:
     288                 :     {
     289               2 :       int val = va_arg(ap, int);
     290                 :       
     291               2 :       USTR_ASSERT_RET((val == !!val), USTR_FALSE);
     292                 :       
     293               2 :       ustr__opts->mc_r_scrub = val;
     294                 :       
     295               2 :       ret = USTR_TRUE;
     296                 :     }
     297               2 :     break;
     298                 :       
     299                 :     case 666:
     300                 :     {
     301          416523 :       unsigned long valT = va_arg(ap, unsigned long);
     302          416523 :       int enabled = !!ustr__cntl_mc_sz;
     303                 : 
     304          416218 :       USTR_ASSERT(ustr__cntl_mc_num <= ustr__cntl_mc_sz);
     305                 :       
     306          416523 :       if (valT == 0x0FFE)
     307                 :       {
     308              46 :         ret = ustr__cntl_mc_num + enabled;
     309              46 :         break;
     310                 :       }
     311                 :       
     312          416477 :       switch (valT)
     313                 :       {
     314                 :         case 0xF0F0:
     315                 :         case 0xF0F1:
     316                 :         case 0x0FF0:
     317                 :         case 0x0FF1:
     318                 :         case 0x0FF2:
     319                 :         case 0x0FF3:
     320                 :         case 0x0FF4:
     321                 :         case 0x0FFF:
     322          416477 :           ret = USTR_TRUE;
     323                 :       }
     324          416195 :       USTR_ASSERT(ret);
     325                 : 
     326          416477 :       if (!enabled && (valT == 0x0FFF))
     327                 :       {
     328               4 :         ret = USTR_FALSE;
     329               4 :         break;
     330                 :       }      
     331          416473 :       if (!enabled && (valT != 0x0FF0))
     332              43 :         break; /* pretend it worked */
     333                 :       
     334          416430 :       switch (valT)
     335                 :       {
     336                 :         case 0xF0F0:
     337                 :         {
     338             218 :           unsigned long valV = va_arg(ap, unsigned long);
     339             218 :           MALLOC_CHECK_FAIL_IN(valV);
     340                 :         }
     341             218 :         break;
     342                 : 
     343                 :         case 0xF0F1:
     344                 :         {
     345              76 :           unsigned long *valV = va_arg(ap, unsigned long *);
     346              76 :           *valV = MALLOC_CHECK_STORE.mem_fail_num;
     347                 :         }
     348              76 :         break;
     349                 :         
     350                 :         case 0x0FF0:
     351                 :         {
     352              52 :           const char  *file = va_arg(ap, char *);
     353              52 :           unsigned int line = va_arg(ap, unsigned int);
     354              52 :           const char  *func = va_arg(ap, char *);
     355              52 :           struct Ustr__cntl_mc_ptrs *tptr = ustr__cntl_mc_ptr;
     356              52 :           size_t tsz = 3;
     357                 : 
     358              52 :           if (!enabled)
     359              44 :             tptr = MC_MALLOC(sizeof(Ustr__cntl_mc_ptrs) * tsz);
     360               8 :           else if (++ustr__cntl_mc_num >= ustr__cntl_mc_sz)
     361                 :           {
     362               4 :             tsz = (ustr__cntl_mc_sz * 2) + 1;
     363               4 :             tptr = MC_REALLOC(tptr, sizeof(Ustr__cntl_mc_ptrs) * tsz);
     364                 :           }
     365                 :           
     366              52 :           if (!tptr)
     367                 :           {
     368               2 :             if (enabled)
     369               2 :               --ustr__cntl_mc_num;
     370               2 :             ret = USTR_FALSE;
     371               2 :             break;
     372                 :           }
     373                 : 
     374              50 :           if (!enabled)
     375                 :           {
     376              44 :             ustr__opts->umem.sys_malloc  = ustr__cntl_mc_malloc;
     377              44 :             ustr__opts->umem.sys_realloc = ustr__cntl_mc_realloc;
     378              44 :             ustr__opts->umem.sys_free    = ustr__cntl_mc_free;
     379                 :           }
     380                 :           
     381              50 :           ustr__cntl_mc_ptr = tptr;
     382              50 :           ustr__cntl_mc_sz  = tsz;
     383                 :           
     384              50 :           ustr__cntl_mc_ptr[ustr__cntl_mc_num].file = file;
     385              50 :           ustr__cntl_mc_ptr[ustr__cntl_mc_num].line = line;
     386              50 :           ustr__cntl_mc_ptr[ustr__cntl_mc_num].func = func;
     387                 :         }
     388              50 :         break;
     389                 : 
     390                 :         case 0x0FF1:
     391                 :         {
     392              82 :           struct Ustr__cntl_mc_ptrs *ptr = ustr__cntl_mc_ptr;
     393              82 :           size_t num = ustr__cntl_mc_num;
     394              82 :           void *valP = va_arg(ap, void *);
     395              82 :           malloc_check_mem(valP, ptr[num].file, ptr[num].line, ptr[num].func);
     396                 :         }
     397              82 :         break;
     398                 : 
     399                 :         case 0x0FF2:
     400                 :         {
     401          415881 :           struct Ustr__cntl_mc_ptrs *ptr = ustr__cntl_mc_ptr;
     402          415881 :           size_t num = ustr__cntl_mc_num;
     403          415881 :           void *valP  = va_arg(ap, void *);
     404          415881 :           size_t valV = va_arg(ap, size_t);
     405          415881 :           malloc_check_mem_sz(valP, valV,
     406                 :                               ptr[num].file, ptr[num].line, ptr[num].func);
     407                 :         }
     408          415881 :         break;
     409                 : 
     410                 :         case 0x0FF3:
     411                 :         {
     412              65 :           struct Ustr__cntl_mc_ptrs *ptr = ustr__cntl_mc_ptr;
     413              65 :           size_t num = ustr__cntl_mc_num;
     414              65 :           void *valP  = va_arg(ap, void *);
     415              65 :           size_t valV = va_arg(ap, size_t);
     416              65 :           malloc_check_mem_minsz(valP, valV,
     417                 :                                  ptr[num].file, ptr[num].line, ptr[num].func);
     418                 :         }
     419              65 :         break;
     420                 : 
     421                 :         case 0x0FF4:
     422                 :         { /* needed for realloc() down doesn't fail */
     423               6 :           struct Ustr__cntl_mc_ptrs *ptr_mc = ustr__cntl_mc_ptr;
     424               6 :           size_t num_mc = ustr__cntl_mc_num;
     425               6 :           void *ptr = va_arg(ap, void *);
     426               6 :           size_t nsz = va_arg(ap, size_t);
     427                 :           unsigned int scan = malloc_check_mem(ptr,
     428                 :                                                ptr_mc[num_mc].file,
     429                 :                                                ptr_mc[num_mc].line,
     430               6 :                                                ptr_mc[num_mc].func);
     431                 : 
     432               6 :           MALLOC_CHECK_STORE.mem_vals[scan].sz = nsz;
     433                 :         }
     434               6 :         break;
     435                 : 
     436                 :         case 0x0FFF:
     437                 :         {
     438              50 :           const char  *file = va_arg(ap, char *);
     439              50 :           unsigned int line = va_arg(ap, unsigned int);
     440              50 :           const char  *func = va_arg(ap, char *);
     441                 : 
     442              50 :           if (ustr__cntl_mc_num)
     443                 :           {
     444               3 :             USTR_ASSERT(!strcmp(file,
     445                 :                                 ustr__cntl_mc_ptr[ustr__cntl_mc_num].file));
     446               3 :             USTR_ASSERT(line); /* can't say much about this */
     447               3 :             USTR_ASSERT(!strcmp(func,
     448                 :                                 ustr__cntl_mc_ptr[ustr__cntl_mc_num].func));
     449                 :           
     450               6 :             --ustr__cntl_mc_num;
     451               6 :             break;
     452                 :           }
     453                 : 
     454              44 :           MC_FREE(ustr__cntl_mc_ptr);
     455              44 :           ustr__cntl_mc_num = 0;
     456              44 :           ustr__cntl_mc_sz  = 0;
     457              44 :           ustr__cntl_mc_ptr = 0;
     458                 :           
     459                 :           /* it's bad otherwise */
     460              44 :           malloc_check_empty(file, line, func);
     461                 :           
     462              44 :           ustr__opts->umem.sys_malloc  = malloc;
     463              44 :           ustr__opts->umem.sys_realloc = realloc;
     464              44 :           ustr__opts->umem.sys_free    = free;
     465                 :           
     466              44 :           MALLOC_CHECK_STORE.mem_num      = 0;
     467              44 :           MALLOC_CHECK_STORE.mem_fail_num = 0;
     468                 :         }
     469                 :         break;
     470                 :       }
     471                 :     }
     472             260 :     break;
     473                 :     
     474                 :     case USTR_CNTL_OPT_GET_FMT:
     475                 :     {
     476               4 :       struct Ustr_cntl_fmt *val = va_arg(ap, struct Ustr_cntl_fmt *);
     477                 : 
     478               4 :       val->sys_vsnprintf_beg = ustr__opts->ufmt.sys_vsnprintf_beg;
     479               4 :       val->sys_vsnprintf_end = ustr__opts->ufmt.sys_vsnprintf_end;
     480                 :       
     481               4 :       ret = USTR_TRUE;
     482                 :     }
     483               4 :     break;
     484                 :     
     485                 :     case USTR_CNTL_OPT_SET_FMT:
     486                 :     {
     487               2 :       const struct Ustr_cntl_fmt *val = va_arg(ap, struct Ustr_cntl_fmt *);
     488                 : 
     489               2 :       ustr__opts->ufmt.sys_vsnprintf_beg = val->sys_vsnprintf_beg;
     490               2 :       ustr__opts->ufmt.sys_vsnprintf_end = val->sys_vsnprintf_end;
     491                 :       
     492               2 :       ret = USTR_TRUE;
     493                 :     }
     494                 :     /* break; */
     495                 : 
     496               1 :     USTR_ASSERT_NO_SWITCH_DEF("Bad option passed to ustr_cntl_opt()");
     497                 :   }
     498                 :   
     499          416760 :   va_end(ap);
     500                 : 
     501          416760 :   return (ret);
     502                 : }

Generated by: LTP GCOV extension version 1.4