#include "repl.h"


/* macro to test the type of two adjacent cells */
#define TEST2(cp)  (MAWK->mpow2[(cp)->type]+MAWK->mpow2[((cp)+1)->type])

/* paranoia cell checks for cell debug */
#ifdef CELLDEBUG
#define cell_destroy_paranoia_set(cp)  (cp)->type = C_FREED;
#define cell_paranoia_chk(MAWK, cp)  \
do { \
	if ((cp)->type == C_FREED) \
		mawk_bozo(MAWK, "invalid cell reference."); \
} while (0)
#else
#define cell_destroy_paranoia_set(cp)
#define cell_paranoia_chk(MAWK, cp)
#endif


/* cell_destroy: macro or function, for debugging */
#ifdef CELLDEBUG
#define mawk_cell_destroy(MAWK, cp)  DB_cell_destroy(MAWK, cp)
#else
#define mawk_cell_destroy(MAWK, cp) \
do { \
	if ( (cp)->type >= C_STRING && -- string(cp)->ref_cnt == 0) \
		mawk_zfree(MAWK, string(cp),string(cp)->len+STRING_OH); \
		cell_destroy_paranoia_set(cp); \
} while(0)
#endif

/* cellcpy: macro or function, for debugging */
#ifdef CELLDEBUG
/* debug version: real function */
void DB_mawk_cellcpy(mawk_state_t *MAWK, register mawk_cell_t *target, const register mawk_cell_t *source);
#define mawk_cellcpy DB_mawk_cellcpy
#else
/* fast version: macro */
extern char *mawk_bozo_cellcpy;
#define mawk_cellcpy(MAWK_, target, source) \
do { \
	const mawk_cell_t *cellcpy__source = (const mawk_cell_t *)(source); \
	mawk_cell_t *cellcpy__target = (target); \
	cell_paranoia_chk((MAWK_), cellcpy__source); \
	switch (cellcpy__target->type = cellcpy__source->type) { \
	case C_NOINIT: \
	case C_SPACE: \
	case C_SNULL: \
		break; \
	case C_NUM: \
		cellcpy__target->d.dval = cellcpy__source->d.dval; \
		break; \
	case C_STRNUM: \
		cellcpy__target->d.dval = cellcpy__source->d.dval; \
	case C_REPL: \
	case C_MBSTRN: \
	case C_STRING: \
		string(cellcpy__source)->ref_cnt++; \
	case C_RE: \
		cellcpy__target->ptr = cellcpy__source->ptr; \
		break; \
	case C_REPLV: \
		mawk_replv_cpy((MAWK_), cellcpy__target, cellcpy__source); \
		break; \
	default: \
		mawk_bozo(MAWK_, mawk_bozo_cellcpy); \
		break; \
	} \
} while(0)
#endif


