summaryrefslogtreecommitdiff
path: root/fluid/app
diff options
context:
space:
mode:
authormaxim nikonov <maxim.nikonov@hqo.co>2026-02-06 02:33:41 +0500
committermaxim nikonov <maxim.nikonov@hqo.co>2026-02-06 02:33:41 +0500
commit43e0a37906afabb0b3b091b8d3eac9a910cae50c (patch)
treed2a037c2bf0dc395fddb08e32ebfcf2795503b7c /fluid/app
parent4ce4967c33d56e4b56d85d11fe0e0be91e159f5d (diff)
wip
Diffstat (limited to 'fluid/app')
-rw-r--r--fluid/app/Image_Asset.cxx22
-rw-r--r--fluid/app/Image_Asset.h2
-rw-r--r--fluid/app/Menu.cxx79
-rw-r--r--fluid/app/Snap_Action.cxx44
-rw-r--r--fluid/app/args.cxx56
-rw-r--r--fluid/app/args.h19
-rw-r--r--fluid/app/history.cxx62
-rw-r--r--fluid/app/history.h11
-rw-r--r--fluid/app/shell_command.cxx537
-rw-r--r--fluid/app/shell_command.h64
-rw-r--r--fluid/app/templates.cxx4
11 files changed, 467 insertions, 433 deletions
diff --git a/fluid/app/Image_Asset.cxx b/fluid/app/Image_Asset.cxx
index 09550fac0..cea3cc058 100644
--- a/fluid/app/Image_Asset.cxx
+++ b/fluid/app/Image_Asset.cxx
@@ -209,8 +209,8 @@ void Image_Asset::write_static_rgb(fld::io::Code_Writer& f, const char* idata_na
*/
void Image_Asset::write_static(fld::io::Code_Writer& f, int compressed) {
if (!image_) return;
- const char *idata_name = f.unique_id(this, "idata", fl_filename_name(filename()), nullptr);
- initializer_function_ = f.unique_id(this, "image", fl_filename_name(filename()), nullptr);
+ const char *idata_name = f.unique_id(this, "idata", fl_filename_name(filename()), 0);
+ initializer_function_ = f.unique_id(this, "image", fl_filename_name(filename()), 0);
if (is_animated_gif_) {
// Write animated gif image data...
@@ -309,8 +309,8 @@ void Image_Asset::write_static(fld::io::Code_Writer& f, int compressed) {
} else {
// if FLUID runs from the command line, make sure that the image is not
// only loaded but also rasterized, so we can write the RGB image data
- Fl_RGB_Image* rgb_image = nullptr;
- Fl_SVG_Image* svg_image = nullptr;
+ Fl_RGB_Image* rgb_image = 0;
+ Fl_SVG_Image* svg_image = 0;
if (image_->d()>0)
rgb_image = (Fl_RGB_Image*)image_->image();
if (rgb_image)
@@ -343,7 +343,7 @@ void Image_Asset::write_static(fld::io::Code_Writer& f, int compressed) {
void Image_Asset::write_file_error(fld::io::Code_Writer& f, const char *fmt) {
f.write_c("#warning Cannot read %s file \"%s\": %s\n", fmt, filename(), strerror(errno));
Fluid.proj.enter_project_dir();
- f.write_c("// Searching in path \"%s\"\n", fl_getcwd(nullptr, FL_PATH_MAX));
+ f.write_c("// Searching in path \"%s\"\n", fl_getcwd(0, FL_PATH_MAX));
Fluid.proj.leave_project_dir();
}
@@ -434,10 +434,10 @@ void Image_Asset::write_inline(fld::io::Code_Writer& f, int inactive) {
If the image asset has already been loaded, it is returned from the cache.
If the image asset has not been loaded, it is loaded from the file system.
- If the image asset cannot be loaded, nullptr is returned.
+ If the image asset cannot be loaded, 0 is returned.
\param iname The filename of the image asset to find.
- \returns The image asset, or nullptr if it cannot be loaded.
+ \returns The image asset, or 0 if it cannot be loaded.
*/
Image_Asset* Image_Asset::find(const char *iname) {
if (!iname || !*iname) return 0;
@@ -553,12 +553,12 @@ Image_Asset::~Image_Asset() {
.pgm, .png, .ppm, .xbm, .xpm, and .svg (and .svgz if zlib support is
enabled). The function returns a pointer to an Image_Asset object that
references the selected image. If the user cancels the file chooser or
- selects a file that does not exist, the function returns nullptr.
+ selects a file that does not exist, the function returns 0.
\param oldname The default filename to display in the file chooser.
\return A pointer to an Image_Asset object that references the selected
- image, or nullptr if the user cancels the file chooser or selects a file
+ image, or 0 if the user cancels the file chooser or selects a file
that does not exist. The asset is automaticly added to the global image
asset map.
*/
@@ -572,8 +572,8 @@ Image_Asset *ui_find_image(const char *oldname) {
#endif
"})",
oldname,1);
- fl_file_chooser_ok_label(nullptr);
- Image_Asset *ret = (name && *name) ? Image_Asset::find(name) : nullptr;
+ fl_file_chooser_ok_label(0);
+ Image_Asset *ret = (name && *name) ? Image_Asset::find(name) : 0;
Fluid.proj.leave_project_dir();
return ret;
}
diff --git a/fluid/app/Image_Asset.h b/fluid/app/Image_Asset.h
index f5376beaa..fcc8fb31c 100644
--- a/fluid/app/Image_Asset.h
+++ b/fluid/app/Image_Asset.h
@@ -32,7 +32,7 @@ private: // member variables
bool is_animated_gif_ = false; ///< It's an animated gif.
std::string filename_ { }; ///< Relative path to the image file
int refcount_ = 0; ///< Reference count
- Fl_Shared_Image *image_ = nullptr; ///< The actual image as managed by FLTK
+ Fl_Shared_Image *image_ = 0; ///< The actual image as managed by FLTK
std::string initializer_function_ { }; ///< The name of the initializer function
private: // methods
diff --git a/fluid/app/Menu.cxx b/fluid/app/Menu.cxx
index ab03a822d..54db5801f 100644
--- a/fluid/app/Menu.cxx
+++ b/fluid/app/Menu.cxx
@@ -35,11 +35,8 @@ extern void layout_suite_marker(Fl_Widget *, void *user_data);
extern void select_layout_preset_cb(Fl_Widget *, void *user_data);
extern Fl_Menu_Item main_layout_submenu_[];
-using namespace fld;
-
-
void write_cb(Fl_Widget *, void *) {
- Fluid.write_code_files();
+ Fluid.write_code_files(0);
}
void openwidget_cb(Fl_Widget *, void *) { Fluid.edit_selected(); }
void copy_cb(Fl_Widget*, void*) { Fluid.copy_selected(); }
@@ -59,13 +56,13 @@ void manual_cb(Fl_Widget *, void *) {
Fluid.show_help("index.html");
}
-static void menu_file_new_cb(Fl_Widget *, void *) { Fluid.new_project(); }
+static void menu_file_new_cb(Fl_Widget *, void *) { Fluid.new_project(1); }
static void menu_file_new_from_template_cb(Fl_Widget *, void *) { Fluid.new_project_from_template(); }
static void menu_file_open_cb(Fl_Widget *, void *) { Fluid.open_project_file(""); }
static void menu_file_insert_cb(Fl_Widget *, void *) { Fluid.merge_project_file(""); }
void menu_file_save_cb(Fl_Widget *, void *arg) { Fluid.save_project_file(arg); }
static void menu_file_print_cb(Fl_Widget *, void *arg) { Fluid.print_snapshots(); }
-void menu_file_open_history_cb(Fl_Widget *, void *v) { Fluid.open_project_file(std::string((const char*)v)); }
+void menu_file_open_history_cb(Fl_Widget *, void *v) { Fluid.open_project_file((const char*)v); }
static void menu_layout_sync_resize_cb(Fl_Menu_ *m, void*) {
if (m->mvalue()->value()) Fluid.proj.tree.allow_layout = 1; else Fluid.proj.tree.allow_layout = 0;
}
@@ -88,21 +85,21 @@ void toggle_widgetbin_cb(Fl_Widget *, void *) { Fluid.toggle_widget_bin(); }
\todo Shortcuts are all over the place (Alt, Ctrl, Command, Shift-Ctrl,
function keys), and there should be a help page listing all shortcuts.
*/
-Fl_Menu_Item Application::main_menu[] = {
- {"&File",0,nullptr,nullptr,FL_SUBMENU},
+Fl_Menu_Item fld::Application::main_menu[] = {
+ {"&File",0,0,0,FL_SUBMENU},
{"&New", FL_COMMAND+'n', menu_file_new_cb},
{"&Open...", FL_COMMAND+'o', menu_file_open_cb},
- {"&Insert...", FL_COMMAND+'i', menu_file_insert_cb, nullptr, FL_MENU_DIVIDER},
- {"&Save", FL_COMMAND+'s', menu_file_save_cb, nullptr},
+ {"&Insert...", FL_COMMAND+'i', menu_file_insert_cb, 0, FL_MENU_DIVIDER},
+ {"&Save", FL_COMMAND+'s', menu_file_save_cb, 0},
{"Save &As...", FL_COMMAND+FL_SHIFT+'s', menu_file_save_cb, (void*)1},
{"Sa&ve A Copy...", 0, menu_file_save_cb, (void*)2},
- {"&Revert...", 0, menu_file_revert_cb, nullptr, FL_MENU_DIVIDER},
- {"New &From Template...", FL_COMMAND+'N', menu_file_new_from_template_cb, nullptr},
- {"Save As &Template...", 0, save_template_cb, nullptr, FL_MENU_DIVIDER},
+ {"&Revert...", 0, menu_file_revert_cb, 0, FL_MENU_DIVIDER},
+ {"New &From Template...", FL_COMMAND+'N', menu_file_new_from_template_cb, 0},
+ {"Save As &Template...", 0, save_template_cb, 0, FL_MENU_DIVIDER},
{"&Print...", FL_COMMAND+'p', menu_file_print_cb},
- {"Write &Code", FL_COMMAND+FL_SHIFT+'c', write_cb, nullptr},
+ {"Write &Code", FL_COMMAND+FL_SHIFT+'c', write_cb, 0},
{"MergeBack Code", FL_COMMAND+FL_SHIFT+'m', mergeback_cb, 0},
- {"&Write Strings", FL_COMMAND+FL_SHIFT+'w', write_strings_cb, nullptr, FL_MENU_DIVIDER},
+ {"&Write Strings", FL_COMMAND+FL_SHIFT+'w', write_strings_cb, 0, FL_MENU_DIVIDER},
{Fluid.history.relpath[0], FL_COMMAND+'1', menu_file_open_history_cb, Fluid.history.abspath[0]},
{Fluid.history.relpath[1], FL_COMMAND+'2', menu_file_open_history_cb, Fluid.history.abspath[1]},
{Fluid.history.relpath[2], FL_COMMAND+'3', menu_file_open_history_cb, Fluid.history.abspath[2]},
@@ -114,67 +111,67 @@ Fl_Menu_Item Application::main_menu[] = {
{Fluid.history.relpath[8], FL_COMMAND+'9', menu_file_open_history_cb, Fluid.history.abspath[8]},
{Fluid.history.relpath[9], 0, menu_file_open_history_cb, Fluid.history.abspath[9], FL_MENU_DIVIDER},
{"&Quit", FL_COMMAND+'q', exit_cb},
- {nullptr},
- {"&Edit",0,nullptr,nullptr,FL_SUBMENU},
+ {0},
+ {"&Edit",0,0,0,FL_SUBMENU},
{"&Undo", FL_COMMAND+'z', fld::proj::Undo::undo_cb},
- {"&Redo", FL_COMMAND+FL_SHIFT+'z', fld::proj::Undo::redo_cb, nullptr, FL_MENU_DIVIDER},
+ {"&Redo", FL_COMMAND+FL_SHIFT+'z', fld::proj::Undo::redo_cb, 0, FL_MENU_DIVIDER},
{"C&ut", FL_COMMAND+'x', cut_cb},
{"&Copy", FL_COMMAND+'c', copy_cb},
{"&Paste", FL_COMMAND+'v', paste_cb},
{"Dup&licate", FL_COMMAND+'u', duplicate_cb},
- {"&Delete", FL_Delete, delete_cb, nullptr, FL_MENU_DIVIDER},
+ {"&Delete", FL_Delete, delete_cb, 0, FL_MENU_DIVIDER},
{"Select &All", FL_COMMAND+'a', select_all_cb},
- {"Select &None", FL_COMMAND+FL_SHIFT+'a', select_none_cb, nullptr, FL_MENU_DIVIDER},
+ {"Select &None", FL_COMMAND+FL_SHIFT+'a', select_none_cb, 0, FL_MENU_DIVIDER},
{"Pr&operties...", FL_F+1, openwidget_cb},
{"&Sort",0,sort_cb},
{"&Earlier", FL_F+2, earlier_cb},
{"&Later", FL_F+3, later_cb},
{"&Group", FL_F+7, group_cb},
- {"Ung&roup", FL_F+8, ungroup_cb,nullptr, FL_MENU_DIVIDER},
+ {"Ung&roup", FL_F+8, ungroup_cb,0, FL_MENU_DIVIDER},
{"Hide O&verlays",FL_COMMAND+FL_SHIFT+'o',toggle_overlays},
{"Hide Guides",FL_COMMAND+FL_SHIFT+'g',toggle_guides},
{"Hide Restricted",FL_COMMAND+FL_SHIFT+'r',toggle_restricted},
{"Show Widget &Bin...",FL_ALT+'b',toggle_widgetbin_cb},
- {"Show Code View",FL_ALT+'c', (Fl_Callback*)toggle_codeview_cb, nullptr, FL_MENU_DIVIDER},
+ {"Show Code View",FL_ALT+'c', (Fl_Callback*)toggle_codeview_cb, 0, FL_MENU_DIVIDER},
{"Settings...",FL_ALT+'p',show_settings_cb},
- {nullptr},
- {"&New", 0, nullptr, (void *)New_Menu, FL_SUBMENU_POINTER},
- {"&Layout",0,nullptr,nullptr,FL_SUBMENU},
- {"&Align",0,nullptr,nullptr,FL_SUBMENU},
+ {0},
+ {"&New", 0, 0, (void *)New_Menu, FL_SUBMENU_POINTER},
+ {"&Layout",0,0,0,FL_SUBMENU},
+ {"&Align",0,0,0,FL_SUBMENU},
{"&Left",0,(Fl_Callback *)align_widget_cb,(void*)10},
{"&Center",0,(Fl_Callback *)align_widget_cb,(void*)11},
{"&Right",0,(Fl_Callback *)align_widget_cb,(void*)12},
{"&Top",0,(Fl_Callback *)align_widget_cb,(void*)13},
{"&Middle",0,(Fl_Callback *)align_widget_cb,(void*)14},
{"&Bottom",0,(Fl_Callback *)align_widget_cb,(void*)15},
- {nullptr},
- {"&Space Evenly",0,nullptr,nullptr,FL_SUBMENU},
+ {0},
+ {"&Space Evenly",0,0,0,FL_SUBMENU},
{"&Across",0,(Fl_Callback *)align_widget_cb,(void*)20},
{"&Down",0,(Fl_Callback *)align_widget_cb,(void*)21},
- {nullptr},
- {"&Make Same Size",0,nullptr,nullptr,FL_SUBMENU},
+ {0},
+ {"&Make Same Size",0,0,0,FL_SUBMENU},
{"&Width",0,(Fl_Callback *)align_widget_cb,(void*)30},
{"&Height",0,(Fl_Callback *)align_widget_cb,(void*)31},
{"&Both",0,(Fl_Callback *)align_widget_cb,(void*)32},
- {nullptr},
- {"&Center In Group",0,nullptr,nullptr,FL_SUBMENU},
+ {0},
+ {"&Center In Group",0,0,0,FL_SUBMENU},
{"&Horizontal",0,(Fl_Callback *)align_widget_cb,(void*)40},
{"&Vertical",0,(Fl_Callback *)align_widget_cb,(void*)41},
- {nullptr},
- {"Synchronized Resize", 0, (Fl_Callback*)menu_layout_sync_resize_cb, nullptr, FL_MENU_TOGGLE|FL_MENU_DIVIDER },
- {"&Grid and Size Settings...",FL_COMMAND+'g',show_grid_cb, nullptr, FL_MENU_DIVIDER},
+ {0},
+ {"Synchronized Resize", 0, (Fl_Callback*)menu_layout_sync_resize_cb, 0, FL_MENU_TOGGLE|FL_MENU_DIVIDER },
+ {"&Grid and Size Settings...",FL_COMMAND+'g',show_grid_cb, 0, FL_MENU_DIVIDER},
{"Presets", 0, layout_suite_marker, (void*)main_layout_submenu_, FL_SUBMENU_POINTER },
- {"Application", 0, select_layout_preset_cb, (void*)nullptr, FL_MENU_RADIO|FL_MENU_VALUE },
+ {"Application", 0, select_layout_preset_cb, (void*)0, FL_MENU_RADIO|FL_MENU_VALUE },
{"Dialog", 0, select_layout_preset_cb, (void*)1, FL_MENU_RADIO },
{"Toolbox", 0, select_layout_preset_cb, (void*)2, FL_MENU_RADIO },
- {nullptr},
+ {0},
{"&Shell", 0, Fd_Shell_Command_List::menu_marker, (void*)Fd_Shell_Command_List::default_menu, FL_SUBMENU_POINTER},
- {"&Help",0,nullptr,nullptr,FL_SUBMENU},
+ {"&Help",0,0,0,FL_SUBMENU},
{"&Rapid development with FLUID...",0,help_cb},
- {"&FLTK Programmers Manual...",0,manual_cb, nullptr, FL_MENU_DIVIDER},
+ {"&FLTK Programmers Manual...",0,manual_cb, 0, FL_MENU_DIVIDER},
{"&About FLUID...",0,about_cb},
- {nullptr},
-{nullptr}};
+ {0},
+{0}};
/**
Show or hide the code preview window.
diff --git a/fluid/app/Snap_Action.cxx b/fluid/app/Snap_Action.cxx
index 2ec7affad..51cdb9817 100644
--- a/fluid/app/Snap_Action.cxx
+++ b/fluid/app/Snap_Action.cxx
@@ -112,13 +112,13 @@ static Layout_Suite static_suite_list[] = {
Fl_Menu_Item main_layout_submenu_[] = {
{ static_suite_list[0].menu_label, 0, select_layout_suite_cb, (void*)0, FL_MENU_RADIO|FL_MENU_VALUE },
{ static_suite_list[1].menu_label, 0, select_layout_suite_cb, (void*)1, FL_MENU_RADIO },
- { nullptr }
+ { 0 }
};
static Fl_Menu_Item static_choice_menu[] = {
{ static_suite_list[0].menu_label },
{ static_suite_list[1].menu_label },
- { nullptr }
+ { 0 }
};
@@ -131,17 +131,17 @@ void layout_suite_marker(Fl_Widget *, void *) {
void select_layout_suite_cb(Fl_Widget *, void *user_data) {
int index = (int)(fl_intptr_t)user_data;
assert(index >= 0);
- assert(index < Fluid.layout_list.list_size_);
- Fluid.layout_list.current_suite(index);
- Fluid.layout_list.update_dialogs();
+ assert(index < Fluid.layout_list->list_size_);
+ Fluid.layout_list->current_suite(index);
+ Fluid.layout_list->update_dialogs();
}
void select_layout_preset_cb(Fl_Widget *, void *user_data) {
int index = (int)(fl_intptr_t)user_data;
assert(index >= 0);
assert(index < 3);
- Fluid.layout_list.current_preset(index);
- Fluid.layout_list.update_dialogs();
+ Fluid.layout_list->current_preset(index);
+ Fluid.layout_list->update_dialogs();
}
void edit_layout_preset_cb(Fl_Button *w, void *user_data) {
@@ -149,10 +149,10 @@ void edit_layout_preset_cb(Fl_Button *w, void *user_data) {
assert(index >= 0);
assert(index < 3);
if (user_data == LOAD) {
- w->value(Fluid.layout_list.current_preset() == index);
+ w->value(Fluid.layout_list->current_preset() == index);
} else {
- Fluid.layout_list.current_preset(index);
- Fluid.layout_list.update_dialogs();
+ Fluid.layout_list->current_preset(index);
+ Fluid.layout_list->update_dialogs();
}
}
@@ -412,7 +412,7 @@ void Layout_Suite::update_label() {
if (menu_label)
::free(menu_label);
menu_label = fl_strdup(sym.c_str());
- Fluid.layout_list.update_menu_labels();
+ Fluid.layout_list->update_menu_labels();
}
/**
@@ -425,7 +425,7 @@ void Layout_Suite::name(const char *n) {
if (n)
name_ = fl_strdup(n);
else
- name_ = nullptr;
+ name_ = 0;
update_label();
}
@@ -433,9 +433,9 @@ void Layout_Suite::name(const char *n) {
Initialize the class for first use.
*/
void Layout_Suite::init() {
- name_ = nullptr;
- menu_label = nullptr;
- layout[0] = layout[1] = layout[2] = nullptr;
+ name_ = 0;
+ menu_label = 0;
+ layout[0] = layout[1] = layout[2] = 0;
storage_ = FLD_TOOL_STORE_INTERNAL;
}
@@ -630,7 +630,7 @@ Layout_List::~Layout_List() {
Update the Setting dialog and menus to reflect the current Layout selection state.
*/
void Layout_List::update_dialogs() {
- static Fl_Menu_Item *preset_menu = nullptr;
+ static Fl_Menu_Item *preset_menu = 0;
if (!preset_menu) {
preset_menu = (Fl_Menu_Item*)Fluid.main_menubar->find_item(select_layout_preset_cb);
assert(preset_menu);
@@ -665,7 +665,7 @@ void Layout_List::update_menu_labels() {
*/
int Layout_List::load(const std::string &filename) {
remove_all(FLD_TOOL_STORE_FILE);
- Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", nullptr, Fl_Preferences::C_LOCALE);
+ Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", 0, Fl_Preferences::C_LOCALE);
read(prefs, FLD_TOOL_STORE_FILE);
return 0;
}
@@ -675,7 +675,7 @@ int Layout_List::load(const std::string &filename) {
*/
int Layout_List::save(const std::string &filename) {
assert(this);
- Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", nullptr, (Fl_Preferences::Root)(Fl_Preferences::C_LOCALE|Fl_Preferences::CLEAR));
+ Fl_Preferences prefs(filename.c_str(), "layout.fluid.fltk.org", 0, (Fl_Preferences::Root)(Fl_Preferences::C_LOCALE|Fl_Preferences::CLEAR));
prefs.clear();
write(prefs, FLD_TOOL_STORE_FILE);
return 0;
@@ -829,7 +829,7 @@ void Layout_List::current_preset(int ix) {
Allocate enough space for n entries in the list.
*/
void Layout_List::capacity(int n) {
- static Fl_Menu_Item *suite_menu = nullptr;
+ static Fl_Menu_Item *suite_menu = 0;
if (!suite_menu)
suite_menu = (Fl_Menu_Item*)Fluid.main_menubar->find_item(layout_suite_marker);
@@ -1467,11 +1467,11 @@ class Fd_Snap_Sibling : public Snap_Action {
protected:
Fl_Widget *best_match;
public:
- Fd_Snap_Sibling() : best_match(nullptr) { }
+ Fd_Snap_Sibling() : best_match(0) { }
virtual int sibling_check(Snap_Data &d, Fl_Widget *s) = 0;
void check(Snap_Data &d) override {
clr();
- best_match = nullptr;
+ best_match = 0;
if (!d.wgt) return;
if (!d.wgt->parent->is_a(FLD_NODE_TYPE_Group)) return;
int dsib_min = 1024;
@@ -1707,7 +1707,7 @@ Snap_Action *Snap_Action::list[] = {
&snap_widget_ideal_width,
&snap_widget_ideal_height,
- nullptr
+ 0
};
// ---- draw alignment marks ------------------------------------------- MARK: -
diff --git a/fluid/app/args.cxx b/fluid/app/args.cxx
index b9d958e8c..70faebafc 100644
--- a/fluid/app/args.cxx
+++ b/fluid/app/args.cxx
@@ -22,8 +22,21 @@
#include <FL/filename.H>
#include <FL/fl_ask.H>
-using namespace fld;
-using namespace fld::app;
+#include <string.h>
+#include "../src/flstring.h"
+
+
+fld::app::Args::Args()
+: update_file(0),
+ compile_file(0),
+ compile_strings(0),
+ show_version(0)
+{
+ code_filename[0] = '\0';
+ header_filename[0] = '\0';
+ autodoc_path[0] = '\0';
+}
+
/**
Load args from command line into variables.
@@ -33,12 +46,12 @@ using namespace fld::app;
\return 0 if the args were handled successfully, -1 if there was an error
and the usage message was shown.
*/
-int Args::load(int argc,char **argv) {
+int fld::app::Args::load(int argc, char **argv) {
int i = 1;
Fl::args_to_utf8(argc, argv); // for MSYS2/MinGW
- if ( (Fl::args(argc,argv,i,arg_cb) == 0) // unsupported argument found
- || (Fluid.batch_mode && (i != argc-1)) // .fl filename missing
- || (!Fluid.batch_mode && (i < argc-1)) // more than one filename found
+ if ( (Fl::args(argc, argv, i, arg_cb) == 0) // unsupported argument found
+ || (Fluid.batch_mode && (i != argc - 1)) // .fl filename missing
+ || (!Fluid.batch_mode && (i < argc - 1)) // more than one filename found
|| (argv[i] && (argv[i][0] == '-'))) { // unknown option
static const char *msg =
"usage: %s <switches> name.fl\n"
@@ -50,13 +63,12 @@ int Args::load(int argc,char **argv) {
" --help : brief usage information\n"
" --version, -v : print fluid version number\n"
" -d : enable internal debugging\n";
- const char *app_name = nullptr;
- if ( (argc > 0) && argv[0] && argv[0][0] )
+ const char *app_name = 0;
+ if ((argc > 0) && argv[0] && argv[0][0])
app_name = fl_filename_name(argv[0]);
- if ( !app_name || !app_name[0])
+ if (!app_name || !app_name[0])
app_name = "fluid";
#ifdef _MSC_VER
- // TODO: if this is fluid-cmd, use stderr and not fl_message
fl_message(msg, app_name);
#else
fprintf(stderr, msg, app_name);
@@ -67,7 +79,7 @@ int Args::load(int argc,char **argv) {
}
-int Args::arg_cb(int argc, char** argv, int& i) {
+int fld::app::Args::arg_cb(int argc, char** argv, int& i) {
return Fluid.args.arg(argc, argv, i);
}
@@ -79,11 +91,11 @@ int Args::arg_cb(int argc, char** argv, int& i) {
\param[inout] i current argument index
\return number of arguments used; if 0, the argument is not supported
*/
-int Args::arg(int argc, char** argv, int& i) {
+int fld::app::Args::arg(int argc, char** argv, int& i) {
if (argv[i][0] != '-')
return 0;
if (argv[i][1] == 'd' && !argv[i][2]) {
- Fluid.debug_external_editor=1;
+ Fluid.debug_external_editor = 1;
i++; return 1;
}
if (argv[i][1] == 'u' && !argv[i][2]) {
@@ -96,7 +108,7 @@ int Args::arg(int argc, char** argv, int& i) {
Fluid.batch_mode++;
i++; return 1;
}
- if ((strcmp(argv[i], "-v")==0) || (strcmp(argv[i], "--version")==0)) {
+ if ((strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--version") == 0)) {
show_version = 1;
i++; return 1;
}
@@ -106,31 +118,29 @@ int Args::arg(int argc, char** argv, int& i) {
Fluid.batch_mode++;
i++; return 1;
}
- if (argv[i][1] == 'o' && !argv[i][2] && i+1 < argc) {
- code_filename = argv[i+1];
+ if (argv[i][1] == 'o' && !argv[i][2] && i + 1 < argc) {
+ strlcpy(code_filename, argv[i + 1], FL_PATH_MAX);
Fluid.batch_mode++;
i += 2; return 2;
}
#ifndef NDEBUG
- if ((i+1 < argc) && (strcmp(argv[i], "--autodoc") == 0)) {
- autodoc_path = argv[i+1];
+ if ((i + 1 < argc) && (strcmp(argv[i], "--autodoc") == 0)) {
+ strlcpy(autodoc_path, argv[i + 1], FL_PATH_MAX);
i += 2; return 2;
}
#endif
- if (strcmp(argv[i], "--help")==0) {
+ if (strcmp(argv[i], "--help") == 0) {
return 0;
}
if (argv[i][1] == 'h' && !argv[i][2]) {
- if ( (i+1 < argc) && (argv[i+1][0] != '-') ) {
- header_filename = argv[i+1];
+ if ((i + 1 < argc) && (argv[i + 1][0] != '-')) {
+ strlcpy(header_filename, argv[i + 1], FL_PATH_MAX);
Fluid.batch_mode++;
i += 2;
return 2;
} else {
- // a lone "-h" without a filename will output the help string
return 0;
}
}
return 0;
}
-
diff --git a/fluid/app/args.h b/fluid/app/args.h
index 80dfa2290..1165c4f58 100644
--- a/fluid/app/args.h
+++ b/fluid/app/args.h
@@ -17,7 +17,7 @@
#ifndef FLUID_APP_ARGS_H
#define FLUID_APP_ARGS_H
-#include <string>
+#include <FL/filename.H>
namespace fld {
namespace app {
@@ -29,21 +29,21 @@ class Args {
int arg(int argc, char** argv, int& i);
public:
/// Set, if Fluid was started with the command line argument -u
- int update_file { 0 }; // fluid -u
+ int update_file;
/// Set, if Fluid was started with the command line argument -c
- int compile_file { 0 }; // fluid -c
+ int compile_file;
/// Set, if Fluid was started with the command line argument -cs
- int compile_strings { 0 }; // fluid -cs
+ int compile_strings;
/// command line arguments that overrides the generate code file extension or name
- std::string code_filename { }; // fluid -o filename
+ char code_filename[FL_PATH_MAX];
/// command line arguments that overrides the generate header file extension or name
- std::string header_filename { }; // fluid -h filename
+ char header_filename[FL_PATH_MAX];
/// if set, generate images for automatic documentation in this directory
- std::string autodoc_path { }; // fluid --autodoc path
+ char autodoc_path[FL_PATH_MAX];
/// Set, if Fluid was started with the command line argument -v
- int show_version { 0 }; // fluid -v
+ int show_version;
/// Constructor.
- Args() = default;
+ Args();
// Load args from command line into variables.
int load(int argc, char **argv);
};
@@ -52,4 +52,3 @@ public:
} // namespace fld
#endif // FLUID_APP_ARGS_H
-
diff --git a/fluid/app/history.cxx b/fluid/app/history.cxx
index 7eadb5469..91b2f0b99 100644
--- a/fluid/app/history.cxx
+++ b/fluid/app/history.cxx
@@ -17,11 +17,20 @@
#include "app/history.h"
#include "Fluid.h"
+#include "tools/filename.h"
#include "../src/flstring.h"
-using namespace fld;
-using namespace fld::app;
+
+fld::app::History::History() {
+ int i, j;
+ for (i = 0; i < 10; i++) {
+ for (j = 0; j < FL_PATH_MAX; j++) {
+ abspath[i][j] = '\0';
+ relpath[i][j] = '\0';
+ }
+ }
+}
/**
@@ -31,25 +40,23 @@ using namespace fld::app;
It also computes and stores the relative filepaths for display in
the main menu.
*/
-void History::load() {
- int i; // Looping var
- int max_files;
+void fld::app::History::load() {
+ int i;
+ int max_files;
Fluid.preferences.get("recent_files", max_files, 5);
if (max_files > 10) max_files = 10;
- for (i = 0; i < max_files; i ++) {
- Fluid.preferences.get( Fl_Preferences::Name("file%d", i), abspath[i], "", sizeof(abspath[i]));
+ for (i = 0; i < max_files; i++) {
+ Fluid.preferences.get(Fl_Preferences::Name("file%d", i), abspath[i], "", sizeof(abspath[i]));
if (abspath[i][0]) {
- // Make a shortened version of the filename for the menu...
- std::string fn = fl_filename_shortened(abspath[i], 48);
- strncpy(relpath[i], fn.c_str(), sizeof(relpath[i]) - 1);
+ fl_filename_shortened(relpath[i], sizeof(relpath[i]), abspath[i], 48);
if (i == 9) Fluid.history_item[i].flags = FL_MENU_DIVIDER;
else Fluid.history_item[i].flags = 0;
} else break;
}
- for (; i < 10; i ++) {
+ for (; i < 10; i++) {
if (i) Fluid.history_item[i-1].flags |= FL_MENU_DIVIDER;
Fluid.history_item[i].hide();
}
@@ -64,19 +71,24 @@ void History::load() {
\param[in] project_file path and filename of .fl project file, will be
converted into an absolute file path based on the current working directory.
*/
-void History::update(std::string project_file) {
- int i; // Looping var
- int max_files;
+void fld::app::History::update(const char *project_file) {
+ int i;
+ int max_files;
+
+ if (!project_file || !project_file[0]) return;
Fluid.preferences.get("recent_files", max_files, 5);
if (max_files > 10) max_files = 10;
- std::string absolute = fld::fix_separators(fl_filename_absolute_str(project_file));
- for (i = 0; i < max_files; i ++)
+ char absolute[FL_PATH_MAX];
+ fl_filename_absolute(absolute, FL_PATH_MAX, project_file);
+ fld_fix_separators(absolute);
+
+ for (i = 0; i < max_files; i++)
#if defined(_WIN32) || defined(__APPLE__)
- if (!strcasecmp(absolute.c_str(), abspath[i])) break;
+ if (!strcasecmp(absolute, abspath[i])) break;
#else
- if (!strcmp(absolute.c_str(), abspath[i])) break;
+ if (!strcmp(absolute, abspath[i])) break;
#endif // _WIN32 || __APPLE__
// Does the first entry match?
@@ -92,24 +104,22 @@ void History::update(std::string project_file) {
memmove(relpath + 1, relpath, i * sizeof(relpath[0]));
// Put the new file at the top...
- strlcpy(abspath[0], absolute.c_str(), sizeof(abspath[0]));
- std::string fn = fl_filename_shortened(absolute, 48);
- strncpy(relpath[0], fn.c_str(), sizeof(relpath[0]) - 1);
+ strlcpy(abspath[0], absolute, sizeof(abspath[0]));
+ fl_filename_shortened(relpath[0], sizeof(relpath[0]), absolute, 48);
// Update the menu items as needed...
- for (i = 0; i < max_files; i ++) {
- Fluid.preferences.set( Fl_Preferences::Name("file%d", i), abspath[i]);
+ for (i = 0; i < max_files; i++) {
+ Fluid.preferences.set(Fl_Preferences::Name("file%d", i), abspath[i]);
if (abspath[i][0]) {
if (i == 9) Fluid.history_item[i].flags = FL_MENU_DIVIDER;
else Fluid.history_item[i].flags = 0;
} else break;
}
- for (; i < 10; i ++) {
- Fluid.preferences.set( Fl_Preferences::Name("file%d", i), "");
+ for (; i < 10; i++) {
+ Fluid.preferences.set(Fl_Preferences::Name("file%d", i), "");
if (i) Fluid.history_item[i-1].flags |= FL_MENU_DIVIDER;
Fluid.history_item[i].hide();
}
Fluid.preferences.flush();
}
-
diff --git a/fluid/app/history.h b/fluid/app/history.h
index e32723b4b..99200757a 100644
--- a/fluid/app/history.h
+++ b/fluid/app/history.h
@@ -17,8 +17,6 @@
#ifndef FLUID_APP_HISTORY_H
#define FLUID_APP_HISTORY_H
-#include <tools/filename.h>
-
#include <FL/filename.H>
namespace fld {
@@ -27,19 +25,18 @@ namespace app {
class History {
public:
/// Stores the absolute filename of the last 10 project files, saved in app preferences.
- char abspath[10][FL_PATH_MAX] { };
+ char abspath[10][FL_PATH_MAX];
/// The list of filenames as displayed in the main menu.
- char relpath[10][FL_PATH_MAX] { };
+ char relpath[10][FL_PATH_MAX];
// Create the project file history.
- History() = default;
+ History();
// Load the project history from the preferences database.
void load();
// Add a new file to the project history using absolute paths.
- void update(std::string project_file);
+ void update(const char *project_file);
};
} // namespace app
} // namespace fld
#endif // FLUID_APP_HISTORY_H
-
diff --git a/fluid/app/shell_command.cxx b/fluid/app/shell_command.cxx
index 05bc28ec0..0a9a04121 100644
--- a/fluid/app/shell_command.cxx
+++ b/fluid/app/shell_command.cxx
@@ -1,5 +1,5 @@
//
-// Shell Command database coe for the Fast Light Tool Kit (FLTK).
+// Shell Command database code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2025 by Bill Spitzak and others.
//
@@ -14,87 +14,6 @@
// https://www.fltk.org/bugs.php
//
-// in progress:
-// FLUID comes with example shell commands to build the current project file
-// and run the project. This is accomplished by calling `fltk-config` on the
-// files generated by FLUID, and by calling the executable directly.
-//
-// If the user wants more complex commands, he can add or modify them in the
-// "Shell" settings panel. Modified shell commands are saved with the .fl
-// file.
-
-// The Shell panel has a list of shell commands in the upper half. Under the
-// list are buttons to add, duplicate, and delete shell commands. A popup
-// menu offers import and export functionality and a list of sample scripts.
-// We may want to add up and down buttons, so the user can change the
-// order of commands.
-
-// Selecting any shell command in the list fills in and activates a list of
-// options in the lower half of the panel. Those settings are:
-// - Name: the name of the shell command in the list
-// - Label: the label in the pulldown menu (could be the same as name?)
-// - Shortcut: shortcut key to launch the command
-// - Storage: where to store this shell command
-// - Condition: pulldown menu to make the entry conditional for various
-// target platforms, for example, a "Windows only" entry would only be added
-// to the Shell menu on a Windows machine. Other options could be:
-// - Linux only, macOS only, never (to make a list header!?), inactive?
-// - Command: a multiline input for the actual shell command
-// - Variables: a pulldown menu that insert variable names like $<sourcefile>
-// - options to save project, code, and strings before running
-// - test-run button
-
-// TODO: add @APPDIR@?
-// TODO: get a macro to find `fltk-config` @FLTK_CONFIG@
-// TODO: add an input field so the user can insert their preferred file and path for fltk-config (user setting)
-// `fltk-config` is actually tricky to find
-// for live builds, we could check the program launch directory
-// if we know where build/Xcode/bin/Debug/fluid is, we
-// may or may not find ./build/Xcode/fltk-config
-// on macOS with homebrew, we find /opt/homebrew/bin/fltk-config but the user
-// can set their own install path.
-// We can query the shell path, but that requires knowing the users shell (echo $SHELL).
-// We can run the shell as a login shell with `-l`, so the user $PTH is set: /bin/bash -l -c 'fltk-config'
-// The shell should output the path of the fltk-config that it found and why it is using that one.
-// This can also output the fltk-config version.
-// TODO: add a bunch of sensible sample shell commands
-// TODO: when this new feature is used for the very first time, import two or three samples as initial user setting
-// TODO: make the settings dialog resizable
-// TODO: make g_shell_config static, not a pointer, but don't load anything in batch mode
-
-// FEATURE: fld::Tool_Store icons are currently redundant with @file and @save and could be improved
-// FEATURE: hostname, username, getenv support?
-// FEATURE: add the files ./fluid.prefs and ./fluid.user.prefs as tool locations
-// FEATURE: interpret compiler output, for example: clang, and highlight errors and warnings
-// `.../shell_command.cxx:71:2: error: test`
-// `71 | #error test`
-// `clang++: error: no such file or directory: '.../shell_command.o'`
-// would make the error message clickable in the shell window and could select the widget,
-// open the matching editor in the widget panel, and highlight the line in SourceView.
-
-/*
- Some ideas:
-
- default shell is in $SHELL on linux and macOS
-
- On macOS, we can write Apple Scripts:
-
- #!/usr/bin/env osascript
- say "@BASENAME@"
-
- osascript <<EOD
- say "spark"
- EOD
-
- osascript <<EOD
- tell application "Xcode"
- build workspace document 1
- end tell
- EOD
-
- powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^{ESCAPE}')
- */
-
#include "app/shell_command.h"
#include "Fluid.h"
@@ -109,17 +28,15 @@
#include <FL/fl_string_functions.h>
#include <errno.h>
+#include <string.h>
-using namespace fld;
-
-static std::string fltk_config_cmd;
static Fl_Process s_proc;
/**
See if shell command is running (public)
*/
-bool shell_command_running() {
- return s_proc.desc() ? true : false;
+int shell_command_running() {
+ return s_proc.desc() ? 1 : 0;
}
/** \class Fl_Process
@@ -130,13 +47,13 @@ bool shell_command_running() {
Create a process manager
*/
Fl_Process::Fl_Process() {
+ _fpt = 0;
}
/**
Destroy the project manager.
*/
Fl_Process::~Fl_Process() {
- // TODO: check what we need to do if a task is still running
if (_fpt) close();
}
@@ -150,13 +67,13 @@ Fl_Process::~Fl_Process() {
FILE * Fl_Process::popen(const char *cmd, const char *mode) {
#if defined(_WIN32) && !defined(__CYGWIN__)
// PRECONDITIONS
- if (!mode || !*mode || (*mode!='r' && *mode!='w') ) return nullptr;
+ if (!mode || !*mode || (*mode!='r' && *mode!='w') ) return 0;
if (_fpt) close(); // close first before reuse
ptmode = *mode;
pin[0] = pin[1] = pout[0] = pout[1] = perr[0] = perr[1] = INVALID_HANDLE_VALUE;
// stderr to stdout wanted ?
- int fusion = (strstr(cmd,"2>&1") !=nullptr);
+ int fusion = (strstr(cmd,"2>&1") != 0);
// Create windows pipes
if (!createPipe(pin) || !createPipe(pout) || (!fusion && !createPipe(perr) ) )
@@ -170,8 +87,8 @@ FILE * Fl_Process::popen(const char *cmd, const char *mode) {
si.hStdOutput = pout[1];
si.hStdError = fusion ? pout[1] : perr [1];
- if ( CreateProcess(nullptr, (LPTSTR) cmd,nullptr,nullptr,TRUE,
- DETACHED_PROCESS,nullptr,nullptr, &si, &pi)) {
+ if ( CreateProcess(0, (LPTSTR) cmd, 0, 0, TRUE,
+ DETACHED_PROCESS, 0, 0, &si, &pi)) {
// don't need theses handles inherited by child process:
clean_close(pin[0]); clean_close(pout[1]); clean_close(perr[1]);
HANDLE & h = *mode == 'r' ? pout[0] : pin[1];
@@ -198,13 +115,13 @@ int Fl_Process::close() {
clean_close(perr[0]);
clean_close(pin[1]);
clean_close(pout[0]);
- _fpt = nullptr;
+ _fpt = 0;
return 0;
}
return -1;
#else
int ret = ::pclose(_fpt);
- _fpt=nullptr;
+ _fpt = 0;
return ret;
#endif
}
@@ -223,16 +140,14 @@ FILE *Fl_Process::desc() const {
\param[out] line buffer to receive the line
\param[in] s size of the provided buffer
- \return nullptr if an error occurred, otherwise a pointer to the string
+ \return 0 if an error occurred, otherwise a pointer to the string
*/
char *Fl_Process::get_line(char * line, size_t s) const {
- return _fpt ? fgets(line, (int)s, _fpt) : nullptr;
+ return _fpt ? fgets(line, (int)s, _fpt) : 0;
}
// returns fileno(FILE*):
// (file must be open, i.e. _fpt must be non-null)
-// *FIXME* we should find a better solution for the 'fileno' issue
-// non null if file is open
int Fl_Process::get_fileno() const {
#ifdef _MSC_VER
return _fileno(_fpt); // suppress MSVC warning
@@ -243,19 +158,19 @@ int Fl_Process::get_fileno() const {
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool Fl_Process::createPipe(HANDLE * h, BOOL bInheritHnd) {
+int Fl_Process::createPipe(HANDLE * h, BOOL bInheritHnd) {
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = nullptr;
+ sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = bInheritHnd;
- return CreatePipe (&h[0],&h[1],&sa,0) ? true : false;
+ return CreatePipe (&h[0],&h[1],&sa,0) ? 1 : 0;
}
FILE *Fl_Process::freeHandles() {
clean_close(pin[0]); clean_close(pin[1]);
clean_close(pout[0]); clean_close(pout[1]);
clean_close(perr[0]); clean_close(perr[1]);
- return nullptr; // convenient for error management
+ return 0; // convenient for error management
}
void Fl_Process::clean_close(HANDLE& h) {
@@ -270,24 +185,23 @@ void Fl_Process::clean_close(HANDLE& h) {
Prepare FLUID for running a shell command according to the command flags.
\param[in] flags set various flags to save the project, code, and string before running the command
- \return false if the previous command is still running
+ \return 0 if the previous command is still running
*/
-static bool prepare_shell_command(int flags) {
-// settings_window->hide();
+static int prepare_shell_command(int flags) {
if (s_proc.desc()) {
fl_alert("Previous shell command still running!");
- return false;
+ return 0;
}
if (flags & Fd_Shell_Command::SAVE_PROJECT) {
- Fluid.save_project_file(nullptr);
+ Fluid.save_project_file(0);
}
if (flags & Fd_Shell_Command::SAVE_SOURCECODE) {
- Fluid.write_code_files(true);
+ Fluid.write_code_files(1);
}
if (flags & Fd_Shell_Command::SAVE_STRINGS) {
Fluid.proj.write_strings();
}
- return true;
+ return 1;
}
/**
@@ -312,7 +226,7 @@ void shell_timer_cb(void*) {
void shell_pipe_cb(FL_SOCKET, void*) {
char line[1024]=""; // Line from command output...
- if (s_proc.get_line(line, sizeof(line)) != nullptr) {
+ if (s_proc.get_line(line, sizeof(line)) != 0) {
// Add the line to the output list...
shell_run_terminal->append(line);
} else {
@@ -324,38 +238,77 @@ void shell_pipe_cb(FL_SOCKET, void*) {
}
}
-/** Find the script `fltk-config` that most closely relates to this version of FLUID.
- This is not implemented yet.
+/**
+ Replace all occurrences of a macro with the given content.
+
+ \param[inout] cmd buffer holding the command (must have enough space)
+ \param[in] cmd_size size of the command buffer
+ \param[in] macro the macro string to replace (e.g., "@BASENAME@")
+ \param[in] content the replacement string
*/
-//static void find_fltk_config() {
-//
-//}
+static void expand_macro(char *cmd, int cmd_size, const char *macro, const char *content) {
+ char *pos;
+ int macro_len;
+ int content_len;
+ int tail_len;
+
+ if (!cmd || !macro || !content) return;
+ macro_len = (int)strlen(macro);
+ content_len = (int)strlen(content);
-static void expand_macro(std::string &cmd, const std::string &macro, const std::string &content) {
- for (int i=0;;) {
- i = (int)cmd.find(macro, i);
- if (i==(int)std::string::npos) break;
- cmd.replace(i, macro.size(), content);
+ while ((pos = strstr(cmd, macro)) != 0) {
+ tail_len = (int)strlen(pos + macro_len);
+ if ((pos - cmd) + content_len + tail_len >= cmd_size - 1) {
+ // Not enough space, truncate
+ break;
+ }
+ memmove(pos + content_len, pos + macro_len, tail_len + 1);
+ memcpy(pos, content, content_len);
}
}
-static void expand_macros(std::string &cmd) {
- expand_macro(cmd, "@BASENAME@", Fluid.proj.basename());
- expand_macro(cmd, "@PROJECTFILE_PATH@", Fluid.proj.projectfile_path());
- expand_macro(cmd, "@PROJECTFILE_NAME@", Fluid.proj.projectfile_name());
- expand_macro(cmd, "@CODEFILE_PATH@", Fluid.proj.codefile_path());
- expand_macro(cmd, "@CODEFILE_NAME@", Fluid.proj.codefile_name());
- expand_macro(cmd, "@HEADERFILE_PATH@", Fluid.proj.headerfile_path());
- expand_macro(cmd, "@HEADERFILE_NAME@", Fluid.proj.headerfile_name());
- expand_macro(cmd, "@TEXTFILE_PATH@", Fluid.proj.stringsfile_path());
- expand_macro(cmd, "@TEXTFILE_NAME@", Fluid.proj.stringsfile_name());
-// TODO: implement finding the script `fltk-config` for all platforms
-// if (cmd.find("@FLTK_CONFIG@") != std::string::npos) {
-// find_fltk_config();
-// expand_macro(cmd, "@FLTK_CONFIG@", fltk_config_cmd.c_str());
-// }
- if (cmd.find("@TMPDIR@") != std::string::npos)
- expand_macro(cmd, "@TMPDIR@", Fluid.get_tmpdir());
+/**
+ Expand all known macros in the command string.
+
+ \param[inout] cmd buffer holding the command
+ \param[in] cmd_size size of the command buffer
+ */
+static void expand_macros(char *cmd, int cmd_size) {
+ char buf[FL_PATH_MAX];
+
+ Fluid.proj.basename(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@BASENAME@", buf);
+
+ Fluid.proj.projectfile_path(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@PROJECTFILE_PATH@", buf);
+
+ {
+ const char *name = Fluid.proj.projectfile_name();
+ expand_macro(cmd, cmd_size, "@PROJECTFILE_NAME@", name ? name : "");
+ }
+
+ Fluid.proj.codefile_path(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@CODEFILE_PATH@", buf);
+
+ Fluid.proj.codefile_name(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@CODEFILE_NAME@", buf);
+
+ Fluid.proj.headerfile_path(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@HEADERFILE_PATH@", buf);
+
+ Fluid.proj.headerfile_name(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@HEADERFILE_NAME@", buf);
+
+ Fluid.proj.stringsfile_path(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@TEXTFILE_PATH@", buf);
+
+ Fluid.proj.stringsfile_name(buf, FL_PATH_MAX);
+ expand_macro(cmd, cmd_size, "@TEXTFILE_NAME@", buf);
+
+ if (strstr(cmd, "@TMPDIR@") != 0) {
+ const char *tmpdir = Fluid.get_tmpdir();
+ expand_macro(cmd, cmd_size, "@TMPDIR@", tmpdir ? tmpdir : "");
+ }
}
/**
@@ -374,22 +327,26 @@ void show_terminal_window() {
shell_run_window->show();
}
+#define SHELL_CMD_BUF_SIZE 4096
+
/**
Prepare for and run a shell command.
\param[in] cmd the command that is sent to `/bin/sh -c ...` or `cmd.exe` on Windows machines
\param[in] flags various flags in preparation of the command
*/
-void run_shell_command(const std::string &cmd, int flags) {
- if (cmd.empty()) {
+void run_shell_command(const char *cmd, int flags) {
+ char expanded_cmd[SHELL_CMD_BUF_SIZE];
+
+ if (!cmd || !cmd[0]) {
fl_alert("No shell command entered!");
return;
}
if (!prepare_shell_command(flags)) return;
- std::string expanded_cmd = cmd;
- expand_macros(expanded_cmd);
+ strlcpy(expanded_cmd, cmd, sizeof(expanded_cmd));
+ expand_macros(expanded_cmd, sizeof(expanded_cmd));
if ( ((flags & Fd_Shell_Command::DONT_SHOW_TERMINAL) == 0)
&& (!shell_run_window->visible()))
@@ -403,10 +360,10 @@ void run_shell_command(const std::string &cmd, int flags) {
if (flags & Fd_Shell_Command::CLEAR_HISTORY)
shell_run_terminal->printf("\033[3J");
shell_run_terminal->scrollbar->value(0);
- shell_run_terminal->printf("\033[0;32m%s\033[0m\n", expanded_cmd.c_str());
- shell_run_window->label(expanded_cmd.c_str());
+ shell_run_terminal->printf("\033[0;32m%s\033[0m\n", expanded_cmd);
+ shell_run_window->label(expanded_cmd);
- if (s_proc.popen((char *)expanded_cmd.c_str()) == nullptr) {
+ if (s_proc.popen(expanded_cmd, "r") == 0) {
shell_run_terminal->printf("\033[1;31mUnable to run shell command: %s\033[0m\n",
strerror(errno));
shell_run_window->label("FLUID Shell");
@@ -421,15 +378,24 @@ void run_shell_command(const std::string &cmd, int flags) {
Fl::add_fd(s_proc.get_fileno(), shell_pipe_cb);
}
+// Helper to duplicate a string safely
+static char *dup_str(const char *s) {
+ return s ? strdup(s) : 0;
+}
+
/**
Create an empty shell command structure.
*/
Fd_Shell_Command::Fd_Shell_Command()
-: shortcut(0),
+: name(0),
+ label(0),
+ shortcut(0),
storage(FLD_TOOL_STORE_USER),
condition(0),
+ condition_data(0),
+ command(0),
flags(0),
- shell_menu_item_(nullptr)
+ shell_menu_item_(0)
{
}
@@ -439,75 +405,94 @@ Fd_Shell_Command::Fd_Shell_Command()
\param[in] rhs copy from this prototype
*/
Fd_Shell_Command::Fd_Shell_Command(const Fd_Shell_Command *rhs)
-: name(rhs->name),
- label(rhs->label),
+: name(dup_str(rhs->name)),
+ label(dup_str(rhs->label)),
shortcut(rhs->shortcut),
storage(rhs->storage),
condition(rhs->condition),
- condition_data(rhs->condition_data),
- command(rhs->command),
+ condition_data(dup_str(rhs->condition_data)),
+ command(dup_str(rhs->command)),
flags(rhs->flags),
- shell_menu_item_(nullptr)
+ shell_menu_item_(0)
{
}
/**
Create a default storage for a shell command and how it is accessible in FLUID.
- \param[in] name is used as a stand-in for the command name and label
+ \param[in] in_name is used as a stand-in for the command name and label
*/
-Fd_Shell_Command::Fd_Shell_Command(const std::string &in_name)
-: name(in_name),
- label(in_name),
+Fd_Shell_Command::Fd_Shell_Command(const char *in_name)
+: name(dup_str(in_name)),
+ label(dup_str(in_name)),
shortcut(0),
storage(FLD_TOOL_STORE_USER),
condition(Fd_Shell_Command::ALWAYS),
- command("echo \"Hello, FLUID!\""),
+ condition_data(0),
+ command(strdup("echo \"Hello, FLUID!\"")),
flags(Fd_Shell_Command::SAVE_PROJECT|Fd_Shell_Command::SAVE_SOURCECODE),
- shell_menu_item_(nullptr)
+ shell_menu_item_(0)
{
}
/**
Create a storage for a shell command and how it is accessible in FLUID.
-
- \param[in] in_name name of this command in the command list in the settings panel
- \param[in] in_label label text in the main pulldown menu
- \param[in] in_shortcut a keyboard shortcut that will also appear in the main menu
- \param[in] in_storage storage location for this command
- \param[in] in_condition commands can be hidden for certain platforms by setting a condition
- \param[in] in_condition_data more details for future conditions, i.e. per user, per host, etc.
- \param[in] in_command the shell command that we want to run
- \param[in] in_flags some flags to tell FLUID to save the project, code, or strings before running the command
- */
-Fd_Shell_Command::Fd_Shell_Command(const std::string &in_name,
- const std::string &in_label,
+ */
+Fd_Shell_Command::Fd_Shell_Command(const char *in_name,
+ const char *in_label,
Fl_Shortcut in_shortcut,
fld::Tool_Store in_storage,
int in_condition,
- const std::string &in_condition_data,
- const std::string &in_command,
+ const char *in_condition_data,
+ const char *in_command,
int in_flags)
-: name(in_name),
- label(in_label),
+: name(dup_str(in_name)),
+ label(dup_str(in_label)),
shortcut(in_shortcut),
storage(in_storage),
condition(in_condition),
- condition_data(in_condition_data),
- command(in_command),
+ condition_data(dup_str(in_condition_data)),
+ command(dup_str(in_command)),
flags(in_flags),
- shell_menu_item_(nullptr)
+ shell_menu_item_(0)
{
}
/**
- Run this command now.
+ Destructor - free all allocated strings.
+ */
+Fd_Shell_Command::~Fd_Shell_Command() {
+ if (name) free(name);
+ if (label) free(label);
+ if (condition_data) free(condition_data);
+ if (command) free(command);
+}
+
+void Fd_Shell_Command::set_name(const char *s) {
+ if (name) free(name);
+ name = dup_str(s);
+}
+
+void Fd_Shell_Command::set_label(const char *s) {
+ if (label) free(label);
+ label = dup_str(s);
+}
+
+void Fd_Shell_Command::set_condition_data(const char *s) {
+ if (condition_data) free(condition_data);
+ condition_data = dup_str(s);
+}
+
+void Fd_Shell_Command::set_command(const char *s) {
+ if (command) free(command);
+ command = dup_str(s);
+}
- Will open the Shell Panel and execute the command if no other command is
- currently running.
+/**
+ Run this command now.
*/
void Fd_Shell_Command::run() {
- if (!command.empty())
+ if (command && command[0])
run_shell_command(command, flags);
}
@@ -516,9 +501,9 @@ void Fd_Shell_Command::run() {
*/
void Fd_Shell_Command::update_shell_menu() {
if (shell_menu_item_) {
- const char *old_label = shell_menu_item_->label(); // can be nullptr
- const char *new_label = label.c_str(); // never nullptr
- if (!old_label || (old_label && strcmp(old_label, new_label))) {
+ const char *old_label = shell_menu_item_->label(); // can be 0
+ const char *new_label = label ? label : "";
+ if (!old_label || strcmp(old_label, new_label)) {
if (old_label) ::free((void*)old_label);
shell_menu_item_->label(fl_strdup(new_label));
}
@@ -529,66 +514,75 @@ void Fd_Shell_Command::update_shell_menu() {
/**
Check if the set condition is met.
- \return true if this command appears in the main menu
+ \return 1 if this command appears in the main menu
*/
-bool Fd_Shell_Command::is_active() {
+int Fd_Shell_Command::is_active() {
switch (condition) {
- case ALWAYS: return true;
- case NEVER: return false;
+ case ALWAYS: return 1;
+ case NEVER: return 0;
#ifdef _WIN32
- case MAC_ONLY: return false;
- case UX_ONLY: return false;
- case WIN_ONLY: return true;
- case MAC_AND_UX_ONLY: return false;
+ case MAC_ONLY: return 0;
+ case UX_ONLY: return 0;
+ case WIN_ONLY: return 1;
+ case MAC_AND_UX_ONLY: return 0;
#elif defined(__APPLE__)
- case MAC_ONLY: return true;
- case UX_ONLY: return false;
- case WIN_ONLY: return false;
- case MAC_AND_UX_ONLY: return true;
+ case MAC_ONLY: return 1;
+ case UX_ONLY: return 0;
+ case WIN_ONLY: return 0;
+ case MAC_AND_UX_ONLY: return 1;
#else
- case MAC_ONLY: return false;
- case UX_ONLY: return true;
- case WIN_ONLY: return false;
- case MAC_AND_UX_ONLY: return true;
+ case MAC_ONLY: return 0;
+ case UX_ONLY: return 1;
+ case WIN_ONLY: return 0;
+ case MAC_AND_UX_ONLY: return 1;
#endif
- case USER_ONLY: return false; // TODO: get user name
- case HOST_ONLY: return false; // TODO: get host name
+ case USER_ONLY: return 0; // TODO: get user name
+ case HOST_ONLY: return 0; // TODO: get host name
case ENV_ONLY: {
- const char *value = fl_getenv(condition_data.c_str());
- if (value && *value) return true;
- return false;
+ const char *value = condition_data ? fl_getenv(condition_data) : 0;
+ if (value && *value) return 1;
+ return 0;
}
}
- return false;
+ return 0;
}
void Fd_Shell_Command::read(Fl_Preferences &prefs) {
int tmp;
char *str_ptr = 0;
prefs.get("name", str_ptr, "<unnamed>");
- if (str_ptr) { name = str_ptr; free(str_ptr); str_ptr = 0; }
+ set_name(str_ptr);
+ if (str_ptr) { free(str_ptr); str_ptr = 0; }
+
prefs.get("label", str_ptr, "<no label>");
- if (str_ptr) { label = str_ptr; free(str_ptr); str_ptr = 0; }
+ set_label(str_ptr);
+ if (str_ptr) { free(str_ptr); str_ptr = 0; }
+
prefs.get("shortcut", tmp, 0);
shortcut = (Fl_Shortcut)tmp;
prefs.get("storage", tmp, -1);
if (tmp != -1) storage = (fld::Tool_Store)tmp;
prefs.get("condition", condition, ALWAYS);
+
prefs.get("condition_data", str_ptr, "");
- if (str_ptr) { condition_data = str_ptr; free(str_ptr); str_ptr = 0; }
+ set_condition_data(str_ptr);
+ if (str_ptr) { free(str_ptr); str_ptr = 0; }
+
prefs.get("command", str_ptr, "");
- if (str_ptr) { command = str_ptr; free(str_ptr); str_ptr = 0; }
+ set_command(str_ptr);
+ if (str_ptr) { free(str_ptr); str_ptr = 0; }
+
prefs.get("flags", flags, 0);
}
-void Fd_Shell_Command::write(Fl_Preferences &prefs, bool save_location) {
- prefs.set("name", name.c_str());
- prefs.set("label", label.c_str());
+void Fd_Shell_Command::write(Fl_Preferences &prefs, int save_location) {
+ prefs.set("name", name ? name : "");
+ prefs.set("label", label ? label : "");
if (shortcut != 0) prefs.set("shortcut", (int)shortcut);
if (save_location) prefs.set("storage", (int)storage);
if (condition != ALWAYS) prefs.set("condition", condition);
- if (!condition_data.empty()) prefs.set("condition_data", condition_data.c_str());
- if (!command.empty()) prefs.set("command", command.c_str());
+ if (condition_data && condition_data[0]) prefs.set("condition_data", condition_data);
+ if (command && command[0]) prefs.set("command", command);
if (flags != 0) prefs.set("flags", flags);
}
@@ -600,17 +594,17 @@ void Fd_Shell_Command::read(class fld::io::Project_Reader *in) {
c = in->read_word(1);
if (strcmp(c, "}")==0) break; // end of command list
else if (strcmp(c, "name")==0)
- name = in->read_word();
+ set_name(in->read_word());
else if (strcmp(c, "label")==0)
- label = in->read_word();
+ set_label(in->read_word());
else if (strcmp(c, "shortcut")==0)
shortcut = in->read_int();
else if (strcmp(c, "condition")==0)
condition = in->read_int();
else if (strcmp(c, "condition_data")==0)
- condition_data = in->read_word();
+ set_condition_data(in->read_word());
else if (strcmp(c, "command")==0)
- command = in->read_word();
+ set_command(in->read_word());
else if (strcmp(c, "flags")==0)
flags = in->read_int();
else
@@ -620,14 +614,14 @@ void Fd_Shell_Command::read(class fld::io::Project_Reader *in) {
void Fd_Shell_Command::write(class fld::io::Project_Writer *out) {
out->write_string("\n command {");
- out->write_string("\n name "); out->write_word(name);
- out->write_string("\n label "); out->write_word(label);
+ out->write_string("\n name "); out->write_word(name ? name : "");
+ out->write_string("\n label "); out->write_word(label ? label : "");
if (shortcut) out->write_string("\n shortcut %d", shortcut);
if (condition) out->write_string("\n condition %d", condition);
- if (!condition_data.empty()) {
+ if (condition_data && condition_data[0]) {
out->write_string("\n condition_data "); out->write_word(condition_data);
}
- if (!command.empty()) {
+ if (command && command[0]) {
out->write_string("\n command "); out->write_word(command);
}
if (flags) out->write_string("\n flags %d", flags);
@@ -639,6 +633,10 @@ void Fd_Shell_Command::write(class fld::io::Project_Writer *out) {
Manage a list of shell commands and their parameters.
*/
Fd_Shell_Command_List::Fd_Shell_Command_List()
+: list(0),
+ list_size(0),
+ list_capacity(0),
+ shell_menu_(0)
{
}
@@ -664,13 +662,14 @@ Fd_Shell_Command *Fd_Shell_Command_List::at(int index) const {
*/
void Fd_Shell_Command_List::clear() {
if (list) {
- for (int i=0; i<list_size; i++) {
+ int i;
+ for (i=0; i<list_size; i++) {
delete list[i];
}
::free(list);
list_size = 0;
list_capacity = 0;
- list = nullptr;
+ list = 0;
}
}
@@ -678,7 +677,8 @@ void Fd_Shell_Command_List::clear() {
remove all shell commands of the given storage location from the list.
*/
void Fd_Shell_Command_List::clear(fld::Tool_Store storage) {
- for (int i=list_size-1; i>=0; i--) {
+ int i;
+ for (i=list_size-1; i>=0; i--) {
if (list[i]->storage == storage) {
remove(i);
}
@@ -689,6 +689,7 @@ void Fd_Shell_Command_List::clear(fld::Tool_Store storage) {
Read shell configuration from a preferences group.
*/
void Fd_Shell_Command_List::read(Fl_Preferences &prefs, fld::Tool_Store storage) {
+ int i, n;
// import the old shell commands from previous user settings
if (&Fluid.preferences == &prefs) {
int version;
@@ -697,12 +698,12 @@ void Fd_Shell_Command_List::read(Fl_Preferences &prefs, fld::Tool_Store storage)
int save_fl, save_code, save_strings;
Fd_Shell_Command *cmd = new Fd_Shell_Command();
cmd->storage = FLD_TOOL_STORE_USER;
- cmd->name = "Sample Shell Command";
- cmd->label = "Sample Shell Command";
+ cmd->set_name("Sample Shell Command");
+ cmd->set_label("Sample Shell Command");
cmd->shortcut = FL_ALT+'g';
char *cmd_str = 0;
Fluid.preferences.get("shell_command", cmd_str, "echo \"Sample Shell Command\"");
- if (cmd_str) { cmd->command = cmd_str; free(cmd_str); }
+ if (cmd_str) { cmd->set_command(cmd_str); free(cmd_str); }
Fluid.preferences.get("shell_savefl", save_fl, 1);
Fluid.preferences.get("shell_writecode", save_code, 1);
Fluid.preferences.get("shell_writemsgs", save_strings, 0);
@@ -715,8 +716,8 @@ void Fd_Shell_Command_List::read(Fl_Preferences &prefs, fld::Tool_Store storage)
prefs.set("shell_commands_version", version);
}
Fl_Preferences shell_commands(prefs, "shell_commands");
- int n = shell_commands.groups();
- for (int i=0; i<n; i++) {
+ n = shell_commands.groups();
+ for (i=0; i<n; i++) {
Fl_Preferences cmd_prefs(shell_commands, Fl_Preferences::Name(i));
Fd_Shell_Command *cmd = new Fd_Shell_Command();
cmd->storage = FLD_TOOL_STORE_USER;
@@ -729,13 +730,14 @@ void Fd_Shell_Command_List::read(Fl_Preferences &prefs, fld::Tool_Store storage)
Write shell configuration to a preferences group.
*/
void Fd_Shell_Command_List::write(Fl_Preferences &prefs, fld::Tool_Store storage) {
+ int i, index;
Fl_Preferences shell_commands(prefs, "shell_commands");
shell_commands.delete_all_groups();
- int index = 0;
- for (int i=0; i<list_size; i++) {
+ index = 0;
+ for (i=0; i<list_size; i++) {
if (list[i]->storage == FLD_TOOL_STORE_USER) {
Fl_Preferences cmd(shell_commands, Fl_Preferences::Name(index++));
- list[i]->write(cmd);
+ list[i]->write(cmd, 0);
}
}
}
@@ -764,14 +766,14 @@ void Fd_Shell_Command_List::read(fld::io::Project_Reader *in) {
Write shell configuration to a project file.
*/
void Fd_Shell_Command_List::write(fld::io::Project_Writer *out) {
- int n_in_project_file = 0;
- for (int i=0; i<list_size; i++) {
+ int i, n_in_project_file = 0;
+ for (i=0; i<list_size; i++) {
if (list[i]->storage == FLD_TOOL_STORE_PROJECT)
n_in_project_file++;
}
if (n_in_project_file > 0) {
out->write_string("\nshell_commands {");
- for (int i=0; i<list_size; i++) {
+ for (i=0; i<list_size; i++) {
if (list[i]->storage == FLD_TOOL_STORE_PROJECT)
list[i]->write(out);
}
@@ -842,12 +844,14 @@ void menu_shell_customize_cb(Fl_Widget*, void*) {
Rebuild the entire shell submenu from scratch and replace the old menu.
*/
void Fd_Shell_Command_List::rebuild_shell_menu() {
- static Fl_Menu_Item *shell_submenu = nullptr;
+ static Fl_Menu_Item *shell_submenu = 0;
+ int i, j, num_active_items;
+
if (!shell_submenu)
shell_submenu = (Fl_Menu_Item*)Fluid.main_menubar->find_item(menu_marker);
- int i, j, num_active_items = 0;
// count the active commands
+ num_active_items = 0;
for (i=0; i<list_size; i++) {
if (list[i]->is_active()) num_active_items++;
}
@@ -875,9 +879,9 @@ void Fd_Shell_Command_List::rebuild_shell_menu() {
// free all resources from the old menu
if (mi_old && (mi_old != default_menu)) {
for (i=0; ; i++) {
- const char *label = mi_old[i].label();
- if (!label) break;
- ::free((void*)label);
+ const char *lbl = mi_old[i].label();
+ if (!lbl) break;
+ ::free((void*)lbl);
}
::free(mi_old);
}
@@ -896,7 +900,7 @@ void Fd_Shell_Command_List::update_settings_dialog() {
*/
Fl_Menu_Item Fd_Shell_Command_List::default_menu[] = {
{ "Customize...", FL_ALT+'x', menu_shell_customize_cb },
- { nullptr }
+ { 0 }
};
/**
@@ -908,12 +912,11 @@ void Fd_Shell_Command_List::menu_marker(Fl_Widget*, void*) {
/**
Export all selected shell commands to an external file.
-
- Verify that g_shell_config and w_settings_shell_list are not nullptr. Open a
- file chooser and export all items that are selected in w_settings_shell_list
- into an external file.
*/
void Fd_Shell_Command_List::export_selected() {
+ char path[FL_PATH_MAX];
+ char preset[FL_PATH_MAX];
+
if (!g_shell_config || (g_shell_config->list_size == 0)) return;
if (!w_settings_shell_list) return;
@@ -921,28 +924,37 @@ void Fd_Shell_Command_List::export_selected() {
dialog.title("Export selected shell commands:");
dialog.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
dialog.filter("FLUID Files\t*.flcmd\n");
- dialog.directory(Fluid.proj.projectfile_path().c_str());
- dialog.preset_file((Fluid.proj.basename() + ".flcmd").c_str());
+
+ Fluid.proj.projectfile_path(path, FL_PATH_MAX);
+ dialog.directory(path);
+
+ Fluid.proj.basename(preset, FL_PATH_MAX);
+ strlcat(preset, ".flcmd", FL_PATH_MAX);
+ dialog.preset_file(preset);
+
if (dialog.show() != 0) return;
- Fl_Preferences file(dialog.filename(), "flcmd.fluid.fltk.org", nullptr, (Fl_Preferences::Root)(Fl_Preferences::C_LOCALE|Fl_Preferences::CLEAR));
+ Fl_Preferences file(dialog.filename(), "flcmd.fluid.fltk.org", 0, (Fl_Preferences::Root)(Fl_Preferences::C_LOCALE|Fl_Preferences::CLEAR));
Fl_Preferences shell_commands(file, "shell_commands");
- int i, index = 0, n = w_settings_shell_list->size();
+ int i, index, n;
+ index = 0;
+ n = w_settings_shell_list->size();
for (i = 0; i < n; i++) {
if (w_settings_shell_list->selected(i+1)) {
Fl_Preferences cmd(shell_commands, Fl_Preferences::Name(index++));
- g_shell_config->list[i]->write(cmd, true);
+ g_shell_config->list[i]->write(cmd, 1);
}
}
}
/**
Import shell commands from an external file and add them to the list.
-
- Verify that g_shell_config and w_settings_shell_list are not nullptr. Open a
- file chooser and import all items.
*/
void Fd_Shell_Command_List::import_from_file() {
+ char path[FL_PATH_MAX];
+ char preset[FL_PATH_MAX];
+ int i, n;
+
if (!g_shell_config || (g_shell_config->list_size == 0)) return;
if (!w_settings_shell_list) return;
@@ -950,13 +962,19 @@ void Fd_Shell_Command_List::import_from_file() {
dialog.title("Import shell commands:");
dialog.type(Fl_Native_File_Chooser::BROWSE_FILE);
dialog.filter("FLUID Files\t*.flcmd\n");
- dialog.directory(Fluid.proj.projectfile_path().c_str());
- dialog.preset_file((Fluid.proj.basename() + ".flcmd").c_str());
+
+ Fluid.proj.projectfile_path(path, FL_PATH_MAX);
+ dialog.directory(path);
+
+ Fluid.proj.basename(preset, FL_PATH_MAX);
+ strlcat(preset, ".flcmd", FL_PATH_MAX);
+ dialog.preset_file(preset);
+
if (dialog.show() != 0) return;
- Fl_Preferences file(dialog.filename(), "flcmd.fluid.fltk.org", nullptr, Fl_Preferences::C_LOCALE);
+ Fl_Preferences file(dialog.filename(), "flcmd.fluid.fltk.org", 0, Fl_Preferences::C_LOCALE);
Fl_Preferences shell_commands(file, "shell_commands");
- int i, n = shell_commands.groups();
+ n = shell_commands.groups();
for (i = 0; i < n; i++) {
Fl_Preferences cmd_prefs(shell_commands, Fl_Preferences::Name(i));
Fd_Shell_Command *cmd = new Fd_Shell_Command();
@@ -973,5 +991,4 @@ void Fd_Shell_Command_List::import_from_file() {
/**
A pointer to the list of shell commands if we are not in batch mode.
*/
-Fd_Shell_Command_List *g_shell_config = nullptr;
-
+Fd_Shell_Command_List *g_shell_config = 0;
diff --git a/fluid/app/shell_command.h b/fluid/app/shell_command.h
index b9e68ca15..716a87349 100644
--- a/fluid/app/shell_command.h
+++ b/fluid/app/shell_command.h
@@ -23,7 +23,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <string>
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <direct.h>
# include <windows.h>
@@ -49,8 +48,8 @@ class Fl_Widget;
class Fl_Preferences;
void show_terminal_window();
-void run_shell_command(const std::string &cmd, int flags);
-bool shell_command_running(void);
+void run_shell_command(const char *cmd, int flags);
+int shell_command_running(void);
class Fl_Process {
@@ -58,7 +57,7 @@ public:
Fl_Process();
~Fl_Process();
- FILE *popen(const char *cmd, const char *mode="r");
+ FILE *popen(const char *cmd, const char *mode);
int close();
FILE * desc() const;
@@ -73,7 +72,7 @@ protected:
PROCESS_INFORMATION pi;
STARTUPINFO si;
- static bool createPipe(HANDLE * h, BOOL bInheritHnd=TRUE);
+ static int createPipe(HANDLE * h, BOOL bInheritHnd);
private:
FILE * freeHandles();
@@ -81,7 +80,7 @@ private:
#endif
protected:
- FILE * _fpt = nullptr;
+ FILE * _fpt;
};
@@ -90,42 +89,51 @@ public:
enum { ALWAYS, NEVER, MAC_ONLY, UX_ONLY, WIN_ONLY, MAC_AND_UX_ONLY, USER_ONLY, HOST_ONLY, ENV_ONLY }; // conditions
enum { SAVE_PROJECT = 1, SAVE_SOURCECODE = 2, SAVE_STRINGS = 4, SAVE_ALL = 7,
DONT_SHOW_TERMINAL = 8, CLEAR_TERMINAL = 16, CLEAR_HISTORY = 32 }; // flags
+
+ char *name;
+ char *label;
+ Fl_Shortcut shortcut;
+ fld::Tool_Store storage;
+ int condition;
+ char *condition_data;
+ char *command;
+ int flags;
+ Fl_Menu_Item *shell_menu_item_;
+
Fd_Shell_Command();
Fd_Shell_Command(const Fd_Shell_Command *rhs);
- Fd_Shell_Command(const std::string &in_name);
- Fd_Shell_Command(const std::string &in_name,
- const std::string &in_label,
+ Fd_Shell_Command(const char *in_name);
+ Fd_Shell_Command(const char *in_name,
+ const char *in_label,
Fl_Shortcut in_shortcut,
fld::Tool_Store in_storage,
int in_condition,
- const std::string &in_condition_data,
- const std::string &in_command,
+ const char *in_condition_data,
+ const char *in_command,
int in_flags);
- std::string name { };
- std::string label { };
- Fl_Shortcut shortcut = 0;
- fld::Tool_Store storage = FLD_TOOL_STORE_USER;
- int condition = ALWAYS; // always, hide, windows only, linux only, mac only, user, machine
- std::string condition_data { }; // user name, machine name
- std::string command { };
- int flags = 0; // save_project, save_code, save_string, ...
- Fl_Menu_Item *shell_menu_item_;
+ ~Fd_Shell_Command();
+
+ void set_name(const char *s);
+ void set_label(const char *s);
+ void set_condition_data(const char *s);
+ void set_command(const char *s);
+
void run();
void read(Fl_Preferences &prefs);
- void write(Fl_Preferences &prefs, bool save_location = false);
+ void write(Fl_Preferences &prefs, int save_location);
void read(class fld::io::Project_Reader*);
void write(class fld::io::Project_Writer*);
void update_shell_menu();
- bool is_active();
+ int is_active();
};
class Fd_Shell_Command_List {
public:
- Fd_Shell_Command **list = nullptr;
- int list_size = 0;
- int list_capacity = 0;
- Fl_Menu_Item *shell_menu_ = nullptr;
+ Fd_Shell_Command **list;
+ int list_size;
+ int list_capacity;
+ Fl_Menu_Item *shell_menu_;
public:
Fd_Shell_Command_List();
~Fd_Shell_Command_List();
@@ -135,10 +143,6 @@ public:
void remove(int index);
void clear();
void clear(fld::Tool_Store store);
-// void move_up();
-// void move_down();
-// int load(const std::string &filename);
-// int save(const std::string &filename);
void read(Fl_Preferences &prefs, fld::Tool_Store storage);
void write(Fl_Preferences &prefs, fld::Tool_Store storage);
void read(class fld::io::Project_Reader*);
diff --git a/fluid/app/templates.cxx b/fluid/app/templates.cxx
index 09fdc0220..8b9b69f2a 100644
--- a/fluid/app/templates.cxx
+++ b/fluid/app/templates.cxx
@@ -93,7 +93,7 @@ void fld::app::save_template() {
if (!fl_access(filename, 0)) {
if (fl_choice("The template \"%s\" already exists.\n"
"Do you want to replace it?", "Cancel",
- "Replace", nullptr, c) == 0) return;
+ "Replace", 0, c) == 0) return;
}
if (!fld::io::write_file(Fluid.proj, filename)) {
@@ -117,7 +117,7 @@ void fld::app::save_template() {
uchar *pixels;
int w, h;
- if ((pixels = wt->read_image(w, h)) == nullptr) return;
+ if ((pixels = wt->read_image(w, h)) == 0) return;
// Save to a PNG file...
strcpy(ext, ".png");