/*
array.h
libmawk changes (C) 2009-2010, Tibor 'Igor2' Palinkas;
based on mawk code coming with the below copyright:
copyright 1991-96, Michael D. Brennan
This is a source file for mawk, an implementation of
the AWK programming language.
Mawk is distributed without warranty under the terms of
the GNU General Public License, version 2, 1991.
*/
/*
This file originally had been generated with the command
notangle -R'"array.h"' array.w > array.h
but is maintained as .h in libmawk.
(Notangle is part of Norman Ramsey's noweb literate programming package
available from CTAN(ftp.shsu.edu)).
*/
#ifndef ARRAY_H
#define ARRAY_H 1
#define AY_NULL 0
#define AY_INT 1
#define AY_STR 2
#define AY_SPLIT 4
#define NO_MAWK_CREATE 0
#define MAWK_CREATE 1
#include "cell.h"
#include "array_orig.h"
/* create a new, empty array, copying implementation from imp; if imp is NULL,
use the default (original) implementation. */
mawk_array_t mawk_array_new(mawk_state_t *MAWK, const array_imp_t *imp);
/* free all memory used by ARR */
void mawk_array_destroy(mawk_state_t *MAWK, mawk_array_t ARR);
/* concat multiple expressions separated by SUBSEP to be an array index */
mawk_cell_t *mawk_array_cat(mawk_state_t *MAWK, mawk_cell_t *sp, int cnt);
/* clear the common administrative part of the array, leaving imp alone;
this must be used instead of memsetting the mawk_array_t */
void mawk_array_clear_common(mawk_state_t *MAWK, mawk_array_t A);
/* wrappers for accessing the implementations; a layer of macros is introduced
here to guarantee future flexibility */
/* **** WARNING: these macros will ecaluate ARR_ at least twice! **** */
#define mawk_array_find(MAWK_, ARR_, idx_, result_, create_) (ARR_)->imp.find((MAWK_), (ARR_), (idx_), (result_), (create_))
#define mawk_array_set(MAWK_, ARR_, idx_, val_) (ARR_)->imp.set((MAWK_), (ARR_), (idx_), (val_))
#define mawk_array_delete(MAWK_, ARR_, cell_) (ARR_)->imp.delet((MAWK_), (ARR_), (cell_))
#define mawk_array_clear(MAWK_, ARR_) (ARR_)->imp.clear((MAWK_), (ARR_))
#define mawk_array_loop_vector(MAWK_, ARR_, sizep_) (ARR_)->imp.loop_vect((MAWK_), (ARR_), (sizep_))
#define mawk_array_load(MAWK_, ARR_, cnt_) (ARR_)->imp.load((MAWK_), (ARR_), (cnt_))
/* The following macros are used in execute.c for fast and convenient access
to cells on SP */
/* check whether an array is pure (no side effects, aka orig implementation) for
read or read+write */
#define mawk_array_pure4wr(MAWK, ARR_) (ARR_)->imp.set == mawk_array_orig_imp.set
#define mawk_array_pure4del(MAWK, ARR_) (ARR_)->imp.delet == mawk_array_orig_imp.delet
#define mawk_array_pure4rd(MAWK, ARR_) (ARR_)->imp.find == mawk_array_orig_imp.find
#define mawk_array_pure4rdwr(MAWK, ARR_) ((mawk_array_pure4wr((MAWK), (ARR_))) && (mawk_array_pure4del((MAWK), (ARR_))) && (mawk_array_pure4rd((MAWK), (ARR_))))
#define mawk_array_pure(MAWK, ARR_REF_, for_write) ((for_write) ? (mawk_array_pure4rdwr((MAWK), (mawk_array_t)(ARR_REF_)->ptr)) : (mawk_array_pure4rd((MAWK), (mawk_array_t)(ARR_REF_)->ptr)))
/* change the value of an array pointed to by ARR_REF_ (typer C_ARR_REF).
This wrapper is useful from execute.c where multiple assignments
to array elemts will have to do the same:
- look up the index in the array
- modify the content of the array element
- destroy the index and the rvalue
- put the value of the expr in res_
Note: mawk_cell_destroy(MAWK, (mawk_cell_t *)(ARR_REF_)) is not required: destroy of C_ARR_REF is a nop
*/
#define mawk_array_set_execute_(MAWK, res_, ARR_REF_, IDX_, rvalue_) \
do { \
mawk_array_set(MAWK, (mawk_array_t)((ARR_REF_)->ptr), (IDX_), rvalue_); \
mawk_cell_destroy(MAWK, (mawk_cell_t *)(IDX_)); \
if (IDX_ != res_) \
mawk_cell_destroy(MAWK, res_); \
mawk_cellcpy(MAWK, res_, rvalue_); \
mawk_cell_destroy(MAWK, rvalue_); \
} while(0)
/* look up an array element; place the resulting cell in res_
Does not destroy IDX_.
Note: mawk_cell_destroy(MAWK, (mawk_cell_t *)(ARR_REF_)) is not required: destroy of C_ARR_REF is a nop
*/
#define mawk_array_get_execute_(MAWK, res_, ARR_REF_, IDX_) \
do { \
mawk_array_find(MAWK, (mawk_array_t)((ARR_REF_)->ptr), (IDX_), (res_), MAWK_CREATE); \
} while(0)
/* this must not be used on arrays with side effects */
mawk_cell_t *mawk_array_find_orig_(mawk_state_t *MAWK, mawk_array_t A, const mawk_cell_t *cp, int create_flag);
#define mawk_array_getptr_execute_(MAWK, res_, ARR_REF_, IDX_) \
do { \
res_ = mawk_array_find_orig_(MAWK, (mawk_array_t)((ARR_REF_)->ptr), (IDX_), MAWK_CREATE); \
} while(0)
/* same as mawk_arra_get_execute plus cast the result to number if it is not
a number already
does not destroy IDX
*/
#define mawk_array_getnum_execute_(MAWK, res_, ARR_REF_, IDX_) \
do { \
mawk_array_get_execute(MAWK, (res_), (ARR_REF_), (IDX_)); \
if ((res_)->type != C_NUM) \
mawk_cast1_to_num(MAWK, (res_)); \
} while(0)
#ifdef DEBUG
/* in debug mode use static inlines for easier debugging */
static inline void mawk_array_get_execute(mawk_state_t *MAWK, mawk_cell_t *res, mawk_cell_t *arr_ref, mawk_cell_t *idx)
{
mawk_array_get_execute_(MAWK, res, arr_ref, idx);
}
static inline void mawk_array_getptr_execute(mawk_state_t *MAWK, mawk_cell_t *res, mawk_cell_t *arr_ref, mawk_cell_t *idx)
{
mawk_array_getptr_execute_(MAWK, res, arr_ref, idx);
}
static inline void mawk_array_getnum_execute(mawk_state_t *MAWK, mawk_cell_t *res, mawk_cell_t *arr_ref, mawk_cell_t *idx)
{
mawk_array_getnum_execute_(MAWK, res, arr_ref, idx);
}
static inline void mawk_array_set_execute(mawk_state_t *MAWK, mawk_cell_t *res, mawk_cell_t *arr_ref, mawk_cell_t *idx, mawk_cell_t *rvalue)
{
mawk_array_set_execute_(MAWK, res, arr_ref, idx, rvalue);
}
#else
#define mawk_array_getnum_execute mawk_array_getnum_execute_
#define mawk_array_getptr_execute mawk_array_getptr_execute_
#define mawk_array_get_execute mawk_array_get_execute_
#define mawk_array_set_execute mawk_array_set_execute_
#endif
#endif /* ARRAY_H */