From 4ce4967c33d56e4b56d85d11fe0e0be91e159f5d Mon Sep 17 00:00:00 2001 From: maxim nikonov Date: Fri, 6 Feb 2026 00:00:50 +0500 Subject: wip --- fluid/io/Code_Writer.cxx | 139 ++++++++++++++++++++++++++++++++++++++--------- fluid/io/Code_Writer.h | 59 +++++++++++++++++--- 2 files changed, 162 insertions(+), 36 deletions(-) (limited to 'fluid/io') diff --git a/fluid/io/Code_Writer.cxx b/fluid/io/Code_Writer.cxx index 916d024bd..0998ed287 100644 --- a/fluid/io/Code_Writer.cxx +++ b/fluid/io/Code_Writer.cxx @@ -28,14 +28,100 @@ #include #include -#include -#include -#include +#include +#include +#include using namespace fld; using namespace fld::io; using namespace fld::proj; +// ---- Fd_Id_Map implementation ---- + +void Fd_Id_Map::clear() { + int i; + for (i = 0; i < count; i++) { + free(entries[i].key); + } + free(entries); + entries = 0; + count = 0; + capacity = 0; +} + +const char *Fd_Id_Map::find_or_insert(const char *key, void *value, void **found_value) { + int i; + for (i = 0; i < count; i++) { + if (strcmp(entries[i].key, key) == 0) { + *found_value = entries[i].value; + return entries[i].key; + } + } + // Not found, insert + if (count >= capacity) { + capacity = capacity ? capacity * 2 : 16; + entries = (Fd_Id_Entry*)realloc(entries, capacity * sizeof(Fd_Id_Entry)); + } + entries[count].key = strdup(key); + entries[count].value = value; + *found_value = value; + return entries[count++].key; +} + +// ---- Fd_String_Set implementation ---- + +void Fd_String_Set::clear() { + int i; + for (i = 0; i < count; i++) { + free(strings[i]); + } + free(strings); + strings = 0; + count = 0; + capacity = 0; +} + +bool Fd_String_Set::contains(const char *s) { + int i; + for (i = 0; i < count; i++) { + if (strcmp(strings[i], s) == 0) return true; + } + return false; +} + +void Fd_String_Set::insert(const char *s) { + if (count >= capacity) { + capacity = capacity ? capacity * 2 : 16; + strings = (char**)realloc(strings, capacity * sizeof(char*)); + } + strings[count++] = strdup(s); +} + +// ---- Fd_Pointer_Set implementation ---- + +void Fd_Pointer_Set::clear() { + free(pointers); + pointers = 0; + count = 0; + capacity = 0; +} + +bool Fd_Pointer_Set::contains(void *p) { + int i; + for (i = 0; i < count; i++) { + if (pointers[i] == p) return true; + } + return false; +} + +void Fd_Pointer_Set::insert(void *p) { + if (count >= capacity) { + capacity = capacity ? capacity * 2 : 16; + pointers = (void**)realloc(pointers, capacity * sizeof(void*)); + } + pointers[count++] = p; +} + /** Return true if c can be in a C identifier. I needed this so it is not messed up by locale settings. @@ -76,18 +162,14 @@ const char* Code_Writer::unique_id(void* o, const char* type, const char* name, // okay, search the tree and see if the name was already used: int which = 0; for (;;) { - auto it = unique_id_list.find(buffer); - // If the id does not exist, add it to the map - if (it == unique_id_list.end()) { - it = unique_id_list.insert(std::make_pair(buffer, o)).first; - return it->first.c_str(); - } - // If it does exist, and the pointers are the same, just return it. - if (it->second == o) { - return it->first.c_str(); + void *found_value = 0; + const char *key = unique_id_list.find_or_insert(buffer, o, &found_value); + // If found_value matches o, we either inserted new or found existing with same pointer + if (found_value == o) { + return key; } - // Else repeat until we have a new id, - sprintf(q,"%x",++which); + // Else the id exists with a different pointer, try next + sprintf(q, "%x", ++which); } } @@ -148,7 +230,7 @@ int Code_Writer::write_h_once(const char *format, ...) { va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); va_end(args); - if (text_in_header.find(buf) != text_in_header.end()) { + if (text_in_header.contains(buf)) { return 0; } fprintf(header_file, "%s\n", buf); @@ -169,11 +251,11 @@ int Code_Writer::write_c_once(const char *format, ...) { vsnprintf(buf, sizeof(buf), format, args); va_end(args); // Return if the text was already printed to the header file. - if (text_in_header.find(buf) != text_in_header.end()) { + if (text_in_header.contains(buf)) { return 0; } // Return if the text was already printed to the source file. - if (text_in_code.find(buf) != text_in_code.end()) { + if (text_in_code.contains(buf)) { return 0; } crc_printf("%s\n", buf); @@ -188,7 +270,7 @@ int Code_Writer::write_c_once(const char *format, ...) { \return true if found in the tree, false if added to the tree */ bool Code_Writer::c_contains(void *pp) { - if (ptr_in_code.find(pp) != ptr_in_code.end()) { + if (ptr_in_code.contains(pp)) { return true; } ptr_in_code.insert(pp); @@ -643,9 +725,11 @@ int Code_Writer::write_code(const char *s, const char *t, bool to_codeview) { // explicitly set by the user in the Project Settings. std::string macro_name_str = proj_.include_guard; if (macro_name_str.empty()) { - std::ostringstream macro_name; + char macro_name[1024]; + char *mp = macro_name; + char *mp_end = macro_name + sizeof(macro_name) - 16; std::string header_name; - const char* a = nullptr; + const char* a = 0; if (write_codeview) { header_name = proj_.headerfile_name(); a = header_name.c_str(); @@ -656,21 +740,22 @@ int Code_Writer::write_code(const char *s, const char *t, bool to_codeview) { int len = 0; unsigned ucs = fl_utf8decode(a, b, &len); if ((ucs > 127) || (!isalpha(ucs) && (ucs != '_'))) - macro_name << '_'; - while (a < b) { + *mp++ = '_'; + while (a < b && mp < mp_end) { ucs = fl_utf8decode(a, b, &len); if (ucs > 0x0000ffff) { // large unicode character - macro_name << "\\U" << std::setw(8) << std::setfill('0') << std::hex << ucs; + mp += sprintf(mp, "\\U%08x", ucs); } else if (ucs > 127) { // small unicode character or not an ASCI letter or digit - macro_name << "\\u" << std::setw(4) << std::setfill('0') << std::hex << ucs; + mp += sprintf(mp, "\\u%04x", ucs); } else if (!isalnum(ucs)) { - macro_name << '_'; + *mp++ = '_'; } else { - macro_name << (char)ucs; + *mp++ = (char)ucs; } a += len; } - macro_name_str = macro_name.str(); + *mp = 0; + macro_name_str = macro_name; } fprintf(header_file, "#ifndef %s\n", macro_name_str.c_str()); fprintf(header_file, "#define %s\n", macro_name_str.c_str()); diff --git a/fluid/io/Code_Writer.h b/fluid/io/Code_Writer.h index c199197ec..9d52e0600 100644 --- a/fluid/io/Code_Writer.h +++ b/fluid/io/Code_Writer.h @@ -23,14 +23,55 @@ #include #include +#include +#include #include -#include -#include class Node; -struct Fd_Identifier_Tree; -struct Fd_Text_Tree; -struct Fd_Pointer_Tree; + +/** Simple string-to-pointer map entry */ +struct Fd_Id_Entry { + char *key; + void *value; +}; + +/** Simple string-to-pointer map (unsorted array, linear search) */ +struct Fd_Id_Map { + Fd_Id_Entry *entries; + int count; + int capacity; + + Fd_Id_Map() : entries(0), count(0), capacity(0) {} + ~Fd_Id_Map() { clear(); } + void clear(); + const char *find_or_insert(const char *key, void *value, void **found_value); +}; + +/** Simple string set (unsorted array, linear search) */ +struct Fd_String_Set { + char **strings; + int count; + int capacity; + + Fd_String_Set() : strings(0), count(0), capacity(0) {} + ~Fd_String_Set() { clear(); } + void clear(); + bool contains(const char *s); + void insert(const char *s); +}; + +/** Simple pointer set (unsorted array, linear search) */ +struct Fd_Pointer_Set { + void **pointers; + int count; + int capacity; + + Fd_Pointer_Set() : pointers(0), count(0), capacity(0) {} + ~Fd_Pointer_Set() { clear(); } + void clear(); + bool contains(void *p); + void insert(void *p); +}; int is_id(char c); @@ -52,13 +93,13 @@ private: FILE *header_file = nullptr; /// tree of unique but human-readable identifiers - std::map unique_id_list { }; + Fd_Id_Map unique_id_list; /// searchable text tree for text that is only written once to the header file - std::set text_in_header { }; + Fd_String_Set text_in_header; /// searchable text tree for text that is only written once to the code file - std::set text_in_code { }; + Fd_String_Set text_in_code; /// searchable tree for pointers that are only written once to the code file - std::set ptr_in_code { }; + Fd_Pointer_Set ptr_in_code; /// crc32 for blocks of text written to the code file unsigned long block_crc_ = 0; -- cgit v1.2.3