summaryrefslogtreecommitdiff
path: root/fluid
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2023-09-05 15:11:09 +0200
committerMatthias Melcher <github@matthiasm.com>2023-09-05 15:11:09 +0200
commit2e38007d1f1d6b13ad0ba5303bf58169ffb8da27 (patch)
tree830ca1910666e2a14a5d04da8df19ab2428fb014 /fluid
parent6bb5a81cee7e76e8a4e69f7f49869f39c1c382f0 (diff)
FLUID: increases readability
- removed some direct filename manipulation - central place to generate file names and paths - fixes command line filename override if no actual batch command is given
Diffstat (limited to 'fluid')
-rw-r--r--fluid/code.cxx8
-rw-r--r--fluid/code.h3
-rw-r--r--fluid/file.cxx9
-rw-r--r--fluid/fluid.cxx201
-rw-r--r--fluid/fluid.h13
-rw-r--r--fluid/sourceview_panel.cxx2
6 files changed, 183 insertions, 53 deletions
diff --git a/fluid/code.cxx b/fluid/code.cxx
index 7a3725ee0..561d6fca7 100644
--- a/fluid/code.cxx
+++ b/fluid/code.cxx
@@ -44,14 +44,14 @@ int is_id(char c) {
}
/**
- Write a file that contains all label and tooltip strings for internationalization.
+ Write a file that contains all label and tooltip strings for internationalisation.
*/
-int write_strings(const char *sfile) {
- FILE *fp = fl_fopen(sfile, "w");
+int write_strings(const Fl_String &filename) {
Fl_Type *p;
Fl_Widget_Type *w;
int i;
+ FILE *fp = fl_fopen(filename.c_str(), "w");
if (!fp) return 1;
switch (g_project.i18n_type) {
@@ -799,7 +799,7 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview)
write_c("// Initialize I18N stuff now for menus...\n");
write_c("#%sinclude <locale.h>\n", indent());
write_c("static char *_locale = setlocale(LC_MESSAGES, \"\");\n");
- write_c("static nl_catd _catalog = catopen(\"%s\", 0);\n", g_project.basename.c_str());
+ write_c("static nl_catd _catalog = catopen(\"%s\", 0);\n", g_project.basename().c_str());
}
}
if (conditional) {
diff --git a/fluid/code.h b/fluid/code.h
index 1b596075c..c327b9f21 100644
--- a/fluid/code.h
+++ b/fluid/code.h
@@ -18,6 +18,7 @@
#define _FLUID_CODE_H
#include <FL/fl_attr.h>
+#include <FL/Fl_String.H>
#include <stdarg.h>
#include <stdio.h>
@@ -28,7 +29,7 @@ struct Fd_Text_Tree;
struct Fd_Pointer_Tree;
int is_id(char c);
-int write_strings(const char *sfile);
+int write_strings(const Fl_String &filename);
class Fd_Code_Writer
{
diff --git a/fluid/file.cxx b/fluid/file.cxx
index 1c49d8574..163b41dee 100644
--- a/fluid/file.cxx
+++ b/fluid/file.cxx
@@ -419,14 +419,17 @@ int Fd_Project_Reader::read_project(const char *filename, int merge, Strategy st
read_children(Fl_Type::current, merge, strategy);
Fl_Type::current = 0;
// Force menu items to be rebuilt...
- for (o = Fl_Type::first; o; o = o->next)
- if (o->is_a(Fl_Type::ID_Menu_Manager_))
+ for (o = Fl_Type::first; o; o = o->next) {
+ if (o->is_a(Fl_Type::ID_Menu_Manager_)) {
o->add_child(0,0);
- for (o = Fl_Type::first; o; o = o->next)
+ }
+ }
+ for (o = Fl_Type::first; o; o = o->next) {
if (o->selected) {
Fl_Type::current = o;
break;
}
+ }
selection_changed(Fl_Type::current);
shell_settings_read();
int ret = close_read();
diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx
index 788ed241e..ef2ba390e 100644
--- a/fluid/fluid.cxx
+++ b/fluid/fluid.cxx
@@ -170,6 +170,7 @@ int batch_mode = 0; // if set (-c, -u) don't open display
/// command line arguments override settings in the projectfile
Fl_String g_code_filename_arg;
Fl_String g_header_filename_arg;
+Fl_String g_launch_path;
/** \var int Fluid_Project::header_file_set
If set, commandline overrides header file name in .fl file.
@@ -302,7 +303,6 @@ void Fluid_Project::reset() {
i18n_pos_file = "";
i18n_pos_set = "1";
- basename = "";
include_H_from_C = 1;
use_FL_COMMAND = 0;
utf8_in_src = 0;
@@ -985,6 +985,112 @@ void apple_open_cb(const char *c) {
}
#endif // __APPLE__
+// make sure that a path nae ends with a forward slash
+static Fl_String end_with_slash(const Fl_String &str) {
+ char last = str[str.size()-1];
+ if (last !='/' && last != '\\')
+ return str + "/";
+ else
+ return str;
+}
+
+/**
+ Get the absolute path of the project file, for example `/Users/matt/dev/`.
+ */
+Fl_String Fluid_Project::projectfile_path() const {
+ return end_with_slash(fl_filename_absolute(fl_filename_path(filename), g_launch_path));
+}
+
+/**
+ Get the project file name including extension, for example `test.fl`.
+ */
+Fl_String Fluid_Project::projectfile_name() const {
+ return fl_filename_name(filename);
+}
+
+/**
+ Get the absolute path of the generated C++ code file, for example `/Users/matt/dev/src/`.
+ */
+Fl_String Fluid_Project::codefile_path() const {
+ Fl_String path = fl_filename_path(code_file_name);
+ if (batch_mode)
+ return end_with_slash(fl_filename_absolute(path, g_launch_path));
+ else
+ return end_with_slash(fl_filename_absolute(path, projectfile_path()));
+}
+
+/**
+ Get the generated C++ code file name including extension, for example `test.cxx`.
+ */
+Fl_String Fluid_Project::codefile_name() const {
+ Fl_String name = fl_filename_name(code_file_name);
+ if (name.empty()) {
+ return fl_filename_setext(fl_filename_name(filename), ".cxx");
+ } else if (name[0] == '.') {
+ return fl_filename_setext(fl_filename_name(filename), code_file_name);
+ } else {
+ return name;
+ }
+}
+
+/**
+ Get the absolute path of the generated C++ header file, for example `/Users/matt/dev/src/`.
+ */
+Fl_String Fluid_Project::headerfile_path() const {
+ Fl_String path = fl_filename_path(header_file_name);
+ if (batch_mode)
+ return end_with_slash(fl_filename_absolute(path, g_launch_path));
+ else
+ return end_with_slash(fl_filename_absolute(path, projectfile_path()));
+}
+
+/**
+ Get the generated C++ header file name including extension, for example `test.cxx`.
+ */
+Fl_String Fluid_Project::headerfile_name() const {
+ Fl_String name = fl_filename_name(header_file_name);
+ if (name.empty()) {
+ return fl_filename_setext(fl_filename_name(filename), ".h");
+ } else if (name[0] == '.') {
+ return fl_filename_setext(fl_filename_name(filename), header_file_name);
+ } else {
+ return name;
+ }
+}
+
+/**
+ Get the absolute path of the generated i18n strings file, for example `/Users/matt/dev/`.
+ Although it may be more useful to put the text file into the same directory
+ with the source and header file, historically, the text is always saved with
+ the project file in interactive mode, and in the FLUID launch directory in
+ batch mode.
+ */
+Fl_String Fluid_Project::stringsfile_path() const {
+ if (batch_mode)
+ return end_with_slash(g_launch_path);
+ else
+ return projectfile_path();
+}
+
+/**
+ Get the generated i18n text file name including extension, for example `test.po`.
+ */
+Fl_String Fluid_Project::stringsfile_name() const {
+ switch (i18n_type) {
+ default: return fl_filename_setext(fl_filename_name(filename), ".txt");
+ case 1: return fl_filename_setext(fl_filename_name(filename), ".po");
+ case 2: return fl_filename_setext(fl_filename_name(filename), ".msg");
+ }
+}
+
+/**
+ Get the name of the project file without the filename extension.
+ */
+Fl_String Fluid_Project::basename() const {
+ return fl_filename_setext(fl_filename_name(filename), "");
+}
+
+
/**
Generate the C++ source and header filenames and write those files.
@@ -1004,43 +1110,46 @@ void apple_open_cb(const char *c) {
\return 1 if the operation failed, 0 if it succeeded
*/
-int write_code_files() {
+int write_code_files()
+{
+ // -- handle user interface issues
flush_text_widgets();
if (!filename) {
save_cb(0,0);
if (!filename) return 1;
}
- char cname[FL_PATH_MAX+1];
- char hname[FL_PATH_MAX+1];
- g_project.basename = fl_filename_name(filename);
- g_project.basename = fl_filename_setext(g_project.basename, "");
- if (g_project.code_file_name[0] == '.' && strchr(g_project.code_file_name.c_str(), '/') == NULL) {
- strlcpy(cname, fl_filename_name(filename), FL_PATH_MAX);
- fl_filename_setext(cname, FL_PATH_MAX, g_project.code_file_name.c_str());
- } else {
- strlcpy(cname, g_project.code_file_name.c_str(), FL_PATH_MAX);
- }
- if (g_project.header_file_name[0] == '.' && strchr(g_project.header_file_name.c_str(), '/') == NULL) {
- strlcpy(hname, fl_filename_name(filename), FL_PATH_MAX);
- fl_filename_setext(hname, FL_PATH_MAX, g_project.header_file_name.c_str());
- } else {
- strlcpy(hname, g_project.header_file_name.c_str(), FL_PATH_MAX);
- }
- if (!batch_mode) enter_project_dir();
+
+ // -- generate the file names with absolute paths
Fd_Code_Writer f;
- int x = f.write_code(cname, hname);
+ Fl_String code_filename = g_project.codefile_path() + g_project.codefile_name();
+ Fl_String header_filename = g_project.headerfile_path() + g_project.headerfile_name();
+
+ // -- write the code and header files
+ if (!batch_mode) enter_project_dir();
+ int x = f.write_code(code_filename.c_str(), header_filename.c_str());
if (!batch_mode) leave_project_dir();
- strlcat(cname, " and ", FL_PATH_MAX);
- strlcat(cname, hname, FL_PATH_MAX);
+
+ // -- print error message in batch mode or pop up an error or confirmation dialog box
if (batch_mode) {
- if (!x) {fprintf(stderr,"%s : %s\n",cname,strerror(errno)); exit(1);}
+ if (!x) {
+ fprintf(stderr, "%s and %s: %s\n",
+ code_filename.c_str(),
+ header_filename.c_str(),
+ strerror(errno));
+ exit(1);
+ }
} else {
if (!x) {
- fl_message("Can't write %s: %s", cname, strerror(errno));
+ fl_message("Can't write %s and %s: %s",
+ code_filename.c_str(),
+ header_filename.c_str(),
+ strerror(errno));
} else {
set_modflag(-1, 0);
if (completion_button->value()) {
- fl_message("Wrote %s", cname);
+ fl_message("Wrote %s and %s",
+ g_project.codefile_name().c_str(),
+ g_project.headerfile_name().c_str());
}
}
}
@@ -1064,19 +1173,18 @@ void write_strings_cb(Fl_Widget *, void *) {
save_cb(0,0);
if (!filename) return;
}
- char sname[FL_PATH_MAX];
- strlcpy(sname, fl_filename_name(filename), sizeof(sname));
- fl_filename_setext(sname, sizeof(sname), exts[g_project.i18n_type]);
- if (!batch_mode) enter_project_dir();
- int x = write_strings(sname);
- if (!batch_mode) leave_project_dir();
+ Fl_String filename = g_project.stringsfile_path() + g_project.stringsfile_name();
+ int x = write_strings(filename);
if (batch_mode) {
- if (x) {fprintf(stderr,"%s : %s\n",sname,strerror(errno)); exit(1);}
+ if (x) {
+ fprintf(stderr, "%s : %s\n", filename.c_str(), strerror(errno));
+ exit(1);
+ }
} else {
if (x) {
- fl_message("Can't write %s: %s", sname, strerror(errno));
+ fl_message("Can't write %s: %s", filename.c_str(), strerror(errno));
} else if (completion_button->value()) {
- fl_message("Wrote %s", sname);
+ fl_message("Wrote %s", g_project.stringsfile_name().c_str());
}
}
}
@@ -1389,7 +1497,7 @@ static void menu_file_open_history_cb(Fl_Widget *, void *v) { open_project_file(
\c New_Menu creates new widgets and is explained in detail in another location.
\see New_Menu
- \todo This menu need some major modernization. Menus are too long and their
+ \todo This menu need some major modernisation. Menus are too long and their
sorting is not always obvious.
\todo Shortcuts are all over the place (Alt, Ctrl, Command, Shift-Ctrl,
function keys), and there should be a help page listing all shortcuts.
@@ -1887,6 +1995,7 @@ int main(int argc,char **argv) {
setlocale(LC_ALL, ""); // enable multi-language errors in file chooser
setlocale(LC_NUMERIC, "C"); // make sure numeric values are written correctly
+ g_launch_path = end_with_slash(fl_getcwd()); // store the current path at launch
if ( (Fl::args(argc,argv,i,arg) == 0) // unsupported argument found
|| (batch_mode && (i != argc-1)) // .fl filename missing
@@ -1947,13 +2056,16 @@ int main(int argc,char **argv) {
undo_resume();
// command line args override code and header filenames from the project file
- if (!g_code_filename_arg.empty()) {
- g_project.code_file_set = 1;
- g_project.code_file_name = g_code_filename_arg;
- }
- if (!g_header_filename_arg.empty()) {
- g_project.header_file_set = 1;
- g_project.header_file_name = g_header_filename_arg;
+ // in batch mode only
+ if (batch_mode) {
+ if (!g_code_filename_arg.empty()) {
+ g_project.code_file_set = 1;
+ g_project.code_file_name = g_code_filename_arg;
+ }
+ if (!g_header_filename_arg.empty()) {
+ g_project.header_file_set = 1;
+ g_project.header_file_name = g_header_filename_arg;
+ }
}
if (update_file) { // fluid -u
@@ -1968,6 +2080,11 @@ int main(int argc,char **argv) {
write_cb(0,0);
exit(0);
}
+
+ // don't lock up if silly command line arguments were given
+ if (batch_mode)
+ exit(0);
+
set_modflag(0);
undo_clear();
#ifndef _WIN32
diff --git a/fluid/fluid.h b/fluid/fluid.h
index e52828fa7..024dc61ff 100644
--- a/fluid/fluid.h
+++ b/fluid/fluid.h
@@ -90,6 +90,16 @@ public:
void reset();
void update_settings_dialog();
+ Fl_String projectfile_path() const;
+ Fl_String projectfile_name() const;
+ Fl_String codefile_path() const;
+ Fl_String codefile_name() const;
+ Fl_String headerfile_path() const;
+ Fl_String headerfile_name() const;
+ Fl_String stringsfile_path() const;
+ Fl_String stringsfile_name() const;
+ Fl_String basename() const;
+
int i18n_type;
Fl_String i18n_gnu_include;
Fl_String i18n_gnu_conditional;
@@ -101,7 +111,6 @@ public:
Fl_String i18n_pos_file;
Fl_String i18n_pos_set;
- Fl_String basename;
int include_H_from_C;
int use_FL_COMMAND;
int utf8_in_src;
@@ -116,6 +125,8 @@ extern Fluid_Project g_project;
extern Fl_String g_code_filename_arg;
extern Fl_String g_header_filename_arg;
+extern Fl_String g_launch_path;
+
// ---- public functions
diff --git a/fluid/sourceview_panel.cxx b/fluid/sourceview_panel.cxx
index f29f0bcb8..2cd008f85 100644
--- a/fluid/sourceview_panel.cxx
+++ b/fluid/sourceview_panel.cxx
@@ -116,8 +116,6 @@ void update_sourceview_cb(class Fl_Button*, void*) {
sv_strings->buffer()->loadfile(fn);
sv_strings->scroll(top, 0);
} else if (sv_source->visible_r() || sv_header->visible_r()) {
- g_project.basename = fl_filename_name(sv_source_filename);
- g_project.basename = fl_filename_setext(g_project.basename, "");
Fl_String code_file_name_bak = g_project.code_file_name;
g_project.code_file_name = sv_source_filename;
Fl_String header_file_name_bak = g_project.header_file_name;