/* * $Id: tab.c 270 2008-07-20 05:53:29Z baconevi $ * * {License} */ #include "awk_i.h" ase_awk_tab_t* ase_awk_tab_open (ase_awk_tab_t* tab, ase_awk_t* awk) { if (tab == ASE_NULL) { tab = (ase_awk_tab_t*) ASE_AWK_MALLOC ( awk, ASE_SIZEOF(ase_awk_tab_t)); if (tab == ASE_NULL) return ASE_NULL; tab->__dynamic = ASE_TRUE; } else tab->__dynamic = ASE_FALSE; tab->awk = awk; tab->buf = ASE_NULL; tab->size = 0; tab->capa = 0; return tab; } void ase_awk_tab_close (ase_awk_tab_t* tab) { ase_awk_tab_clear (tab); if (tab->buf != ASE_NULL) { ASE_AWK_FREE (tab->awk, tab->buf); tab->buf = ASE_NULL; tab->capa = 0; } if (tab->__dynamic) ASE_AWK_FREE (tab->awk, tab); } ase_size_t ase_awk_tab_getsize (ase_awk_tab_t* tab) { return tab->size; } ase_size_t ase_awk_tab_getcapa (ase_awk_tab_t* tab) { return tab->capa; } ase_awk_tab_t* ase_awk_tab_setcapa (ase_awk_tab_t* tab, ase_size_t capa) { void* tmp; if (tab->size > capa) { ase_awk_tab_remove (tab, capa, tab->size - capa); ASE_ASSERT (tab->size <= capa); } if (capa > 0) { if (tab->awk->mmgr->realloc != ASE_NULL) { tmp = ASE_AWK_REALLOC (tab->awk, tab->buf, ASE_SIZEOF(*tab->buf) * capa); if (tmp == ASE_NULL) return ASE_NULL; } else { tmp = ASE_AWK_MALLOC ( tab->awk, ASE_SIZEOF(*tab->buf) * capa); if (tmp == ASE_NULL) return ASE_NULL; if (tab->buf != ASE_NULL) { ase_size_t x; x = (capa > tab->capa)? tab->capa: capa; ase_memcpy ( tmp, tab->buf, ASE_SIZEOF(*tab->buf) * x); ASE_AWK_FREE (tab->awk, tab->buf); } } } else { if (tab->buf != ASE_NULL) ASE_AWK_FREE (tab->awk, tab->buf); tmp = ASE_NULL; } tab->buf = tmp; tab->capa = capa; return tab; } void ase_awk_tab_clear (ase_awk_tab_t* tab) { ase_size_t i; for (i = 0; i < tab->size; i++) { ASE_AWK_FREE (tab->awk, tab->buf[i].name.ptr); tab->buf[i].name.ptr = ASE_NULL; tab->buf[i].name.len = 0; } tab->size = 0; } ase_size_t ase_awk_tab_insert ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len) { ase_size_t i; ase_char_t* dup; dup = ASE_AWK_STRXDUP (tab->awk, str, len); if (dup == ASE_NULL) return (ase_size_t)-1; if (index >= tab->capa) { ase_size_t capa; if (tab->capa <= 0) capa = (index + 1); else { do { capa = tab->capa * 2; } while (index >= capa); } if (ase_awk_tab_setcapa(tab,capa) == ASE_NULL) { ASE_AWK_FREE (tab->awk, dup); return (ase_size_t)-1; } } for (i = tab->size; i > index; i--) tab->buf[i] = tab->buf[i-1]; tab->buf[index].name.ptr = dup; tab->buf[index].name.len = len; if (index > tab->size) tab->size = index + 1; else tab->size++; return index; } ase_size_t ase_awk_tab_remove ( ase_awk_tab_t* tab, ase_size_t index, ase_size_t count) { ase_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; while (i < k) { ASE_AWK_FREE (tab->awk, tab->buf[i].name.ptr); if (j >= tab->size) { tab->buf[i].name.ptr = ASE_NULL; tab->buf[i].name.len = 0; i++; } else { tab->buf[i].name.ptr = tab->buf[j].name.ptr; tab->buf[i].name.len = tab->buf[j].name.len; i++; j++; } } tab->size -= count; return count; } ase_size_t ase_awk_tab_add ( ase_awk_tab_t* tab, const ase_char_t* str, ase_size_t len) { return ase_awk_tab_insert (tab, tab->size, str, len); } ase_size_t ase_awk_tab_adduniq ( ase_awk_tab_t* tab, const ase_char_t* str, ase_size_t len) { ase_size_t i; i = ase_awk_tab_find (tab, 0, str, len); if (i != (ase_size_t)-1) return i; /* found. return the current index */ /* insert a new entry */ return ase_awk_tab_insert (tab, tab->size, str, len); } ase_size_t ase_awk_tab_find ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len) { ase_size_t i; for (i = index; i < tab->size; i++) { if (ase_strxncmp ( tab->buf[i].name.ptr, tab->buf[i].name.len, str, len) == 0) return i; } return (ase_size_t)-1; } ase_size_t ase_awk_tab_rfind ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len) { ase_size_t i; if (index >= tab->size) return (ase_size_t)-1; for (i = index + 1; i-- > 0; ) { if (ase_strxncmp ( tab->buf[i].name.ptr, tab->buf[i].name.len, str, len) == 0) return i; } return (ase_size_t)-1; } ase_size_t ase_awk_tab_rrfind ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len) { ase_size_t i; if (index >= tab->size) return (ase_size_t)-1; for (i = tab->size - index; i-- > 0; ) { if (ase_strxncmp ( tab->buf[i].name.ptr, tab->buf[i].name.len, str, len) == 0) return i; } return (ase_size_t)-1; } ase_size_t ase_awk_tab_findx ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len, void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg) { ase_size_t i; for (i = index; i < tab->size; i++) { ase_cstr_t x; x.ptr = tab->buf[i].name.ptr; x.len = tab->buf[i].name.len; transform (i, &x, arg); if (ase_strxncmp (x.ptr, x.len, str, len) == 0) return i; } return (ase_size_t)-1; } ase_size_t ase_awk_tab_rfindx ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len, void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg) { ase_size_t i; if (index >= tab->size) return (ase_size_t)-1; for (i = index + 1; i-- > 0; ) { ase_cstr_t x; x.ptr = tab->buf[i].name.ptr; x.len = tab->buf[i].name.len; transform (i, &x, arg); if (ase_strxncmp (x.ptr, x.len, str, len) == 0) return i; } return (ase_size_t)-1; } ase_size_t ase_awk_tab_rrfindx ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len, void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg) { ase_size_t i; if (index >= tab->size) return (ase_size_t)-1; for (i = tab->size - index; i-- > 0; ) { ase_cstr_t x; x.ptr = tab->buf[i].name.ptr; x.len = tab->buf[i].name.len; transform (i, &x, arg); if (ase_strxncmp (x.ptr, x.len, str, len) == 0) return i; } return (ase_size_t)-1; }