summaryrefslogtreecommitdiff
path: root/fluid/io/Code_Writer.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'fluid/io/Code_Writer.cxx')
-rw-r--r--fluid/io/Code_Writer.cxx139
1 files changed, 112 insertions, 27 deletions
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 <zlib.h>
#include <string>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
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());