summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Menu_.cxx34
-rw-r--r--src/Fl_String.cxx15
-rw-r--r--src/Fl_System_Driver.H2
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.H2
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx12
-rw-r--r--src/filename_absolute.cxx86
6 files changed, 114 insertions, 37 deletions
diff --git a/src/Fl_Menu_.cxx b/src/Fl_Menu_.cxx
index 28a476e02..1769af9a1 100644
--- a/src/Fl_Menu_.cxx
+++ b/src/Fl_Menu_.cxx
@@ -267,6 +267,40 @@ const Fl_Menu_Item * Fl_Menu_::find_item(Fl_Callback *cb) {
}
/**
+ Find the menu item for the given user data \p v.
+
+ \param[in] v find the first item with this user data
+ \returns The item found, or NULL if not found
+ \see find_item(const char*)
+ */
+const Fl_Menu_Item* Fl_Menu_::find_item_with_user_data(void *v) {
+ for ( int t=0; t < size(); t++ ) {
+ const Fl_Menu_Item *m = menu_ + t;
+ if (m->user_data_==v) {
+ return m;
+ }
+ }
+ return (const Fl_Menu_Item *)NULL;
+}
+
+/**
+ Find the menu item for the given user argument \p v.
+
+ \param[in] v find the first item with this user argument
+ \returns The item found, or NULL if not found
+ \see find_item(const char*)
+ */
+const Fl_Menu_Item* Fl_Menu_::find_item_with_argument(long v) {
+ for ( int t=0; t < size(); t++ ) {
+ const Fl_Menu_Item *m = menu_ + t;
+ if (m->argument()==v) {
+ return m;
+ }
+ }
+ return (const Fl_Menu_Item *)NULL;
+}
+
+/**
The value is the index into menu() of the last item chosen by
the user. It is zero initially. You can set it as an integer, or set
it with a pointer to a menu item. The set routines return non-zero if
diff --git a/src/Fl_String.cxx b/src/Fl_String.cxx
index 693a88286..e285519ff 100644
--- a/src/Fl_String.cxx
+++ b/src/Fl_String.cxx
@@ -466,6 +466,21 @@ Fl_String &Fl_String::operator+=(char c) {
}
/**
+ Find a string inside this string.
+ \param[in] needle find this string
+ \param[in] start_pos start looking at this position
+ \return the offset of the text inside this string, if it was found
+ \return Fl_String::npos if the needle was not found
+ */
+int Fl_String::find(const Fl_String &needle, int start_pos) const {
+ if ((start_pos < 0) || (start_pos >= size_)) return npos;
+ const char *haystack = data() + start_pos;
+ const char *found = strstr(haystack, needle.c_str());
+ if (!found) return npos;
+ return (int)(found - data());
+}
+
+/**
Replace part of the string with a C-style string or data.
\param[in] at erase and insert at this index
\param[in] n_del number of bytes to erase
diff --git a/src/Fl_System_Driver.H b/src/Fl_System_Driver.H
index 89110b201..e7230f74e 100644
--- a/src/Fl_System_Driver.H
+++ b/src/Fl_System_Driver.H
@@ -134,7 +134,7 @@ public:
// the default implementation of filename_relative() is in src/filename_absolute.cxx and may be enough
virtual int filename_relative(char *to, int tolen, const char *from, const char *base);
// the default implementation of filename_absolute() is in src/filename_absolute.cxx and may be enough
- virtual int filename_absolute(char *to, int tolen, const char *from);
+ virtual int filename_absolute(char *to, int tolen, const char *from, const char *base);
// the default implementation of filename_isdir() is in src/filename_isdir.cxx and may be enough
virtual int filename_isdir(const char* n);
// the default implementation of filename_isdir_quick() is in src/filename_isdir.cxx and may be enough
diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H
index 10047b632..aae1017e2 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H
+++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H
@@ -74,7 +74,7 @@ public:
char *errmsg=NULL, int errmsg_sz=0) FL_OVERRIDE;
int filename_expand(char *to,int tolen, const char *from) FL_OVERRIDE;
int filename_relative(char *to, int tolen, const char *from, const char *base) FL_OVERRIDE;
- int filename_absolute(char *to, int tolen, const char *from) FL_OVERRIDE;
+ int filename_absolute(char *to, int tolen, const char *from, const char *base) FL_OVERRIDE;
int filename_isdir(const char *n) FL_OVERRIDE;
int filename_isdir_quick(const char *n) FL_OVERRIDE;
const char *filename_ext(const char *buf) FL_OVERRIDE;
diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
index cda8c1b36..c2d41f98e 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
@@ -636,21 +636,17 @@ Fl_WinAPI_System_Driver::filename_relative(char *to, // O - Relative filename
return 1;
}
-int Fl_WinAPI_System_Driver::filename_absolute(char *to, int tolen, const char *from) {
- if (isdirsep(*from) || *from == '|' || from[1]==':') {
+int Fl_WinAPI_System_Driver::filename_absolute(char *to, int tolen, const char *from, const char *base) {
+ if (isdirsep(*from) || *from == '|' || from[1]==':' || !base) {
strlcpy(to, from, tolen);
return 0;
}
char *a;
char *temp = new char[tolen];
const char *start = from;
- a = getcwd(temp, tolen);
- if (!a) {
- strlcpy(to, from, tolen);
- delete[] temp;
- return 0;
- }
+ strlcpy(temp, base, tolen);
for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha
+ /* remove trailing '/' in current working directory */
if (isdirsep(*(a-1))) a--;
/* remove intermediate . and .. names: */
while (*start == '.') {
diff --git a/src/filename_absolute.cxx b/src/filename_absolute.cxx
index 8d016c991..70b86fcf7 100644
--- a/src/filename_absolute.cxx
+++ b/src/filename_absolute.cxx
@@ -1,7 +1,7 @@
//
// Filename expansion routines for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2017 by Bill Spitzak and others.
+// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -30,7 +30,7 @@
static inline int isdirsep(char c) {return c == '/';}
-/** Makes a filename absolute from a relative filename.
+/** Makes a filename absolute from a relative filename to the current working directory.
\code
#include <FL/filename.H>
[..]
@@ -45,30 +45,46 @@ static inline int isdirsep(char c) {return c == '/';}
\return 0 if no change, non zero otherwise
*/
int fl_filename_absolute(char *to, int tolen, const char *from) {
- return Fl::system_driver()->filename_absolute(to, tolen, from);
+ char cwd_buf[FL_PATH_MAX]; // Current directory
+ // get the current directory and return if we can't
+ if (!fl_getcwd(cwd_buf, sizeof(cwd_buf))) {
+ strlcpy(to, from, tolen);
+ return 0;
+ }
+ return Fl::system_driver()->filename_absolute(to, tolen, from, cwd_buf);
}
+/** Concatenate the absolute path `base` with `from` to form the new absolute path in `to`.
+ \code
+ #include <FL/filename.H>
+ char out[FL_PATH_MAX];
+ fl_filename_absolute(out, sizeof(out), "../foo.txt", "/var/tmp"); // out="/var/foo.txt"
+ fl_filename_absolute(out, sizeof(out), "../local/bin", "/usr/bin"); // out="/usr/local/bin"
+ \endcode
+ \param[out] to resulting absolute filename
+ \param[in] tolen size of the absolute filename buffer
+ \param[in] from relative filename
+ \param[in] base `from` is relative to this absolute file path
+ \return 0 if no change, non zero otherwise
+ */
+int fl_filename_absolute(char *to, int tolen, const char *from, const char *base) {
+ return Fl::system_driver()->filename_absolute(to, tolen, from, base);
+}
/**
\cond DriverDev
\addtogroup DriverDeveloper
\{
*/
-
-int Fl_System_Driver::filename_absolute(char *to, int tolen, const char *from) {
- if (isdirsep(*from) || *from == '|') {
+int Fl_System_Driver::filename_absolute(char *to, int tolen, const char *from, const char *base) {
+ if (isdirsep(*from) || *from == '|' || !base) {
strlcpy(to, from, tolen);
return 0;
}
char *a;
char *temp = new char[tolen];
const char *start = from;
- a = fl_getcwd(temp, tolen);
- if (!a) {
- strlcpy(to, from, tolen);
- delete[] temp;
- return 0;
- }
+ strlcpy(temp, base, tolen);
a = temp+strlen(temp);
/* remove trailing '/' in current working directory */
if (isdirsep(*(a-1))) a--;
@@ -125,10 +141,7 @@ int Fl_System_Driver::filename_absolute(char *to, int tolen, const char *from) {
\param[in] from absolute filename
\return 0 if no change, non zero otherwise
*/
-int // O - 0 if no change, 1 if changed
-fl_filename_relative(char *to, // O - Relative filename
- int tolen, // I - Size of "to" buffer
- const char *from) // I - Absolute filename
+int fl_filename_relative(char *to, int tolen, const char *from)
{
char cwd_buf[FL_PATH_MAX]; // Current directory
// get the current directory and return if we can't
@@ -144,14 +157,10 @@ fl_filename_relative(char *to, // O - Relative filename
\param[out] to resulting relative filename
\param[in] tolen size of the relative filename buffer
\param[in] from absolute filename
- \param[in] base relative to this absolute path
+ \param[in] base generate filename relative to this absolute filename
\return 0 if no change, non zero otherwise
*/
-int // O - 0 if no change, 1 if changed
-fl_filename_relative(char *to, // O - Relative filename
- int tolen, // I - Size of "to" buffer
- const char *from, // I - Absolute filename
- const char *base) { // I - Find path relative to this path
+int fl_filename_relative(char *to, int tolen, const char *from, const char *base) {
return Fl::system_driver()->filename_relative(to, tolen, from, base);
}
@@ -162,11 +171,7 @@ fl_filename_relative(char *to, // O - Relative filename
\{
*/
-int // O - 0 if no change, 1 if changed
-Fl_System_Driver::filename_relative(char *to, // O - Relative filename
- int tolen, // I - Size of "to" buffer
- const char *from, // I - Absolute filename
- const char *base) // I - Find path relative to this path
+int Fl_System_Driver::filename_relative(char *to, int tolen, const char *from, const char *base)
{
char *newslash; // Directory separator
const char *slash; // Directory separator
@@ -315,6 +320,20 @@ Fl_String fl_filename_absolute(const Fl_String &from) {
}
/**
+ Append the relative filename `from` to the absolute filename `base` to form
+ the new absolute path.
+ \param[in] from relative filename
+ \param[in] base `from` is relative to this absolute file path
+ \return the new, absolute filename
+ \see fl_filename_absolute(char *to, int tolen, const char *from, const char *base)
+ */
+Fl_String fl_filename_absolute(const Fl_String &from, const Fl_String &base) {
+ char buffer[FL_PATH_MAX];
+ fl_filename_absolute(buffer, FL_PATH_MAX, from.c_str(), base.c_str());
+ return Fl_String(buffer);
+}
+
+/**
Makes a filename relative to the current working directory.
\param[in] from file path and name
\return the new, relative filename
@@ -326,6 +345,19 @@ Fl_String fl_filename_relative(const Fl_String &from) {
return Fl_String(buffer);
}
+/**
+ Makes a filename relative to any directory.
+ \param[in] from file path and name
+ \param[in] base relative to this absolute path
+ \return the new, relative filename
+ \see fl_filename_relative(char *to, int tolen, const char *from, const char *base)
+ */
+Fl_String fl_filename_relative(const Fl_String &from, const Fl_String &base) {
+ char buffer[FL_PATH_MAX];
+ fl_filename_relative(buffer, FL_PATH_MAX, from.c_str(), base.c_str());
+ return Fl_String(buffer);
+}
+
/** Cross-platform function to get the current working directory
as a UTF-8 encoded value in an Fl_String.
\return the CWD encoded as UTF-8