#define SFT_GENERIC 1 public U8 **StrFileRead(U8 *name, I64 *_max_num=NULL, U8 **_colors=NULL, Bool no_nums=FALSE) { CDoc *doc = DocRead(name, DOCF_DBL_DOLLARS | DOCF_NO_CURSOR); CDocEntry *doc_e = doc->head.next; I64 i, max_num = 0; U8 *ptr, **res, *colors; while (doc_e != doc) { if (doc_e->type_u8 == DOCT_TEXT) { if (no_nums) i = ++max_num; else { i = Str2I64(doc_e->tag,, &ptr); if (i > max_num) max_num = i; if (*ptr == ', ') ptr++; ptr = StrNew(ptr); Free(doc_e->tag); doc_e->tag = ptr; } doc_e->user_data = i; } doc_e = doc_e->next; } res = CAlloc(sizeof(U8 *) * (max_num + 1)); colors = CAlloc(sizeof(U8) * (max_num + 1)); doc_e = doc->head.next; while (doc_e != doc) { if (doc_e->type_u8 == DOCT_TEXT && 0 <= doc_e->user_data <= max_num) { res[doc_e->user_data] = doc_e->tag; doc_e->tag = NULL; colors[doc_e->user_data] = doc_e->type.u8[1] & 15; } doc_e = doc_e->next; } DocDel(doc); if (_max_num) *_max_num = max_num; if (_colors) *_colors = colors; else Free(colors); return res; } public U0 StrFileArrDel(U8 **a, I64 max_num) { I64 i; for (i = 0; i <= max_num; i++) Free(a[i]); Free(a); } public I64 StrFileAdd(U8 *st, I64 *_num, CHashTable *table, I64 color=COLOR_INVALID) { CHashGeneric *tmph; if (!st) return 0; if (!(tmph = HashFind(st, table, SFT_GENERIC))) { tmph = CAlloc(sizeof(CHashGeneric)); tmph->type = SFT_GENERIC; tmph->str = StrNew(st); tmph->user_data0 = (*_num)++; HashAdd(tmph, table); } if (color != COLOR_INVALID) tmph->user_data1 = color; return tmph->user_data0; } I64 StrEntriesCompare(CHashGeneric *h1, CHashGeneric *h2) { return h1->user_data0 - h2->user_data0; } public U0 StrFileWrite(U8 *name, CHashTable *table, Bool no_nums=FALSE) { I64 i, j, count, color = BLACK; CDoc *doc = DocNew(name); CHashGeneric *tmph, **a; if (table) { count = 0; //Count Strings for (i = 0; i <= table->mask; i++) count += LinkedListCount(table->body[i]); a = MAlloc(count * sizeof(CHashGeneric *)); j = 0; //Load Strings for (i = 0; i <= table->mask; i++) { tmph = table->body[i]; while (tmph) { a[j++] = tmph; tmph = tmph->next; } } QuickSortI64(a, count, &StrEntriesCompare); for (i = 0; i < count; i++) { tmph = a[i]; if (tmph->user_data1 & 15 != color) { DocPrint(doc, "$FG,%d$", tmph->user_data1 & 15); color = tmph->user_data1 & 15; } if (no_nums) DocPrint(doc, "%s\n", tmph->str); else DocPrint(doc, "%d,%s\n", tmph->user_data0, tmph->str); } Free(a); } doc->flags |= DOCF_NO_CURSOR; DocWrite(doc); DocDel(doc); } public U0 StrFileDel(CHashTable *table) { I64 i; CHashGeneric *tmph, *tmph1; if (!table) return; for (i = 0; i <= table->mask; i++) { tmph = table->body[i]; while (tmph) { tmph1=tmph->next; Free(tmph->str); Free(tmph); tmph = tmph1; } } Free(table->body); Free(table); }