/*
libmawk (C) 2014, Tibor 'Igor2' Palinkas;
libMawk is distributed without warranty under the terms of
the GNU General Public License, version 2, 1991.
*/
#include <stdlib.h>
#include <string.h>
#include "mawk.h"
#include "array.h"
#include "memory.h"
#include "zmalloc.h"
#include "cell.h"
/* -- generic array implementation -- */
/* - creating a new array does not depend on the implementation - */
mawk_array_t mawk_array_new(mawk_state_t *MAWK, const array_imp_t *imp)
{
mawk_array_t a;
a = MAWK_ZMALLOC(MAWK, struct array);
memset(a, 0, sizeof(struct array));
if (imp == NULL)
a->imp = mawk_array_orig_imp;
else
a->imp = *imp;
return a;
}
void mawk_array_destroy(mawk_state_t *MAWK, mawk_array_t ARR)
{
mawk_array_clear(MAWK, ARR);
mawk_zfree(MAWK, ARR, sizeof(struct array));
}
/* catting the indices together doesn't depend on implementation */
mawk_cell_t *mawk_array_cat(mawk_state_t *MAWK, mawk_cell_t *sp, int cnt)
{
mawk_cell_t *p; /* walks the eval stack */
mawk_cell_t subsep; /* local copy of SUBSEP */
unsigned subsep_len; /* string length of subsep_str */
char *subsep_str;
unsigned total_len; /* length of cat'ed expression */
mawk_cell_t *top; /* value of sp at entry */
char *target; /* build cat'ed char* here */
mawk_string_t *sval; /* build cat'ed mawk_string_t here */
mawk_cellcpy(MAWK, &subsep, SUBSEP);
if (subsep.type < C_STRING)
mawk_cast1_to_str(MAWK, &subsep);
subsep_len = string(&subsep)->len;
subsep_str = string(&subsep)->str;
top = sp;
sp -= (cnt - 1);
total_len = (cnt - 1) * subsep_len;
for (p = sp; p <= top; p++) {
if (p->type < C_STRING)
mawk_cast1_to_str(MAWK, p);
total_len += string(p)->len;
}
sval = mawk_new_STRING0(MAWK, total_len);
target = sval->str;
for (p = sp; p < top; p++) {
memcpy(target, string(p)->str, string(p)->len);
target += string(p)->len;
memcpy(target, subsep_str, subsep_len);
target += subsep_len;
}
/* now p == top */
memcpy(target, string(p)->str, string(p)->len);
for (p = sp; p <= top; p++)
free_STRING(string(p));
free_STRING(string(&subsep));
/* set contents of sp , sp->type > C_STRING is possible so reset */
sp->type = C_STRING;
sp->ptr = (PTR) sval;
return sp;
}
void mawk_array_clear_common(mawk_state_t *MAWK, mawk_array_t A)
{
A->ptr = NULL;
A->size = 0;
A->limit = 0;
A->hmask = 0;
A->type = 0;
}
/* - naive implementation for the complex queries -
these assume the most basic operations (set/get/find/delet) to be implemented
and provide a slow, but generic implementation for the higher level
calls */
/* TODO */