/*******************************************************************************
*
* HEADER: cbc.h
*
********************************************************************************
*
* DESCRIPTION: C::B::C common defines
*
********************************************************************************
*
* Copyright (c) 2002-2015 Marcus Holland-Moritz. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the same terms as Perl itself.
*
*******************************************************************************/
#ifndef _CBC_CBC_H
#define _CBC_CBC_H
/*===== GLOBAL INCLUDES ======================================================*/
/*===== LOCAL INCLUDES =======================================================*/
#include "ctlib/arch.h"
#include "ctlib/ctdebug.h"
#include "ctlib/ctparse.h"
#include "ctlib/cttype.h"
#include "cbc/basic.h"
/*===== DEFINES ==============================================================*/
#define XSCLASS "Convert::Binary::C"
#define ARGTYPE_PACKAGE "Convert::Binary::C::ARGTYPE"
/*-------------------------------------*/
/* some quick paranoid checks first... */
/*-------------------------------------*/
#if (defined I8SIZE && I8SIZE != 1) || \
(defined U8SIZE && U8SIZE != 1)
#error "Your I8/U8 doesn't seem to have 8 bits..."
#endif
#if (defined I16SIZE && I16SIZE != 2) || \
(defined U16SIZE && U16SIZE != 2)
#error "Your I16/U16 doesn't seem to have 16 bits..."
#endif
#if (defined I32SIZE && I32SIZE != 4) || \
(defined U32SIZE && U32SIZE != 4)
#error "Your I32/U32 doesn't seem to have 32 bits..."
#endif
/*---------------*/
/* some defaults */
/*---------------*/
#ifndef CBC_DEFAULT_PTR_SIZE
#define CBC_DEFAULT_PTR_SIZE CTLIB_POINTER_SIZE
#else
#if CBC_DEFAULT_PTR_SIZE != 1 && \
CBC_DEFAULT_PTR_SIZE != 2 && \
CBC_DEFAULT_PTR_SIZE != 4 && \
CBC_DEFAULT_PTR_SIZE != 8
#error "CBC_DEFAULT_PTR_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_ENUM_SIZE
#define CBC_DEFAULT_ENUM_SIZE sizeof( int )
#else
#if CBC_DEFAULT_ENUM_SIZE != 0 && \
CBC_DEFAULT_ENUM_SIZE != 1 && \
CBC_DEFAULT_ENUM_SIZE != 2 && \
CBC_DEFAULT_ENUM_SIZE != 4 && \
CBC_DEFAULT_ENUM_SIZE != 8
#error "CBC_DEFAULT_ENUM_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_INT_SIZE
#define CBC_DEFAULT_INT_SIZE CTLIB_int_SIZE
#else
#if CBC_DEFAULT_INT_SIZE != 1 && \
CBC_DEFAULT_INT_SIZE != 2 && \
CBC_DEFAULT_INT_SIZE != 4 && \
CBC_DEFAULT_INT_SIZE != 8
#error "CBC_DEFAULT_INT_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_CHAR_SIZE
#define CBC_DEFAULT_CHAR_SIZE CTLIB_char_SIZE
#else
#if CBC_DEFAULT_CHAR_SIZE != 1 && \
CBC_DEFAULT_CHAR_SIZE != 2 && \
CBC_DEFAULT_CHAR_SIZE != 4 && \
CBC_DEFAULT_CHAR_SIZE != 8
#error "CBC_DEFAULT_CHAR_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_SHORT_SIZE
#define CBC_DEFAULT_SHORT_SIZE CTLIB_short_SIZE
#else
#if CBC_DEFAULT_SHORT_SIZE != 1 && \
CBC_DEFAULT_SHORT_SIZE != 2 && \
CBC_DEFAULT_SHORT_SIZE != 4 && \
CBC_DEFAULT_SHORT_SIZE != 8
#error "CBC_DEFAULT_SHORT_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_LONG_SIZE
#define CBC_DEFAULT_LONG_SIZE CTLIB_long_SIZE
#else
#if CBC_DEFAULT_LONG_SIZE != 1 && \
CBC_DEFAULT_LONG_SIZE != 2 && \
CBC_DEFAULT_LONG_SIZE != 4 && \
CBC_DEFAULT_LONG_SIZE != 8
#error "CBC_DEFAULT_LONG_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_LONG_LONG_SIZE
#define CBC_DEFAULT_LONG_LONG_SIZE CTLIB_long_long_SIZE
#else
#if CBC_DEFAULT_LONG_LONG_SIZE != 1 && \
CBC_DEFAULT_LONG_LONG_SIZE != 2 && \
CBC_DEFAULT_LONG_LONG_SIZE != 4 && \
CBC_DEFAULT_LONG_LONG_SIZE != 8
#error "CBC_DEFAULT_LONG_LONG_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_FLOAT_SIZE
#define CBC_DEFAULT_FLOAT_SIZE CTLIB_float_SIZE
#else
#if CBC_DEFAULT_FLOAT_SIZE != 1 && \
CBC_DEFAULT_FLOAT_SIZE != 2 && \
CBC_DEFAULT_FLOAT_SIZE != 4 && \
CBC_DEFAULT_FLOAT_SIZE != 8 && \
CBC_DEFAULT_FLOAT_SIZE != 12 && \
CBC_DEFAULT_FLOAT_SIZE != 16
#error "CBC_DEFAULT_FLOAT_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_DOUBLE_SIZE
#define CBC_DEFAULT_DOUBLE_SIZE CTLIB_double_SIZE
#else
#if CBC_DEFAULT_DOUBLE_SIZE != 1 && \
CBC_DEFAULT_DOUBLE_SIZE != 2 && \
CBC_DEFAULT_DOUBLE_SIZE != 4 && \
CBC_DEFAULT_DOUBLE_SIZE != 8 && \
CBC_DEFAULT_DOUBLE_SIZE != 12 && \
CBC_DEFAULT_DOUBLE_SIZE != 16
#error "CBC_DEFAULT_DOUBLE_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_LONG_DOUBLE_SIZE
#define CBC_DEFAULT_LONG_DOUBLE_SIZE CTLIB_long_double_SIZE
#else
#if CBC_DEFAULT_LONG_DOUBLE_SIZE != 1 && \
CBC_DEFAULT_LONG_DOUBLE_SIZE != 2 && \
CBC_DEFAULT_LONG_DOUBLE_SIZE != 4 && \
CBC_DEFAULT_LONG_DOUBLE_SIZE != 8 && \
CBC_DEFAULT_LONG_DOUBLE_SIZE != 12 && \
CBC_DEFAULT_LONG_DOUBLE_SIZE != 16
#error "CBC_DEFAULT_LONG_DOUBLE_SIZE is invalid!"
#endif
#endif
#ifndef CBC_DEFAULT_ALIGNMENT
#define CBC_DEFAULT_ALIGNMENT 1
#elif CBC_DEFAULT_ALIGNMENT != 1 && \
CBC_DEFAULT_ALIGNMENT != 2 && \
CBC_DEFAULT_ALIGNMENT != 4 && \
CBC_DEFAULT_ALIGNMENT != 8 && \
CBC_DEFAULT_ALIGNMENT != 16
#error "CBC_DEFAULT_ALIGNMENT is invalid!"
#endif
#ifndef CBC_DEFAULT_COMPOUND_ALIGNMENT
#define CBC_DEFAULT_COMPOUND_ALIGNMENT 1
#elif CBC_DEFAULT_COMPOUND_ALIGNMENT != 1 && \
CBC_DEFAULT_COMPOUND_ALIGNMENT != 2 && \
CBC_DEFAULT_COMPOUND_ALIGNMENT != 4 && \
CBC_DEFAULT_COMPOUND_ALIGNMENT != 8 && \
CBC_DEFAULT_COMPOUND_ALIGNMENT != 16
#error "CBC_DEFAULT_COMPOUND_ALIGNMENT is invalid!"
#endif
#ifndef CBC_DEFAULT_ENUMTYPE
#define CBC_DEFAULT_ENUMTYPE ET_INTEGER
#endif
#if ARCH_NATIVE_BYTEORDER == ARCH_BYTEORDER_BIG_ENDIAN
#define CBC_NATIVE_BYTEORDER CBO_BIG_ENDIAN
#elif ARCH_NATIVE_BYTEORDER == ARCH_BYTEORDER_LITTLE_ENDIAN
#define CBC_NATIVE_BYTEORDER CBO_LITTLE_ENDIAN
#else
#error "unknown native byte order"
#endif
#ifndef CBC_DEFAULT_BYTEORDER
#define CBC_DEFAULT_BYTEORDER CBC_NATIVE_BYTEORDER
#endif
/*--------------------------------------*/
/* macros for different checks/warnings */
/*--------------------------------------*/
#if defined G_WARN_ON && defined G_WARN_ALL_ON
#define PERL_WARNINGS_ON (PL_dowarn & (G_WARN_ON | G_WARN_ALL_ON))
#else
#define PERL_WARNINGS_ON PL_dowarn
#endif
#define WARN(args) STMT_START { if (PERL_WARNINGS_ON) Perl_warn args; } STMT_END
#define WARN2(args) STMT_START { if (PERL_WARNINGS_ON && THIS->cfg.issue_warnings) Perl_warn args; } STMT_END
#define WARN_UNSAFE(type) \
WARN((aTHX_ "Unsafe values used in %s('%s')", method, type))
#define WARN_FLAGS(type, flags) \
STMT_START { \
if ((flags) & T_UNSAFE_VAL) \
WARN_UNSAFE(type); \
} STMT_END
#define CROAK_UNDEF_STRUCT(ptr) \
Perl_croak(aTHX_ "Got no definition for '%s %s'", \
(ptr)->tflags & T_UNION ? "union" : "struct", \
(ptr)->identifier)
#define WARN_UNDEF_STRUCT(ptr) \
WARN((aTHX_ "Got no definition for '%s %s'", \
(ptr)->tflags & T_UNION ? "union" : "struct", \
(ptr)->identifier))
/*----------------------------*/
/* checks if an SV is defined */
/*----------------------------*/
#define DEFINED(sv) ((sv) != NULL && SvOK(sv))
/*----------------------------------*/
/* avoid warnings with older perl's */
/*----------------------------------*/
#if PERL_REVISION == 5 && PERL_VERSION < 6
# define CONST_CHAR(x) ((char *)(x))
#else
# define CONST_CHAR(x) (x)
#endif
/*--------------------------------------------------*/
/* macros to create SV's/HV's with constant strings */
/*--------------------------------------------------*/
#define NEW_SV_PV_CONST(str) \
newSVpvn(str, sizeof(str)/sizeof(char)-1)
#define HV_STORE_CONST(hash, key, value) \
STMT_START { \
SV *_val = value; \
if (hv_store(hash, key, sizeof(key)/sizeof(char)-1, _val, 0) == NULL)\
SvREFCNT_dec(_val); \
} STMT_END
/*-------------------------*/
/* get the size of an enum */
/*-------------------------*/
#define GET_ENUM_SIZE(pCfg, pES) \
((pCfg)->layout.enum_size > 0 \
? (unsigned) (pCfg)->layout.enum_size \
: (pES)->sizes[-(pCfg)->layout.enum_size])
/*------------------------------------------------*/
/* this is needed quite often for unnamed structs */
/*------------------------------------------------*/
#define FOLLOW_AND_CHECK_TSPTR(pTS) \
STMT_START { \
if ((pTS)->tflags & T_TYPE) \
{ \
Typedef *_pT = (Typedef *) (pTS)->ptr; \
for(;;) \
{ \
if (_pT && _pT->pType->tflags & T_TYPE \
&& _pT->pDecl->pointer_flag == 0 \
&& _pT->pDecl->array_flag == 0) \
_pT = (Typedef *) _pT->pType->ptr; \
else \
break; \
} \
(pTS) = _pT->pType; \
} \
\
if (((pTS)->tflags & T_COMPOUND) == 0) \
fatal("Unnamed member was not struct or union (type=0x%08X) " \
"in %s line %d", (pTS)->tflags, __FILE__, __LINE__); \
\
if ((pTS)->ptr == NULL) \
fatal("Type pointer to struct/union was NULL in %s line %d", \
__FILE__, __LINE__); \
} STMT_END
/*===== TYPEDEFS =============================================================*/
typedef struct {
CParseConfig cfg;
CParseInfo cpi;
enum {
ET_INTEGER, ET_STRING, ET_BOTH
} enumType;
/* boolean options */
unsigned order_members : 1;
const char *ixhash;
HV *hv;
BasicTypes basic;
} CBC;
/*===== FUNCTION PROTOTYPES ==================================================*/
#endif