summaryrefslogtreecommitdiff
path: root/fluid/tools
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/tools
parent4ce4967c33d56e4b56d85d11fe0e0be91e159f5d (diff)
wip
Diffstat (limited to 'fluid/tools')
-rw-r--r--fluid/tools/ExternalCodeEditor_UNIX.cxx44
-rw-r--r--fluid/tools/ExternalCodeEditor_UNIX.h2
-rw-r--r--fluid/tools/ExternalCodeEditor_WIN32.cxx46
-rw-r--r--fluid/tools/ExternalCodeEditor_WIN32.h2
-rw-r--r--fluid/tools/autodoc.cxx116
-rw-r--r--fluid/tools/autodoc.h4
-rw-r--r--fluid/tools/filename.cxx289
-rw-r--r--fluid/tools/filename.h67
8 files changed, 246 insertions, 324 deletions
diff --git a/fluid/tools/ExternalCodeEditor_UNIX.cxx b/fluid/tools/ExternalCodeEditor_UNIX.cxx
index 9e9ffd00e..60ed16814 100644
--- a/fluid/tools/ExternalCodeEditor_UNIX.cxx
+++ b/fluid/tools/ExternalCodeEditor_UNIX.cxx
@@ -27,7 +27,7 @@ using namespace fld;
// Static local data
static int L_editors_open = 0; // keep track of #editors open
-static Fl_Timeout_Handler L_update_timer_cb = nullptr; // app's update timer callback
+static Fl_Timeout_Handler L_update_timer_cb = 0; // app's update timer callback
// [Static/Local] See if file exists
static int is_file(const char *filename) {
@@ -59,7 +59,7 @@ static int is_dir(const char *dirname) {
*/
ExternalCodeEditor::ExternalCodeEditor() {
pid_ = -1;
- filename_ = nullptr;
+ filename_ = 0;
file_mtime_ = 0;
file_size_ = 0;
alert_pipe_[0] = alert_pipe_[1] = -1;
@@ -75,7 +75,7 @@ ExternalCodeEditor::~ExternalCodeEditor() {
printf("ExternalCodeEditor() DTOR CALLED (this=%p, pid=%ld)\n",
(void*)this, (long)pid_);
close_editor(); // close editor, delete tmp file
- set_filename(nullptr); // free()s filename
+ set_filename(0); // free()s filename
if (alert_pipe_open_) {
Fl::remove_fd(alert_pipe_[0]);
@@ -87,12 +87,12 @@ ExternalCodeEditor::~ExternalCodeEditor() {
/**
Set the filename for the file we wish to edit.
Handles memory allocation/free.
- If set to nullptr, frees memory.
+ If set to 0, frees memory.
\param[in] val new filename
*/
void ExternalCodeEditor::set_filename(const char *val) {
if ( filename_ ) free((void*)filename_);
- filename_ = val ? fl_strdup(val) : nullptr;
+ filename_ = val ? fl_strdup(val) : 0;
}
/**
@@ -121,7 +121,7 @@ void ExternalCodeEditor::close_editor() {
switch ( fl_choice("Please close external editor\npid=%ld file=%s",
"Force Close", // button 0
"Closed", // button 1
- nullptr, // button 2
+ 0, // button 2
long(pid_), filename() ) ) {
case 0: // Force Close
kill_editor();
@@ -187,7 +187,7 @@ void ExternalCodeEditor::kill_editor() {
\return -1 error getting file info (strerror() has reason)
*/
int ExternalCodeEditor::handle_changes(const char **code, int force) {
- code[0] = nullptr;
+ code[0] = 0;
if ( !is_editing() ) return 0;
// Get current time/size info, see if file changed
int changed = 0;
@@ -247,7 +247,7 @@ int ExternalCodeEditor::remove_tmpfile() {
return -1;
}
}
- set_filename(nullptr);
+ set_filename(0);
file_mtime_ = 0;
file_size_ = 0;
return 1;
@@ -280,7 +280,7 @@ void ExternalCodeEditor::tmpdir_clear() {
/**
Creates temp dir (if doesn't exist) and returns the dirname
as a static string.
- \return nullptr on error, dialog shows reason.
+ \return 0 on error, dialog shows reason.
*/
const char* ExternalCodeEditor::create_tmpdir() {
const char *dirname = tmpdir_name();
@@ -288,7 +288,7 @@ const char* ExternalCodeEditor::create_tmpdir() {
if ( mkdir(dirname, 0777) < 0 ) {
fl_alert("can't create directory '%s': %s",
dirname, strerror(errno));
- return nullptr;
+ return 0;
}
}
return dirname;
@@ -296,13 +296,13 @@ const char* ExternalCodeEditor::create_tmpdir() {
/**
Returns temp filename in static buffer.
- \return nullptr if can't, posts dialog explaining why.
+ \return 0 if can't, posts dialog explaining why.
*/
const char* ExternalCodeEditor::tmp_filename() {
static char path[FL_PATH_MAX+1];
const char *tmpdir = create_tmpdir();
- if ( !tmpdir ) return nullptr;
- const char *ext = Fluid.proj.code_file_name.c_str(); // e.g. ".cxx"
+ if ( !tmpdir ) return 0;
+ const char *ext = Fluid.proj.code_file_name(); // e.g. ".cxx"
snprintf(path, FL_PATH_MAX, "%s/%p%s", tmpdir, (void*)this, ext);
path[FL_PATH_MAX] = 0;
return path;
@@ -310,12 +310,12 @@ const char* ExternalCodeEditor::tmp_filename() {
/**
Save string 'code' to 'filename', returning file's mtime/size.
- 'code' can be nullptr -- writes an empty file if so.
+ 'code' can be 0 -- writes an empty file if so.
\return 0 on success
\return -1 on error (posts dialog with reason)
*/
static int save_file(const char *filename, const char *code) {
- if ( code == nullptr ) code = ""; // nullptr? write an empty file
+ if ( code == 0 ) code = ""; // 0? write an empty file
int fd = open(filename, O_WRONLY|O_CREAT, 0666);
if ( fd == -1 ) {
fl_alert("ERROR: open() '%s': %s", filename, strerror(errno));
@@ -338,7 +338,7 @@ static int save_file(const char *filename, const char *code) {
/**
Convert string 's' to array of argv[], useful for execve().
- - 's' will be modified (words will be nullptr separated)
+ - 's' will be modified (words will be 0 separated)
- argv[] will end up pointing to the words of 's'
- Caller must free argv with: free(argv);
\return -1 in case of memory allocation error
@@ -348,14 +348,14 @@ static int make_args(char *s, // string containing words (gets trashed!)
int *aargc, // pointer to argc
char ***aargv) { // pointer to argv
char *ss, **argv;
- if ((argv=(char**)malloc(sizeof(char*) * (strlen(s)/2)))==nullptr) {
+ if ((argv=(char**)malloc(sizeof(char*) * (strlen(s)/2)))==0) {
return -1;
}
int t;
- for(t=0; (t==0)?(ss=strtok(s," \t")):(ss=strtok(nullptr," \t")); t++) {
+ for(t=0; (t==0)?(ss=strtok(s," \t")):(ss=strtok(0," \t")); t++) {
argv[t] = ss;
}
- argv[t] = nullptr;
+ argv[t] = 0;
aargv[0] = argv;
aargc[0] = t;
return(t);
@@ -401,7 +401,7 @@ int ExternalCodeEditor::start_editor(const char *editor_cmd,
// NOTE: no FLTK calls after a fork. Use a pipe to tell the app if the
// command can't launch
int nargs;
- char **args = nullptr;
+ char **args = 0;
if (make_args(cmd, &nargs, &args) > 0) {
execvp(args[0], args); // run command - doesn't return if succeeds
if (alert_pipe_open_) {
@@ -428,7 +428,7 @@ int ExternalCodeEditor::start_editor(const char *editor_cmd,
/**
Try to reap external editor process.
- If 'pid_reaped' not nullptr, returns PID of reaped editor.
+ If 'pid_reaped' not 0, returns PID of reaped editor.
\return -2: editor not open
\return -1: waitpid() failed (errno has reason)
@@ -464,7 +464,7 @@ int ExternalCodeEditor::reap_editor(pid_t *pid_reaped) {
Open external editor using 'editor_cmd' to edit 'code'.
'code' contains multiline code to be edited as a temp file.
- 'code' can be nullptr -- edits an empty file if so.
+ 'code' can be 0 -- edits an empty file if so.
\return 0 if succeeds
\return -1 if can't open editor (already open, etc),
diff --git a/fluid/tools/ExternalCodeEditor_UNIX.h b/fluid/tools/ExternalCodeEditor_UNIX.h
index 2142d5a10..dfcc1e785 100644
--- a/fluid/tools/ExternalCodeEditor_UNIX.h
+++ b/fluid/tools/ExternalCodeEditor_UNIX.h
@@ -42,7 +42,7 @@ public:
ExternalCodeEditor();
~ExternalCodeEditor();
int is_editing();
- int reap_editor(pid_t *pid_reaped=nullptr);
+ int reap_editor(pid_t *pid_reaped=0);
void close_editor();
const char *filename() { return filename_; }
int open_editor(const char *editor_cmd, const char *code);
diff --git a/fluid/tools/ExternalCodeEditor_WIN32.cxx b/fluid/tools/ExternalCodeEditor_WIN32.cxx
index 64d791400..ea9178c63 100644
--- a/fluid/tools/ExternalCodeEditor_WIN32.cxx
+++ b/fluid/tools/ExternalCodeEditor_WIN32.cxx
@@ -33,12 +33,12 @@ using namespace fld;
// Static local data
static int L_editors_open = 0; // keep track of #editors open
static Fl_Timeout_Handler L_update_timer_cb = 0; // app's update timer callback
-static wchar_t *wbuf = nullptr;
-static char *abuf = nullptr;
+static wchar_t *wbuf = 0;
+static char *abuf = 0;
static wchar_t *utf8_to_wchar(const char *utf8, wchar_t *&wbuf, int lg = -1) {
unsigned len = (lg >= 0) ? (unsigned)lg : (unsigned)strlen(utf8);
- unsigned wn = fl_utf8toUtf16(utf8, len, nullptr, 0) + 1; // Query length
+ unsigned wn = fl_utf8toUtf16(utf8, len, 0, 0) + 1; // Query length
wbuf = (wchar_t *)realloc(wbuf, sizeof(wchar_t) * wn);
wn = fl_utf8toUtf16(utf8, len, (unsigned short *)wbuf, wn); // Convert string
wbuf[wn] = 0;
@@ -47,7 +47,7 @@ static wchar_t *utf8_to_wchar(const char *utf8, wchar_t *&wbuf, int lg = -1) {
static char *wchar_to_utf8(const wchar_t *wstr, char *&utf8) {
unsigned len = (unsigned)wcslen(wstr);
- unsigned wn = fl_utf8fromwc(nullptr, 0, wstr, len) + 1; // query length
+ unsigned wn = fl_utf8fromwc(0, 0, wstr, len) + 1; // query length
utf8 = (char *)realloc(utf8, wn);
wn = fl_utf8fromwc(utf8, wn, wstr, len); // convert string
utf8[wn] = 0;
@@ -68,7 +68,7 @@ static const char *get_ms_errmsg() {
DWORD msize = 0;
// Get error message from Windows
- msize = FormatMessageW(flags, 0, lastErr, langid, (LPWSTR)&mbuf, 0, nullptr);
+ msize = FormatMessageW(flags, 0, lastErr, langid, (LPWSTR)&mbuf, 0, 0);
if ( msize == 0 ) {
_snprintf(emsg, sizeof(emsg), "Error #%ld", (unsigned long)lastErr);
} else {
@@ -119,7 +119,7 @@ ExternalCodeEditor::~ExternalCodeEditor() {
}
// [Protected] Set the filename. Handles memory allocation/free
-// If set to nullptr, frees memory.
+// If set to 0, frees memory.
//
void ExternalCodeEditor::set_filename(const char *val) {
if ( filename_ ) free((void*)filename_);
@@ -252,10 +252,10 @@ int ExternalCodeEditor::handle_changes(const char **code, int force) {
HANDLE fh = CreateFileW(wbuf, // file to read
GENERIC_READ, // reading only
FILE_SHARE_READ, // sharing -- allow read share; just getting file size
- nullptr, // security
+ 0, // security
OPEN_EXISTING, // create flags -- must exist
0, // misc flags
- nullptr); // templates
+ 0); // templates
if ( fh == INVALID_HANDLE_VALUE ) return -1;
LARGE_INTEGER fsize;
// Get file size
@@ -368,7 +368,7 @@ void ExternalCodeEditor::tmpdir_clear() {
}
// [Protected] Creates temp dir (if doesn't exist) and returns the dirname
-// as a static string. Returns nullptr on error, dialog shows reason.
+// as a static string. Returns 0 on error, dialog shows reason.
//
const char* ExternalCodeEditor::create_tmpdir() {
const char *dirname = tmpdir_name();
@@ -377,14 +377,14 @@ const char* ExternalCodeEditor::create_tmpdir() {
if (CreateDirectoryW(wbuf, 0) == 0) {
fl_alert("can't create directory '%s': %s",
dirname, get_ms_errmsg());
- return nullptr;
+ return 0;
}
}
return dirname;
}
// [Protected] Returns temp filename in static buffer.
-// Returns nullptr if can't, posts dialog explaining why.
+// Returns 0 if can't, posts dialog explaining why.
//
const char* ExternalCodeEditor::tmp_filename() {
static char path[512];
@@ -397,7 +397,7 @@ const char* ExternalCodeEditor::tmp_filename() {
}
// [Static/Local] Save string 'code' to 'filename', returning file's mtime/size
-// 'code' can be nullptr -- writes an empty file if so.
+// 'code' can be 0 -- writes an empty file if so.
// Returns:
// 0 on success
// -1 on error (posts dialog with reason)
@@ -406,17 +406,17 @@ static int save_file(const char *filename,
const char *code,
FILETIME &file_mtime, // return these since in win32 it's..
LARGE_INTEGER &file_size) { // ..efficient to get while file open
- if ( code == 0 ) code = ""; // nullptr? write an empty file
+ if ( code == 0 ) code = ""; // 0? write an empty file
memset(&file_mtime, 0, sizeof(file_mtime));
memset(&file_size, 0, sizeof(file_size));
utf8_to_wchar(filename, wbuf);
HANDLE fh = CreateFileW(wbuf, // filename
GENERIC_WRITE, // write only
0, // sharing -- no share during write
- nullptr, // security
+ 0, // security
CREATE_ALWAYS, // create flags -- recreate
FILE_ATTRIBUTE_NORMAL, // misc flags
- nullptr); // templates
+ 0); // templates
if ( fh == INVALID_HANDLE_VALUE ) {
fl_alert("ERROR: couldn't create file '%s': %s",
filename, get_ms_errmsg());
@@ -426,7 +426,7 @@ static int save_file(const char *filename,
DWORD clen = (DWORD)strlen(code);
DWORD count = 0;
int ret = 0;
- if ( WriteFile(fh, code, clen, &count, nullptr) == 0 ) {
+ if ( WriteFile(fh, code, clen, &count, 0) == 0 ) {
fl_alert("ERROR: WriteFile() '%s': %s", filename, get_ms_errmsg());
ret = -1; // fallthru to CloseHandle()
} else if ( count != clen ) {
@@ -474,14 +474,14 @@ int ExternalCodeEditor::start_editor(const char *editor_cmd,
_snprintf(cmd, sizeof(cmd), "%s %s", editor_cmd, filename);
utf8_to_wchar(cmd, wbuf);
// Start editor process
- if (CreateProcessW(nullptr, // app name
+ if (CreateProcessW(0, // app name
wbuf, // command to exec
- nullptr, // secure attribs
- nullptr, // thread secure attribs
+ 0, // secure attribs
+ 0, // thread secure attribs
FALSE, // handle inheritance
0, // creation flags
- nullptr, // environ block
- nullptr, // current dir
+ 0, // environ block
+ 0, // current dir
&sinfo, // startup info
&pinfo_) == 0 ) { // process info
fl_alert("CreateProcess() failed to start '%s': %s",
@@ -512,7 +512,7 @@ void ExternalCodeEditor::reap_cleanup() {
}
// [Public] Try to reap external editor process
-// If 'pid_reaped' not nullptr, returns PID of reaped editor.
+// If 'pid_reaped' not 0, returns PID of reaped editor.
// Returns:
// -2 -- editor not open
// -1 -- WaitForSingleObject() failed (get_ms_errmsg() has reason)
@@ -548,7 +548,7 @@ int ExternalCodeEditor::reap_editor(DWORD *pid_reaped) {
// [Public] Open external editor using 'editor_cmd' to edit 'code'.
//
// 'code' contains multiline code to be edited as a temp file.
-// 'code' can be nullptr -- edits an empty file if so.
+// 'code' can be 0 -- edits an empty file if so.
//
// Returns:
// 0 if succeeds
diff --git a/fluid/tools/ExternalCodeEditor_WIN32.h b/fluid/tools/ExternalCodeEditor_WIN32.h
index 83c50a742..679e474c1 100644
--- a/fluid/tools/ExternalCodeEditor_WIN32.h
+++ b/fluid/tools/ExternalCodeEditor_WIN32.h
@@ -43,7 +43,7 @@ public:
ExternalCodeEditor();
~ExternalCodeEditor();
int is_editing();
- int reap_editor(DWORD *pid_reaped=nullptr);
+ int reap_editor(DWORD *pid_reaped=0);
void close_editor();
const char *filename() { return filename_; }
int open_editor(const char *editor_cmd, const char *code);
diff --git a/fluid/tools/autodoc.cxx b/fluid/tools/autodoc.cxx
index 51afe76c6..a59e08ab9 100644
--- a/fluid/tools/autodoc.cxx
+++ b/fluid/tools/autodoc.cxx
@@ -233,7 +233,7 @@ void blend_alpha_bottom(const Fl_RGB_Image *img, int dy) {
created in FLTK resolution, even if the screen uses a higher resolution.
\param[in] filename the snapshot will be written to this file in png format
- \param[in] w draw a bounding box around all widgets in the nullptr terminated list
+ \param[in] w draw a bounding box around all widgets in the 0 terminated list
\param[in] frame add a margin around the bounding box
\param[in] blend add another margin around the bounding box that fades to full transparency
\param[in] scale scale everything by this factor before saving it
@@ -343,7 +343,7 @@ int fl_snapshot(const char *filename, Fl_Widget *w1, Fl_Widget *w2,
const Fl_Rect &blend,
double scale)
{
- Fl_Widget *ww[3] = { w1, w2, nullptr };
+ Fl_Widget *ww[3] = { w1, w2, 0 };
return fl_snapshot(filename, ww, frame, blend, scale);
}
@@ -364,14 +364,18 @@ int fl_snapshot(const char *filename, Fl_Widget *w,
const Fl_Rect &blend,
double scale)
{
- Fl_Widget *ww[2] = { w, nullptr };
+ Fl_Widget *ww[2] = { w, 0 };
return fl_snapshot(filename, ww, frame, blend, scale);
}
/** @} */
-void run_autodoc(const std::string &target_dir) {
+// Helper macro to build snapshot path
+#define SNAP_PATH(filename) (snprintf(snap_path, FL_PATH_MAX, "%s%s", target_dir, filename), snap_path)
+
+void run_autodoc(const char *target_dir) {
+ char snap_path[FL_PATH_MAX];
// A list of all the margins we will use later
Fl_Margin win_margin(0, 0, 0, 0);
Fl_Margin win_blend(10, 10, 10, 10);
@@ -384,7 +388,7 @@ void run_autodoc(const std::string &target_dir) {
// Fl::scheme("gtk+");
// Create a silly project that contains all widgets that we want to document
- Fluid.new_project(false);
+ Fluid.new_project(0);
/*Node *t_func = */ add_new_widget_from_user("Function", Strategy::AS_LAST_CHILD, false);
Window_Node *t_win = (Window_Node*)add_new_widget_from_user("Fl_Window", Strategy::AS_LAST_CHILD, false);
@@ -430,9 +434,9 @@ void run_autodoc(const std::string &target_dir) {
// explain widget browser
// explain widget browser entry
Fluid.main_window->size(350, 320);
- fl_snapshot((target_dir + "main_window.png").c_str(), Fluid.main_window, win_margin, win_blend);
- fl_snapshot((target_dir + "main_menubar.png").c_str(), Fluid.main_menubar, row_margin, row_blend);
- fl_snapshot((target_dir + "main_browser.png").c_str(), widget_browser, FL_SNAP_AREA_CLEAR,
+ fl_snapshot(SNAP_PATH("main_window.png"), Fluid.main_window, win_margin, win_blend);
+ fl_snapshot(SNAP_PATH("main_menubar.png"), Fluid.main_menubar, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("main_browser.png"), widget_browser, FL_SNAP_AREA_CLEAR,
Fl_Rect(0, 30, FL_SNAP_TO_WINDOW, 100), row_blend, 2.0);
@@ -454,7 +458,7 @@ void run_autodoc(const std::string &target_dir) {
// list exceptions (subwindow, scroll)
Fl::wait(0.2);
Fl::flush();
- fl_snapshot((target_dir + "widgetbin_panel.png").c_str(), widgetbin_panel, win_margin, win_blend);
+ fl_snapshot(SNAP_PATH("widgetbin_panel.png"), widgetbin_panel, win_margin, win_blend);
// ---- code view
// explain functionality
@@ -465,35 +469,35 @@ void run_autodoc(const std::string &target_dir) {
codeview_panel->show();
Fl::wait(0.2);
Fl::flush();
- update_codeview_cb(nullptr, nullptr); // must be visible on screen for this to work
+ update_codeview_cb(0, 0); // must be visible on screen for this to work
cv_tab->value(cv_source_tab);
codeview_panel->redraw();
Fl::flush();
- fl_snapshot((target_dir + "codeview_panel.png").c_str(), codeview_panel, win_margin, win_blend);
- fl_snapshot((target_dir + "cv_find_row.png").c_str(), cv_find_row, row_margin, row_blend);
- fl_snapshot((target_dir + "cv_settings_row.png").c_str(), cv_settings_row, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("codeview_panel.png"), codeview_panel, win_margin, win_blend);
+ fl_snapshot(SNAP_PATH("cv_find_row.png"), cv_find_row, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("cv_settings_row.png"), cv_settings_row, row_margin, row_blend);
// ---- settings dialog
// show and explain all tabs
- fl_snapshot((target_dir + "w_settings.png").c_str(), settings_window, win_margin, win_blend);
- fl_snapshot((target_dir + "w_settings_general_tab.png").c_str(), w_settings_general_tab, xtab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("w_settings.png"), settings_window, win_margin, win_blend);
+ fl_snapshot(SNAP_PATH("w_settings_general_tab.png"), w_settings_general_tab, xtab_margin, row_blend);
w_settings_tabs->value(w_settings_project_tab);
- fl_snapshot((target_dir + "w_settings_project_tab.png").c_str(), w_settings_project_tab, xtab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("w_settings_project_tab.png"), w_settings_project_tab, xtab_margin, row_blend);
w_settings_tabs->value(w_settings_layout_tab);
- fl_snapshot((target_dir + "w_settings_layout_tab.png").c_str(), w_settings_layout_tab, xtab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("w_settings_layout_tab.png"), w_settings_layout_tab, xtab_margin, row_blend);
w_settings_tabs->value(w_settings_shell_tab);
w_settings_shell_list->value(1);
w_settings_shell_list->do_callback();
- fl_snapshot((target_dir + "w_settings_shell_tab.png").c_str(), w_settings_shell_tab, xtab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("w_settings_shell_tab.png"), w_settings_shell_tab, xtab_margin, row_blend);
w_settings_tabs->value(w_settings_i18n_tab);
i18n_type_chooser->value(1);
i18n_type_chooser->do_callback();
- fl_snapshot((target_dir + "w_settings_i18n_gnu.png").c_str(), i18n_type_chooser, i18n_gnu_static_function_input, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("w_settings_i18n_gnu.png"), i18n_type_chooser, i18n_gnu_static_function_input, row_margin, row_blend);
i18n_type_chooser->value(2);
i18n_type_chooser->do_callback();
- fl_snapshot((target_dir + "w_settings_i18n_psx.png").c_str(), i18n_type_chooser, i18n_pos_set_input, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("w_settings_i18n_psx.png"), i18n_type_chooser, i18n_pos_set_input, row_margin, row_blend);
w_settings_tabs->value(w_settings_user_tab);
- fl_snapshot((target_dir + "w_settings_user_tab.png").c_str(), w_settings_user_tab, xtab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("w_settings_user_tab.png"), w_settings_user_tab, xtab_margin, row_blend);
// ---- dialog types
@@ -505,33 +509,33 @@ void run_autodoc(const std::string &target_dir) {
// -- FLD_NODE_TYPE_Function
select_only(t_func);
- fl_snapshot((target_dir + "function_panel.png").c_str(), func_tabs_main, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("function_panel.png"), func_tabs_main, tab_margin, row_blend);
// -- FLD_NODE_TYPE_Code
select_only(t_code);
- fl_snapshot((target_dir + "code_panel.png").c_str(), code_tabs_main, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("code_panel.png"), code_tabs_main, tab_margin, row_blend);
// -- FLD_NODE_TYPE_CodeBlock
select_only(t_codeblock);
- fl_snapshot((target_dir + "codeblock_panel.png").c_str(), declblock_tabs_main, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("codeblock_panel.png"), declblock_tabs_main, tab_margin, row_blend);
// -- FLD_NODE_TYPE_Decl
select_only(t_decl);
- fl_snapshot((target_dir + "decl_panel.png").c_str(), decl_tabs_main, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("decl_panel.png"), decl_tabs_main, tab_margin, row_blend);
// -- FLD_NODE_TYPE_DeclBlock
select_only(t_declblock);
- fl_snapshot((target_dir + "declblock_panel.png").c_str(), declblock_tabs_main, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("declblock_panel.png"), declblock_tabs_main, tab_margin, row_blend);
// -- FLD_NODE_TYPE_Class
select_only(t_class);
- fl_snapshot((target_dir + "class_panel.png").c_str(), class_tabs_main, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("class_panel.png"), class_tabs_main, tab_margin, row_blend);
// -- FLD_NODE_TYPE_Widget_Class is handled like Window_Node
// -- FLD_NODE_TYPE_Comment
select_only(t_comment);
- fl_snapshot((target_dir + "comment_panel.png").c_str(), comment_tabs_comment, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("comment_panel.png"), comment_tabs_comment, tab_margin, row_blend);
// ---- widget dialog
t_win->open(); // open the window
@@ -539,66 +543,66 @@ void run_autodoc(const std::string &target_dir) {
select_only(t_win);
// -- snapshot of the widget properties panel
- fl_snapshot((target_dir + "widget_panel.png").c_str(), the_panel, win_margin, win_blend);
- fl_snapshot((target_dir + "wLiveMode.png").c_str(), wLiveMode, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("widget_panel.png"), the_panel, win_margin, win_blend);
+ fl_snapshot(SNAP_PATH("wLiveMode.png"), wLiveMode, row_margin, row_blend);
// -- snapshot of the GUI tab
widget_tabs->value(wp_gui_tab);
- fl_snapshot((target_dir + "wp_gui_tab.png").c_str(), wp_gui_tab, tab_margin, row_blend);
- fl_snapshot((target_dir + "wp_gui_label.png").c_str(), wp_gui_label, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_tab.png"), wp_gui_tab, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_label.png"), wp_gui_label, row_margin, row_blend);
select_only(t_btn);
- fl_snapshot((target_dir + "wp_gui_image.png").c_str(), widget_image_input, widget_deimage_input, row_margin, row_blend);
- fl_snapshot((target_dir + "wp_gui_alignment.png").c_str(), wp_gui_alignment, row_margin, row_blend);
- fl_snapshot((target_dir + "wp_gui_size.png").c_str(), widget_x_input, xrow_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_image.png"), widget_image_input, widget_deimage_input, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_alignment.png"), wp_gui_alignment, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_size.png"), widget_x_input, xrow_margin, row_blend);
select_only(t_sldr);
- fl_snapshot((target_dir + "wp_gui_values.png").c_str(), wp_gui_values, xrow_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_values.png"), wp_gui_values, xrow_margin, row_blend);
select_only(t_flxc);
- fl_snapshot((target_dir + "wp_gui_flexp.png").c_str(), wp_gui_flexp, xrow_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_flexp.png"), wp_gui_flexp, xrow_margin, row_blend);
select_only(t_flx);
- fl_snapshot((target_dir + "wp_gui_margins.png").c_str(), wp_gui_margins, xrow_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_margins.png"), wp_gui_margins, xrow_margin, row_blend);
select_only(t_win);
- fl_snapshot((target_dir + "wp_gui_sizerange.png").c_str(), wp_gui_sizerange, xrow_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_sizerange.png"), wp_gui_sizerange, xrow_margin, row_blend);
select_only(t_btn);
- fl_snapshot((target_dir + "wp_gui_shortcut.png").c_str(), wp_gui_shortcut, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_shortcut.png"), wp_gui_shortcut, row_margin, row_blend);
select_only(t_win);
- fl_snapshot((target_dir + "wp_gui_xclass.png").c_str(), wp_gui_xclass, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_xclass.png"), wp_gui_xclass, row_margin, row_blend);
select_only(t_btn);
- fl_snapshot((target_dir + "wp_gui_attributes.png").c_str(), wp_gui_attributes, row_margin, row_blend);
- fl_snapshot((target_dir + "wp_gui_tooltip.png").c_str(), wp_gui_tooltip, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_attributes.png"), wp_gui_attributes, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gui_tooltip.png"), wp_gui_tooltip, row_margin, row_blend);
// -- snapshot of the style tab
widget_tabs->value(wp_style_tab);
select_only(t_inp);
- fl_snapshot((target_dir + "wp_style_tab.png").c_str(), wp_style_tab, tab_margin, row_blend);
- fl_snapshot((target_dir + "wp_style_label.png").c_str(), wp_style_label, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_style_tab.png"), wp_style_tab, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_style_label.png"), wp_style_label, row_margin, row_blend);
select_only(t_btn);
- fl_snapshot((target_dir + "wp_style_box.png").c_str(), wp_style_box, wp_style_downbox, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_style_box.png"), wp_style_box, wp_style_downbox, row_margin, row_blend);
select_only(t_inp);
- fl_snapshot((target_dir + "wp_style_text.png").c_str(), wp_style_text, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_style_text.png"), wp_style_text, row_margin, row_blend);
// -- snapshot of the C++ tab
widget_tabs->value(wp_cpp_tab);
select_only(t_btn);
- fl_snapshot((target_dir + "wp_cpp_tab.png").c_str(), wp_cpp_tab, tab_margin, row_blend);
- fl_snapshot((target_dir + "wp_cpp_class.png").c_str(), wp_cpp_class, row_margin, row_blend);
- fl_snapshot((target_dir + "wp_cpp_name.png").c_str(), wp_cpp_name, row_margin, row_blend);
- fl_snapshot((target_dir + "v_input.png").c_str(), v_input[0], v_input[3], row_margin, row_blend);
- fl_snapshot((target_dir + "wComment.png").c_str(), wComment, row_margin, row_blend);
- fl_snapshot((target_dir + "wp_cpp_callback.png").c_str(), wCallback, w_when_box, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_cpp_tab.png"), wp_cpp_tab, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_cpp_class.png"), wp_cpp_class, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_cpp_name.png"), wp_cpp_name, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("v_input.png"), v_input[0], v_input[3], row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wComment.png"), wComment, row_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_cpp_callback.png"), wCallback, w_when_box, row_margin, row_blend);
// -- snapshot of the Grid tab
select_only(t_grd);
widget_tabs->value(widget_tab_grid);
- fl_snapshot((target_dir + "wp_grid_tab.png").c_str(), widget_tab_grid, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_grid_tab.png"), widget_tab_grid, tab_margin, row_blend);
// -- snapshot of the Grid Child tab
select_only(t_grdc);
widget_tabs->value(widget_tab_grid_child);
- fl_snapshot((target_dir + "wp_gridc_tab.png").c_str(), widget_tab_grid_child, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("wp_gridc_tab.png"), widget_tab_grid_child, tab_margin, row_blend);
// -- FLD_NODE_TYPE_Data
select_only(t_data);
- fl_snapshot((target_dir + "data_panel.png").c_str(), data_tabs_data, tab_margin, row_blend);
+ fl_snapshot(SNAP_PATH("data_panel.png"), data_tabs_data, tab_margin, row_blend);
}
diff --git a/fluid/tools/autodoc.h b/fluid/tools/autodoc.h
index 136a7e119..51a39724c 100644
--- a/fluid/tools/autodoc.h
+++ b/fluid/tools/autodoc.h
@@ -26,8 +26,6 @@
#include <FL/Fl_Window.H>
#include <FL/Fl_Rect.H>
-#include <string>
-
/** Class to initialize a Rect by providing the margin around a rect. */
class Fl_Margin : public Fl_Rect {
public:
@@ -53,7 +51,7 @@ extern const int FL_SNAP_TO_WINDOW;
extern Fl_Widget *FL_SNAP_AREA_CLEAR;
-extern void run_autodoc(const std::string &target_dir);
+extern void run_autodoc(const char *target_dir);
#endif
diff --git a/fluid/tools/filename.cxx b/fluid/tools/filename.cxx
index 72386f78b..1cecb387b 100644
--- a/fluid/tools/filename.cxx
+++ b/fluid/tools/filename.cxx
@@ -17,16 +17,6 @@
/** \file fluid/filename.cxx
\brief File names and URI utility functions for FLUID only.
-
- This file defines all fl_filename* functions using std::string and also
- includes the main header file <FL/filename.H>.
-
- \note This file contains some filename functions using std::string which
- which are used in FLTK 1.4.x but will be removed in the next minor
- or major release after 1.4.x (i.e. 1.5 or maybe 4.0).
-
- \note This entire file should become obsolete in 1.5 or higher, whatever
- the next release after 1.4.x will be. We'll use std::string instead!
*/
#include "tools/filename.h"
@@ -35,226 +25,149 @@
#include <FL/fl_utf8.h>
#include <FL/Fl.H>
#include "../src/flstring.h"
-//#include <FL/fl_string_functions.h>
-//#include "../src/flstring.h"
-//
-//#include <stdlib.h>
-//#include <string>
+
+#include <string.h>
/**
Return a shortened filename for limited display width.
- Replace the start uf a path with "~" if it matches the home directory.
- If the remaining filename has more than the give number of characters, it will
+ Replace the start of a path with "~" if it matches the home directory.
+ If the remaining filename has more than the given number of characters, it will
be shortened by replacing parts of the path with an ellipsis ("...").
The shortened name can no longer be used to open a file. This is purely to
- make as much information visible while fitting into a give space.
+ make as much information visible while fitting into a given space.
+ \param[out] result buffer to store result
+ \param[in] result_size size of result buffer
\param[in] filename absolute path and name, UTF-8 aware
- \param[in[ max_chars maximum number of characters in result, including ellipsis
- \return shortened file path and name
+ \param[in] max_chars maximum number of characters in result, including ellipsis
+ \return pointer to result buffer
*/
-std::string fl_filename_shortened(const std::string &filename, int max_chars) {
+char *fl_filename_shortened(char *result, int result_size, const char *filename, int max_chars) {
// Insert this as the ellipsis
static const char *ell = "...";
static const int ell_bytes = 3;
// Replace the start of a path with "~" if it matches the home directory
- static std::string tilde = "~/";
- static std::string home;
+ static char home[FL_PATH_MAX] = "";
+ static int home_len = -1;
static int home_chars = -1;
- if (home_chars==-1) {
- home = fl_filename_expand_str(tilde);
- home_chars = fl_utf_nb_char((const uchar*)home.c_str(), (int)home.size());
+
+ if (home_chars == -1) {
+ fl_filename_expand(home, FL_PATH_MAX, "~/");
+ home_len = (int)strlen(home);
+ home_chars = fl_utf_nb_char((const unsigned char*)home, home_len);
}
- std::string homed_filename;
-#if defined(_WIN32) || defined(__APPLE__)
- bool starts_with_home = fl_utf_strncasecmp(home.c_str(), filename.c_str(), home_chars)==0;
-#else
- bool starts_with_home = ::strncmp(home.c_str(), filename.c_str(), home.size())==0;
-#endif
+
+ // Check if filename starts with home directory
+ char homed_filename[FL_PATH_MAX];
+ int starts_with_home = (strncmp(home, filename, home_len) == 0);
if (starts_with_home) {
- homed_filename = tilde + filename.substr(home.size());
+ snprintf(homed_filename, FL_PATH_MAX, "~/%s", filename + home_len);
} else {
- homed_filename = filename;
+ strlcpy(homed_filename, filename, FL_PATH_MAX);
}
- // C style pointer will stay valid until filename is modified.
- const unsigned char *u8str = reinterpret_cast<const unsigned char *>(homed_filename.c_str());
- // Count the number of UTF-8 characters in the name.
- int num_chars = fl_utf_nb_char(u8str, (int)homed_filename.size());
- if (num_chars+ell_bytes-1 > max_chars) {
- // Create a new string by replacing characters in the middle.
- int remove_chars = num_chars - max_chars + ell_bytes;
- int left_chars = (max_chars - ell_bytes)/2;
-// int right_chars = max_chars - left_chars - 3;
-// int right_start_char = num_chars - right_chars;
- // Convert character counts into byte counts.
- int left_bytes = fl_utf8strlen(homed_filename.c_str(), left_chars);
- int right_start_byte = fl_utf8strlen(homed_filename.c_str()+left_bytes, remove_chars) + left_bytes;
- return homed_filename.substr(0, left_bytes) + ell + homed_filename.substr(right_start_byte);
- } else {
- // Nothing to change.
- return homed_filename;
- }
-}
-/**
- Make sure that a path name ends with a forward slash.
- \param[in] str directory or path name
- \return a new string, ending with a '/'
- */
-std::string fld::end_with_slash(const std::string &str) {
- char last = str[str.size()-1];
- if (last !='/' && last != '\\')
- return str + "/";
- else
- return str;
-}
+ // Count the number of UTF-8 characters in the name
+ int homed_len = (int)strlen(homed_filename);
+ int num_chars = fl_utf_nb_char((const unsigned char*)homed_filename, homed_len);
-/**
- Replace Windows '\\' directory separator with UNix '/' separators.
- \param[in] fn a file path in Unix or Windows format
- \return a copy of the file path in Unix format.
- */
-std::string fld::fix_separators(const std::string &fn) {
- std::string ret = fn;
- for (size_t i=0; i<ret.size(); ++i) {
- if (ret[i] == '\\') {
- ret[i] = '/';
+ if (num_chars + ell_bytes - 1 > max_chars) {
+ // Create a new string by replacing characters in the middle
+ int remove_chars = num_chars - max_chars + ell_bytes;
+ int left_chars = (max_chars - ell_bytes) / 2;
+
+ // Convert character counts into byte counts
+ int left_bytes = fl_utf8strlen(homed_filename, left_chars);
+ int right_start_byte = fl_utf8strlen(homed_filename + left_bytes, remove_chars) + left_bytes;
+
+ // Build result: left part + ellipsis + right part
+ if (left_bytes < result_size - 1) {
+ memcpy(result, homed_filename, left_bytes);
+ int pos = left_bytes;
+ int remaining = result_size - pos - 1;
+ if (remaining > ell_bytes) {
+ memcpy(result + pos, ell, ell_bytes);
+ pos += ell_bytes;
+ remaining = result_size - pos - 1;
+ int right_len = homed_len - right_start_byte;
+ if (right_len > remaining) right_len = remaining;
+ if (right_len > 0) {
+ memcpy(result + pos, homed_filename + right_start_byte, right_len);
+ pos += right_len;
+ }
+ }
+ result[pos] = '\0';
+ } else {
+ strlcpy(result, homed_filename, result_size);
}
+ } else {
+ // Nothing to change
+ strlcpy(result, homed_filename, result_size);
}
- return ret;
-}
-
-// ---- FLUID-local wrapper functions for filename operations ----
-/**
- Get current working directory as std::string.
- \return current working directory path
- */
-std::string fl_getcwd_str() {
- char buf[FL_PATH_MAX];
- fl_getcwd(buf, FL_PATH_MAX);
- return std::string(buf);
+ return result;
}
/**
Get path component (directory) from a filename.
+ \param[out] result buffer to store result (ends with separator if path exists)
+ \param[in] result_size size of result buffer
\param[in] filename the full path
- \return directory portion ending with separator
- */
-std::string fl_filename_path_str(const char *filename) {
- if (!filename || !*filename) return std::string();
- const char *name = fl_filename_name(filename);
- if (name == filename) return std::string();
- return std::string(filename, name - filename);
-}
-
-std::string fl_filename_path_str(const std::string &filename) {
- return fl_filename_path_str(filename.c_str());
-}
-
-/**
- Make a filename absolute.
- \param[in] from relative or absolute filename
- \return absolute filename
+ \return pointer to result buffer
*/
-std::string fl_filename_absolute_str(const char *from) {
- char buf[FL_PATH_MAX];
- fl_filename_absolute(buf, FL_PATH_MAX, from);
- return std::string(buf);
-}
-
-std::string fl_filename_absolute_str(const std::string &from) {
- return fl_filename_absolute_str(from.c_str());
-}
-
-/**
- Make a filename absolute relative to a given directory.
- \param[in] from relative filename
- \param[in] cwd current working directory to use as base
- \return absolute filename
- */
-std::string fl_filename_absolute_str(const char *from, const char *cwd) {
- char buf[FL_PATH_MAX];
- fl_filename_absolute(buf, FL_PATH_MAX, from, cwd);
- return std::string(buf);
-}
+char *fl_filename_path(char *result, int result_size, const char *filename) {
+ result[0] = '\0';
+ if (!filename || !*filename) return result;
-std::string fl_filename_absolute_str(const std::string &from, const std::string &cwd) {
- return fl_filename_absolute_str(from.c_str(), cwd.c_str());
-}
+ const char *name = fl_filename_name(filename);
+ if (name == filename) return result; // no path component
-/**
- Make a filename relative to current directory.
- \param[in] from absolute filename
- \return relative filename
- */
-std::string fl_filename_relative_str(const char *from) {
- char buf[FL_PATH_MAX];
- fl_filename_relative(buf, FL_PATH_MAX, from);
- return std::string(buf);
-}
+ int path_len = (int)(name - filename);
+ if (path_len >= result_size) path_len = result_size - 1;
+ memcpy(result, filename, path_len);
+ result[path_len] = '\0';
-std::string fl_filename_relative_str(const std::string &from) {
- return fl_filename_relative_str(from.c_str());
+ return result;
}
/**
- Get filename portion from a path.
- \param[in] filename the full path
- \return filename without directory
+ Make sure that a path name ends with a forward slash.
+ \param[out] result buffer to store result
+ \param[in] result_size size of result buffer
+ \param[in] path directory or path name
+ \return pointer to result buffer
*/
-std::string fl_filename_name_str(const char *filename) {
- if (!filename) return std::string();
- return std::string(fl_filename_name(filename));
-}
-
-std::string fl_filename_name_str(const std::string &filename) {
- return fl_filename_name_str(filename.c_str());
-}
+char *fld_end_with_slash(char *result, int result_size, const char *path) {
+ if (!path || !*path) {
+ result[0] = '\0';
+ return result;
+ }
-/**
- Change the extension of a filename.
- \param[in] filename original filename
- \param[in] ext new extension (including dot)
- \return filename with new extension
- */
-std::string fl_filename_setext_str(const char *filename, const char *ext) {
- char buf[FL_PATH_MAX];
- if (!filename) return std::string();
- strlcpy(buf, filename, FL_PATH_MAX);
- fl_filename_setext(buf, FL_PATH_MAX, ext);
- return std::string(buf);
-}
+ int len = (int)strlen(path);
+ char last = path[len - 1];
-std::string fl_filename_setext_str(const std::string &filename, const std::string &ext) {
- return fl_filename_setext_str(filename.c_str(), ext.c_str());
-}
+ if (last == '/' || last == '\\') {
+ strlcpy(result, path, result_size);
+ } else {
+ snprintf(result, result_size, "%s/", path);
+ }
-/**
- Expand a filename with shell variables like ~ for home directory.
- \param[in] from filename with possible shell expansions
- \return expanded filename
- */
-std::string fl_filename_expand_str(const std::string &from) {
- char buf[FL_PATH_MAX];
- fl_filename_expand(buf, FL_PATH_MAX, from.c_str());
- return std::string(buf);
+ return result;
}
/**
- Get the extension of a filename.
- \param[in] filename the filename
- \return extension including the dot, or empty string if no extension
+ Replace Windows '\\' directory separator with Unix '/' separators in-place.
+ \param[in,out] path a file path to modify
+ \return pointer to path
*/
-std::string fl_filename_ext_str(const char *filename) {
- if (!filename) return std::string();
- const char *ext = fl_filename_ext(filename);
- if (!ext) return std::string();
- return std::string(ext);
-}
-
-std::string fl_filename_ext_str(const std::string &filename) {
- return fl_filename_ext_str(filename.c_str());
+char *fld_fix_separators(char *path) {
+ if (!path) return path;
+ char *p;
+ for (p = path; *p; p++) {
+ if (*p == '\\') {
+ *p = '/';
+ }
+ }
+ return path;
}
diff --git a/fluid/tools/filename.h b/fluid/tools/filename.h
index 85e4a2844..376ab7641 100644
--- a/fluid/tools/filename.h
+++ b/fluid/tools/filename.h
@@ -23,35 +23,42 @@
#include <FL/filename.H>
#include <FL/fl_utf8.h>
-#include <string>
-
-std::string fl_filename_shortened(const std::string &filename, int maxchars);
-
-// Wrapper functions for filename operations returning std::string
-// These are FLUID-local implementations of functions that were removed from core FLTK
-
-std::string fl_getcwd_str();
-std::string fl_filename_path_str(const char *filename);
-std::string fl_filename_path_str(const std::string &filename);
-std::string fl_filename_absolute_str(const char *from);
-std::string fl_filename_absolute_str(const std::string &from);
-std::string fl_filename_absolute_str(const char *from, const char *cwd);
-std::string fl_filename_absolute_str(const std::string &from, const std::string &cwd);
-std::string fl_filename_relative_str(const char *from);
-std::string fl_filename_relative_str(const std::string &from);
-std::string fl_filename_name_str(const char *filename);
-std::string fl_filename_name_str(const std::string &filename);
-std::string fl_filename_setext_str(const char *filename, const char *ext);
-std::string fl_filename_setext_str(const std::string &filename, const std::string &ext);
-std::string fl_filename_expand_str(const std::string &from);
-std::string fl_filename_ext_str(const char *filename);
-std::string fl_filename_ext_str(const std::string &filename);
-
-namespace fld {
-
-extern std::string end_with_slash(const std::string &fn);
-extern std::string fix_separators(const std::string &fn);
-
-} // namespace fld
+
+/**
+ Return a shortened filename for limited display width.
+ Replaces path start with "~" if it matches home directory, and
+ shortens middle with "..." if needed.
+ \param[out] result buffer to store result
+ \param[in] result_size size of result buffer
+ \param[in] filename absolute path and name, UTF-8 aware
+ \param[in] max_chars maximum number of characters in result
+ \return pointer to result buffer
+ */
+char *fl_filename_shortened(char *result, int result_size, const char *filename, int max_chars);
+
+/**
+ Get path component (directory) from a filename.
+ \param[out] result buffer to store result (ends with separator)
+ \param[in] result_size size of result buffer
+ \param[in] filename the full path
+ \return pointer to result buffer
+ */
+char *fl_filename_path(char *result, int result_size, const char *filename);
+
+/**
+ Make sure that a path name ends with a forward slash.
+ \param[out] result buffer to store result
+ \param[in] result_size size of result buffer
+ \param[in] path directory or path name
+ \return pointer to result buffer
+ */
+char *fld_end_with_slash(char *result, int result_size, const char *path);
+
+/**
+ Replace Windows '\\' directory separator with Unix '/' separators in-place.
+ \param[in,out] path a file path to modify
+ \return pointer to path
+ */
+char *fld_fix_separators(char *path);
#endif // FLUID_TOOLS_FILENAME_H