diff options
Diffstat (limited to 'fluid/io')
| -rw-r--r-- | fluid/io/Code_Writer.cxx | 59 | ||||
| -rw-r--r-- | fluid/io/Project_Reader.cxx | 5 | ||||
| -rw-r--r-- | fluid/io/Project_Writer.cxx | 3 |
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); |
