/*---------------------------------------------------------------------------------------------------*/
#include <unistd.h>
#include "list.h"
/*---------------------------------------------------------------------------------------------------*/
/** ARRAY store macros **/
#define AVS_H(arr, h) av_push(arr, newRV((SV *)h))
#define AVS_A(arr, a) av_push(arr, newRV((SV *)a))
#define AVS_I(arr, i) av_push(arr, newSViv(i))
#define AVS_S(arr, s) av_push(arr, newSVpv(s, 0))
/** HASH store macros **/
/* Use 'name' as structure field name AND HASH key name */
#define HVS(h, name, sv) hv_store(h, #name, sizeof(#name)-1, sv, 0)
#define HVS_S(h, sp, name) if (sp->name) hv_store(h, #name, sizeof(#name)-1, newSVpv(sp->name, 0), 0)
#define HVS_I(h, sp, name) if (sp->name >= 0) hv_store(h, #name, sizeof(#name)-1, newSViv(sp->name), 0)
#define HVS_BIT(h, var, name) hv_store(h, #name, sizeof(#name)-1, newSViv(var & name ? 1 : 0), 0)
/* Specify the structure field name and HASH key name separately */
#define HVSN_S(h, sp, name, key) if (sp->name) hv_store(h, #key, sizeof(#key)-1, newSVpv(sp->name, 0), 0)
#define HVSN_I(h, sp, name, key) if (sp->name >= 0) hv_store(h, #key, sizeof(#key)-1, newSViv(sp->name), 0)
/* Convert string before storing in hash */
#define HVS_STRING(h, sp, name) hv_store(h, #name, sizeof(#name)-1, newSVpv(_to_string(sp->name), 0), 0)
#define HVS_STRING_STRIP(h, sp, name) hv_store(h, #name, sizeof(#name)-1, newSVpv(_to_string_strip(sp->name), 0), 0)
/* non-struct member versions */
#define HVS_INT(h, name, i) hv_store(h, #name, sizeof(#name)-1, newSViv(i), 0)
#define HVS_STR(h, name, s) hv_store(h, #name, sizeof(#name)-1, newSVpv(s, 0), 0)
/** HASH read macros **/
#define HVF_I(hv,var) \
if ( (val = hv_fetch (hv, #var, sizeof (#var) - 1, 0)) ) { \
if ( val != NULL ) { \
var = SvIV (*val); \
if (DVBT_DEBUG) fprintf(stderr, " set %s = %d\n", #var, var); \
} \
}
#define HVF_SV(hv,var) \
if ( (val = hv_fetch (hv, #var, sizeof (#var) - 1, 0)) ) { \
if ( val != NULL ) { \
var = SvSV (*val); \
} \
}
#define HVF_IV(hv,var,ival) \
if ( (val = hv_fetch (hv, #var, sizeof (#var) - 1, 0)) ) { \
if ( val != NULL ) { \
ival = SvIV (*val); \
} \
}
#define HVF_SVV(hv,var,sval) \
if ( (val = hv_fetch (hv, #var, sizeof (#var) - 1, 0)) ) { \
if ( val != NULL ) { \
sval = (*val); \
} \
}
#define HVF(hv, var) hv_fetch (hv, #var, sizeof (#var) - 1, 0)
/* get the HASH ref using the specified key. If not currently set, then create a new HASH and add it to the parent */
#define GET_HREF(hv, key, var) \
if ( (val = hv_fetch (hv, #key, sizeof (#key) - 1, 0)) ) { \
if ( val != NULL ) { \
var = (HV *)sv_2mortal(*val); \
} \
else { \
var = (HV *)sv_2mortal((SV *)newHV()); \
hv_store(hv, #key, sizeof(#key)-1, newRV((SV *)var), 0) ; \
} \
}
/*---------------------------------------------------------------------------------------------------*/
// Copies string into a static area so it can be used for creating Perl hash entries
#define TO_STRING_MAX 8191
static char ret_str[TO_STRING_MAX+1] ;
static char *_to_string(char *str)
{
int i, j, len = strlen(str);
for (i=0, j=0; (i < len) && (i < TO_STRING_MAX); i++)
{
ret_str[j++] = str[i] ;
/* terminate */
ret_str[j] = 0 ;
}
return ret_str ;
}
/*---------------------------------------------------------------------------------------------------*/
// Copies string into a static area so it can be used for creating Perl hash entries. Also strips out
// any invalid chars
static unsigned valid_char[0xff] ;
static unsigned valid_char_init = 0 ;
static char *_to_string_strip(char *str)
{
int i, j, len = strlen(str);
// set up lookup table once
if (!valid_char_init)
{
for (i=0; (i < 0xff); i++)
{
valid_char[i] = 0 ;
if (
((i >= ' ') && (i <= '~'))
|| (i == '\n')
|| (i == '\r')
|| (i == 0)
)
{
valid_char[i] = 1 ;
}
}
valid_char_init = 1 ;
}
// copy valid chars ro destination
for (i=0, j=0; (i < len) && (i < TO_STRING_MAX); i++)
{
if (valid_char[(unsigned char)(str[i]) & 0xff])
{
ret_str[j++] = str[i] ;
}
/* terminate */
ret_str[j] = 0 ;
}
return ret_str ;
}