2006-01-29 18:28:14 +00:00
|
|
|
/*
|
2006-03-31 16:35:37 +00:00
|
|
|
* $Id: tab.c,v 1.7 2006-03-31 16:35:37 bacon Exp $
|
2006-01-29 18:28:14 +00:00
|
|
|
*/
|
|
|
|
|
2006-03-31 16:35:37 +00:00
|
|
|
#include <xp/awk/awk_i.h>
|
2006-01-30 14:45:12 +00:00
|
|
|
|
2006-01-29 18:28:14 +00:00
|
|
|
#ifndef __STAND_ALONE
|
|
|
|
#include <xp/bas/memory.h>
|
2006-01-30 14:45:12 +00:00
|
|
|
#include <xp/bas/string.h>
|
2006-01-29 18:28:14 +00:00
|
|
|
#include <xp/bas/assert.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
xp_awk_tab_t* xp_awk_tab_open (xp_awk_tab_t* tab)
|
|
|
|
{
|
2006-03-07 15:55:14 +00:00
|
|
|
if (tab == XP_NULL)
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
tab = (xp_awk_tab_t*) xp_malloc (xp_sizeof(xp_awk_tab_t));
|
|
|
|
if (tab == XP_NULL) return XP_NULL;
|
|
|
|
tab->__dynamic = xp_true;
|
|
|
|
}
|
|
|
|
else tab->__dynamic = xp_false;
|
|
|
|
|
|
|
|
tab->buf = XP_NULL;
|
|
|
|
tab->size = 0;
|
|
|
|
tab->capa = 0;
|
|
|
|
|
|
|
|
return tab;
|
|
|
|
}
|
|
|
|
|
|
|
|
void xp_awk_tab_close (xp_awk_tab_t* tab)
|
|
|
|
{
|
|
|
|
xp_awk_tab_clear (tab);
|
2006-03-07 15:55:14 +00:00
|
|
|
if (tab->buf != XP_NULL)
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_free (tab->buf);
|
|
|
|
tab->buf = XP_NULL;
|
|
|
|
tab->capa = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tab->__dynamic) xp_free (tab);
|
|
|
|
}
|
|
|
|
|
|
|
|
xp_size_t xp_awk_tab_getsize (xp_awk_tab_t* tab)
|
|
|
|
{
|
|
|
|
return tab->size;
|
|
|
|
}
|
|
|
|
|
|
|
|
xp_size_t xp_awk_tab_getcapa (xp_awk_tab_t* tab)
|
|
|
|
{
|
|
|
|
return tab->capa;
|
|
|
|
}
|
|
|
|
|
|
|
|
xp_awk_tab_t* xp_awk_tab_setcapa (xp_awk_tab_t* tab, xp_size_t capa)
|
|
|
|
{
|
|
|
|
xp_char_t** tmp;
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
if (tab->size > capa)
|
|
|
|
{
|
|
|
|
xp_awk_tab_remove (tab, capa, tab->size - capa);
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_assert (tab->size <= capa);
|
|
|
|
}
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
if (capa > 0)
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
tmp = (xp_char_t**)xp_realloc (
|
|
|
|
tab->buf, xp_sizeof(xp_char_t*) * capa);
|
|
|
|
if (tmp == XP_NULL) return XP_NULL;
|
|
|
|
}
|
2006-03-07 15:55:14 +00:00
|
|
|
else
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
if (tab->buf != XP_NULL) xp_free (tab->buf);
|
|
|
|
tmp = XP_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tab->buf = tmp;
|
|
|
|
tab->capa = capa;
|
|
|
|
|
|
|
|
return tab;
|
|
|
|
}
|
|
|
|
|
|
|
|
void xp_awk_tab_clear (xp_awk_tab_t* tab)
|
|
|
|
{
|
|
|
|
xp_size_t i;
|
|
|
|
|
|
|
|
xp_assert (tab != XP_NULL);
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
for (i = 0; i < tab->size; i++)
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_free (tab->buf[i]);
|
|
|
|
tab->buf[i] = XP_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tab->size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
xp_size_t xp_awk_tab_insert (
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_awk_tab_t* tab, xp_size_t index, const xp_char_t* value)
|
|
|
|
{
|
|
|
|
xp_size_t i;
|
|
|
|
xp_char_t* value_dup;
|
|
|
|
|
|
|
|
value_dup = xp_strdup(value);
|
|
|
|
if (value_dup == XP_NULL) return (xp_size_t)-1;
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
if (index >= tab->capa)
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_size_t capa;
|
|
|
|
|
|
|
|
if (tab->capa <= 0) capa = (index + 1);
|
2006-03-07 15:55:14 +00:00
|
|
|
else
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
do { capa = tab->capa * 2; } while (index >= capa);
|
|
|
|
}
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
if (xp_awk_tab_setcapa(tab,capa) == XP_NULL)
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_free (value_dup);
|
|
|
|
return (xp_size_t)-1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = tab->size; i > index; i--) tab->buf[i] = tab->buf[i-1];
|
|
|
|
tab->buf[index] = value_dup;
|
|
|
|
|
|
|
|
if (index > tab->size) tab->size = index + 1;
|
|
|
|
else tab->size++;
|
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
xp_size_t xp_awk_tab_remove (
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_awk_tab_t* tab, xp_size_t index, xp_size_t count)
|
|
|
|
{
|
|
|
|
xp_size_t i, j, k;
|
|
|
|
|
|
|
|
if (index >= tab->size) return 0;
|
|
|
|
if (count > tab->size - index) count = tab->size - index;
|
|
|
|
|
|
|
|
i = index;
|
|
|
|
j = index + count;
|
|
|
|
k = index + count;
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
while (i < k)
|
|
|
|
{
|
2006-01-29 18:28:14 +00:00
|
|
|
xp_free (tab->buf[i]);
|
2006-03-07 15:55:14 +00:00
|
|
|
|
2006-01-29 18:28:14 +00:00
|
|
|
if (j >= tab->size)
|
2006-03-07 15:55:14 +00:00
|
|
|
{
|
|
|
|
tab->buf[i] = XP_NULL;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tab->buf[i] = tab->buf[j];
|
|
|
|
i++; j++;
|
|
|
|
}
|
2006-01-29 18:28:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tab->size -= count;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2006-03-07 15:55:14 +00:00
|
|
|
xp_size_t xp_awk_tab_add (xp_awk_tab_t* tab, const xp_char_t* value)
|
2006-01-29 18:28:14 +00:00
|
|
|
{
|
2006-03-07 15:55:14 +00:00
|
|
|
return xp_awk_tab_insert (tab, tab->size, value);
|
2006-01-29 18:28:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
xp_size_t xp_awk_tab_find (
|
|
|
|
xp_awk_tab_t* tab, const xp_char_t* value, xp_size_t index)
|
|
|
|
{
|
|
|
|
xp_size_t i;
|
|
|
|
|
|
|
|
for (i = index; i < tab->size; i++) {
|
|
|
|
if (xp_strcmp(tab->buf[i], value) == 0) return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (xp_size_t)-1;
|
|
|
|
}
|
|
|
|
|
2006-02-05 13:45:59 +00:00
|
|
|
xp_size_t xp_awk_tab_rfind (
|
|
|
|
xp_awk_tab_t* tab, const xp_char_t* value, xp_size_t index)
|
|
|
|
{
|
|
|
|
xp_size_t i;
|
|
|
|
|
2006-02-05 14:21:18 +00:00
|
|
|
if (index >= tab->size) return (xp_size_t)-1;
|
|
|
|
|
2006-02-05 13:45:59 +00:00
|
|
|
for (i = index + 1; i-- > 0; ) {
|
|
|
|
if (xp_strcmp(tab->buf[i], value) == 0) return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (xp_size_t)-1;
|
|
|
|
}
|
2006-02-05 14:21:18 +00:00
|
|
|
|
|
|
|
xp_size_t xp_awk_tab_rrfind (
|
|
|
|
xp_awk_tab_t* tab, const xp_char_t* value, xp_size_t index)
|
|
|
|
{
|
|
|
|
xp_size_t i;
|
|
|
|
|
|
|
|
if (index >= tab->size) return (xp_size_t)-1;
|
|
|
|
|
|
|
|
for (i = tab->size - index; i-- > 0; ) {
|
|
|
|
if (xp_strcmp(tab->buf[i], value) == 0) return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (xp_size_t)-1;
|
|
|
|
}
|