📄 tcutil.c
字号:
if(index >= list->num) return NULL; index += list->start; *sp = list->array[index].size; return list->array[index].ptr;}/* Get the string of an element of a list object. */const char *tclistval2(const TCLIST *list, int index){ assert(list && index >= 0); if(index >= list->num) return NULL; index += list->start; return list->array[index].ptr;}/* Add an element at the end of a list object. */void tclistpush(TCLIST *list, const void *ptr, int size){ assert(list && ptr && size >= 0); int index = list->start + list->num; if(index >= list->anum){ list->anum += list->num + 1; TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); } TCLISTDATUM *array = list->array; TCMALLOC(array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); memcpy(array[index].ptr, ptr, size); array[index].ptr[size] = '\0'; array[index].size = size; list->num++;}/* Add a string element at the end of a list object. */void tclistpush2(TCLIST *list, const char *str){ assert(list && str); int index = list->start + list->num; if(index >= list->anum){ list->anum += list->num + 1; TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); } int size = strlen(str); TCLISTDATUM *array = list->array; TCMALLOC(array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); memcpy(array[index].ptr, str, size + 1); array[index].size = size; list->num++;}/* Add an allocated element at the end of a list object. */void tclistpushmalloc(TCLIST *list, void *ptr, int size){ assert(list && ptr && size >= 0); int index = list->start + list->num; if(index >= list->anum){ list->anum += list->num + 1; TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); } TCLISTDATUM *array = list->array; TCREALLOC(array[index].ptr, ptr, size + 1); array[index].ptr[size] = '\0'; array[index].size = size; list->num++;}/* Remove an element of the end of a list object. */void *tclistpop(TCLIST *list, int *sp){ assert(list && sp); if(list->num < 1) return NULL; int index = list->start + list->num - 1; list->num--; *sp = list->array[index].size; return list->array[index].ptr;}/* Remove a string element of the end of a list object. */char *tclistpop2(TCLIST *list){ assert(list); if(list->num < 1) return NULL; int index = list->start + list->num - 1; list->num--; return list->array[index].ptr;}/* Add an element at the top of a list object. */void tclistunshift(TCLIST *list, const void *ptr, int size){ assert(list && ptr && size >= 0); if(list->start < 1){ if(list->start + list->num >= list->anum){ list->anum += list->num + 1; TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); } list->start = list->anum - list->num; memmove(list->array + list->start, list->array, list->num * sizeof(list->array[0])); } int index = list->start - 1; TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); memcpy(list->array[index].ptr, ptr, size); list->array[index].ptr[size] = '\0'; list->array[index].size = size; list->start--; list->num++;}/* Add a string element at the top of a list object. */void tclistunshift2(TCLIST *list, const char *str){ assert(list && str); if(list->start < 1){ if(list->start + list->num >= list->anum){ list->anum += list->num + 1; TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); } list->start = list->anum - list->num; memmove(list->array + list->start, list->array, list->num * sizeof(list->array[0])); } int index = list->start - 1; int size = strlen(str); TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); memcpy(list->array[index].ptr, str, size + 1); list->array[index].size = size; list->start--; list->num++;}/* Remove an element of the top of a list object. */void *tclistshift(TCLIST *list, int *sp){ assert(list && sp); if(list->num < 1) return NULL; int index = list->start; list->start++; list->num--; *sp = list->array[index].size; void *rv = list->array[index].ptr; if((list->start & 0xff) == 0 && list->start > (list->num >> 1)){ memmove(list->array, list->array + list->start, list->num * sizeof(list->array[0])); list->start = 0; } return rv;}/* Remove a string element of the top of a list object. */char *tclistshift2(TCLIST *list){ assert(list); if(list->num < 1) return NULL; int index = list->start; list->start++; list->num--; void *rv = list->array[index].ptr; if((list->start & 0xff) == 0 && list->start > (list->num >> 1)){ memmove(list->array, list->array + list->start, list->num * sizeof(list->array[0])); list->start = 0; } return rv;}/* Add an element at the specified location of a list object. */void tclistinsert(TCLIST *list, int index, const void *ptr, int size){ assert(list && index >= 0 && ptr && size >= 0); if(index > list->num) return; index += list->start; if(list->start + list->num >= list->anum){ list->anum += list->num + 1; TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); } memmove(list->array + index + 1, list->array + index, sizeof(list->array[0]) * (list->start + list->num - index)); TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); memcpy(list->array[index].ptr, ptr, size); list->array[index].ptr[size] = '\0'; list->array[index].size = size; list->num++;}/* Add a string element at the specified location of a list object. */void tclistinsert2(TCLIST *list, int index, const char *str){ assert(list && index >= 0 && str); if(index > list->num) return; index += list->start; if(list->start + list->num >= list->anum){ list->anum += list->num + 1; TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); } memmove(list->array + index + 1, list->array + index, sizeof(list->array[0]) * (list->start + list->num - index)); int size = strlen(str); TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); memcpy(list->array[index].ptr, str, size); list->array[index].ptr[size] = '\0'; list->array[index].size = size; list->num++;}/* Remove an element at the specified location of a list object. */void *tclistremove(TCLIST *list, int index, int *sp){ assert(list && index >= 0 && sp); if(index >= list->num) return NULL; index += list->start; void *rv = list->array[index].ptr; *sp = list->array[index].size; list->num--; memmove(list->array + index, list->array + index + 1, sizeof(list->array[0]) * (list->start + list->num - index)); return rv;}/* Remove a string element at the specified location of a list object. */char *tclistremove2(TCLIST *list, int index){ assert(list && index >= 0); if(index >= list->num) return NULL; index += list->start; void *rv = list->array[index].ptr; list->num--; memmove(list->array + index, list->array + index + 1, sizeof(list->array[0]) * (list->start + list->num - index)); return rv;}/* Overwrite an element at the specified location of a list object. */void tclistover(TCLIST *list, int index, const void *ptr, int size){ assert(list && index >= 0 && ptr && size >= 0); if(index >= list->num) return; index += list->start; if(size > list->array[index].size) TCREALLOC(list->array[index].ptr, list->array[index].ptr, size + 1); memcpy(list->array[index].ptr, ptr, size); list->array[index].size = size; list->array[index].ptr[size] = '\0';}/* Overwrite a string element at the specified location of a list object. */void tclistover2(TCLIST *list, int index, const char *str){ assert(list && index >= 0 && str); if(index >= list->num) return; index += list->start; int size = strlen(str); if(size > list->array[index].size) TCREALLOC(list->array[index].ptr, list->array[index].ptr, size + 1); memcpy(list->array[index].ptr, str, size + 1); list->array[index].size = size;}/* Sort elements of a list object in lexical order. */void tclistsort(TCLIST *list){ assert(list); qsort(list->array + list->start, list->num, sizeof(list->array[0]), tclistelemcmp);}/* Sort elements of a list object in case-insensitive lexical order. */void tclistsortci(TCLIST *list){ assert(list); qsort(list->array + list->start, list->num, sizeof(list->array[0]), tclistelemcmpci);}/* Sort elements of a list object by an arbitrary comparison function. */void tclistsortex(TCLIST *list, int (*cmp)(const TCLISTDATUM *, const TCLISTDATUM *)){ assert(list && cmp); qsort(list->array + list->start, list->num, sizeof(list->array[0]), (int (*)(const void *, const void *))cmp);}/* Search a list object for an element using liner search. */int tclistlsearch(const TCLIST *list, const void *ptr, int size){ assert(list && ptr && size >= 0); int end = list->start + list->num; for(int i = list->start; i < end; i++){ if(list->array[i].size == size && !memcmp(list->array[i].ptr, ptr, size)) return i - list->start; } return -1;}/* Search a list object for an element using binary search. */int tclistbsearch(const TCLIST *list, const void *ptr, int size){ assert(list && ptr && size >= 0); TCLISTDATUM key; key.ptr = (char *)ptr; key.size = size; TCLISTDATUM *res = bsearch(&key, list->array + list->start, list->num, sizeof(list->array[0]), tclistelemcmp); return res ? res - list->array - list->start : -1;}/* Clear a list object. */void tclistclear(TCLIST *list){ assert(list); TCLISTDATUM *array = list->array; int end = list->start + list->num; for(int i = list->start; i < end; i++){ TCFREE(array[i].ptr); } list->start = 0; list->num = 0;}/* Serialize a list object into a byte array. */void *tclistdump(const TCLIST *list, int *sp){ assert(list && sp); const TCLISTDATUM *array = list->array; int end = list->start + list->num; int tsiz = 0; for(int i = list->start; i < end; i++){ tsiz += array[i].size + sizeof(int); } char *buf; TCMALLOC(buf, tsiz + 1); char *wp = buf; for(int i = list->start; i < end; i++){ int step; TCSETVNUMBUF(step, wp, array[i].size); wp += step; memcpy(wp, array[i].ptr, array[i].size); wp += array[i].size; } *sp = wp - buf; return buf;}/* Create a list object from a serialized byte array. */TCLIST *tclistload(const void *ptr, int size){ assert(ptr && size >= 0); TCLIST *list; TCMALLOC(list, sizeof(*list)); int anum = size / sizeof(int) + 1; TCLISTDATUM *array; TCMALLOC(array, sizeof(array[0]) * anum); int num = 0; const char *rp = ptr; const char *ep = (char *)ptr + size; while(rp < ep){ int step, vsiz; TCREADVNUMBUF(rp, vsiz, step); rp += step; if(num >= anum){ anum *= 2; TCREALLOC(array, array, anum * sizeof(array[0])); } TCMALLOC(array[num].ptr, tclmax(vsiz + 1, TCXSTRUNIT)); memcpy(array[num].ptr, rp, vsiz); array[num].ptr[vsiz] = '\0'; array[num].size = vsiz; num++; rp += vsiz; } list->anum = anum; list->array = array; list->start = 0; list->num = num; return list;}/* Compare two list elements in lexical order. `a' specifies the pointer to one element. `b' specifies the pointer to the other element. The return value is positive if the former is big, negative if the latter is big, 0 if both are equivalent. */static int tclistelemcmp(const void *a, const void *b){ assert(a && b); unsigned char *ao = (unsigned char *)((TCLISTDATUM *)a)->ptr; unsigned char *bo = (unsigned char *)((TCLISTDATUM *)b)->ptr; int size = (((TCLISTDATUM *)a)->size < ((TCLISTDATUM *)b)->size) ? ((TCLISTDATUM *)a)->size : ((TCLISTDATUM *)b)->size; for(int i = 0; i < size; i++){ if(ao[i] > bo[i]) return 1; if(ao[i] < bo[i]) return -1; } return ((TCLISTDATUM *)a)->size - ((TCLISTDATUM *)b)->size;}/* Compare two list elements in case-insensitive lexical order.. `a' specifies the pointer to one element. `b' specifies the pointer to the other element. The return value is positive if the former is big, negative if the latter is big, 0 if both are equivalent. */static int tclistelemcmpci(const void *a, const void *b){ assert(a && b); TCLISTDATUM *ap = (TCLISTDATUM *)a; TCLISTDATUM *bp = (TCLISTDATUM *)b; unsigned char *ao = (unsigned char *)ap->ptr; unsigned char *bo = (unsigned char *)bp->ptr; int size = (ap->size < bp->size) ? ap->size : bp->size; for(int i = 0; i < size; i++){ int ac = ao[i]; bool ab = false; if(ac >= 'A' && ac <= 'Z'){ ac += 'a' - 'A'; ab = true; } int bc = bo[i]; bool bb = false; if(bc >= 'A' && bc <= 'Z'){ bc += 'a' - 'A'; bb = true; } if(ac > bc) return 1; if(ac < bc) return -1; if(!ab && bb) return 1; if(ab && !bb) return -1; } return ap->size - bp->size;}/************************************************************************************************* * hash map *************************************************************************************************/#define TCMAPBNUM 4093 // allocation unit number of a map#define TCMAPZMMINSIZ 131072 // minimum memory size to use nullified region#define TCMAPCSUNIT 52 // small allocation unit size of map concatenation#define TCMAPCBUNIT 252 // big allocation unit size of map concatenation/* get the first hash value */#define TCMAPHASH1(TC_res, TC_kbuf, TC_ksiz) \ do { \ const unsigned char *_TC_p = (const unsigned char *)(TC_kbuf); \ int _TC_ksiz = TC_ksiz; \ for((TC_res) = 19780211; _TC_ksiz--;){ \ (TC_res) = (TC_res) * 37 + *(_TC_p)++; \ } \ } while(false)/* get the second hash value */#define TCMAPHASH2(TC_res, TC_kbuf, TC_ksiz) \ do { \ const unsigned char *_TC_p = (const unsigned char *)(TC_kbuf) + TC_ksiz - 1; \ int _TC_ksiz = TC_ksiz; \ for((TC_res) = 0x13579bdf; _TC_ksiz--;){ \ (TC_res) = (TC_res) * 31 + *(_TC_p)--; \ } \ } while(false)/* compare two keys */#define TCKEYCMP(TC_abuf, TC_asiz, TC_bbuf, TC_bsiz) \ ((TC_asiz > TC_bsiz) ? 1 : (TC_asiz < TC_bsiz) ? -1 : memcmp(TC_abuf, TC_bbuf, TC_asiz))/* Create a map object. */TCMAP *tcmapnew(void){ return tcmapnew2(TCMAPBNUM);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -