summaryrefslogtreecommitdiff
path: root/fluid/io
diff options
context:
space:
mode:
Diffstat (limited to 'fluid/io')
-rw-r--r--fluid/io/Code_Writer.cxx59
-rw-r--r--fluid/io/Project_Reader.cxx5
-rw-r--r--fluid/io/Project_Writer.cxx3
3 files changed, 57 insertions, 10 deletions
diff --git a/fluid/io/Code_Writer.cxx b/fluid/io/Code_Writer.cxx
index 086244035..8bcef2f33 100644
--- a/fluid/io/Code_Writer.cxx
+++ b/fluid/io/Code_Writer.cxx
@@ -27,6 +27,11 @@
#include <zlib.h>
+#include <string>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
using namespace fld;
using namespace fld::io;
using namespace fld::proj;
@@ -624,15 +629,51 @@ int Code_Writer::write_code(const char *s, const char *t, bool to_codeview) {
// generated by Fast Light User Interface Designer (fluid) version %.4f\n\n";
fprintf(header_file, hdr, FL_VERSION);
crc_printf(hdr, FL_VERSION);
-
- {char define_name[102];
- const char* a = fl_filename_name(t);
- char* b = define_name;
- if (!isalpha(*a)) {*b++ = '_';}
- while (*a) {*b++ = isalnum(*a) ? *a : '_'; a++;}
- *b = 0;
- fprintf(header_file, "#ifndef %s\n", define_name);
- fprintf(header_file, "#define %s\n", define_name);
+ {
+ // Creating the include guard is more involved than it seems at first glance.
+ // The include guard is deduced from header filename. However, if the
+ // filename contains unicode characters, they need to be encoded using
+ // \Uxxxxxxxx or \\uxxxx encoding to form a valid macro identifier.
+ //
+ // But that approach is not portable. Windows does not normalize Unicode
+ // (ö is the letter \u00F6). macOS normalizes to NFD (ö is \u006F\u0308,
+ // o followed by a Combining Diaresis ¨).
+ //
+ // To make the include guard consistent across l=platforms, it can be
+ // 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;
+ std::string header_name;
+ const char* a = nullptr;
+ if (write_codeview) {
+ header_name = proj_.headerfile_name();
+ a = header_name.c_str();
+ } else {
+ a = fl_filename_name(t);
+ }
+ const char* b = a + strlen(a);
+ int len = 0;
+ unsigned ucs = fl_utf8decode(a, b, &len);
+ if ((ucs > 127) || (!isalpha(ucs) && (ucs != '_')))
+ macro_name << '_';
+ while (a < b) {
+ ucs = fl_utf8decode(a, b, &len);
+ if ((ucs == '.') || (ucs == '_')) {
+ macro_name << '_';
+ } else if (ucs > 0x0000ffff) { // large unicode character
+ macro_name << "\\U" << std::setw(8) << std::setfill('0') << std::hex << ucs;
+ } else if ((ucs > 127) || !isalnum(ucs)) { // small unicode character or not an ASCI letter or digit
+ macro_name << "\\u" << std::setw(4) << std::setfill('0') << std::hex << ucs;
+ } else {
+ macro_name << (char)ucs;
+ }
+ a += len;
+ }
+ macro_name_str = macro_name.str();
+ }
+ fprintf(header_file, "#ifndef %s\n", macro_name_str.c_str());
+ fprintf(header_file, "#define %s\n", macro_name_str.c_str());
}
if (proj_.avoid_early_includes==0) {
diff --git a/fluid/io/Project_Reader.cxx b/fluid/io/Project_Reader.cxx
index c420824aa..0e2809685 100644
--- a/fluid/io/Project_Reader.cxx
+++ b/fluid/io/Project_Reader.cxx
@@ -277,6 +277,11 @@ Node *Project_Reader::read_children(Node *p, int merge, Strategy strategy, char
goto CONTINUE;
}
+ if (!strcmp(c,"include_guard")) {
+ proj_.include_guard = read_word();
+ goto CONTINUE;
+ }
+
if (!strcmp(c, "snap")) {
Fluid.layout_list.read(this);
goto CONTINUE;
diff --git a/fluid/io/Project_Writer.cxx b/fluid/io/Project_Writer.cxx
index 1975ef85d..387c0093f 100644
--- a/fluid/io/Project_Writer.cxx
+++ b/fluid/io/Project_Writer.cxx
@@ -115,12 +115,13 @@ int Project_Writer::write_project(const char *filename, int selected_only, bool
write_string("\nutf8_in_src");
if (proj_.avoid_early_includes)
write_string("\navoid_early_includes");
-
+
proj_.i18n.write(*this);
if (!selected_only) {
write_string("\nheader_name"); write_word(proj_.header_file_name.c_str());
write_string("\ncode_name"); write_word(proj_.code_file_name.c_str());
+ write_string("\ninclude_guard"); write_word(proj_.include_guard.c_str());
Fluid.layout_list.write(this);
if (g_shell_config)
g_shell_config->write(this);