// // FLUID path helper functions for the Fast Light Tool Kit (FLTK). // // Copyright 1998-2025 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 // file is missing or damaged, see the license at: // // https://www.fltk.org/COPYING.php // #ifndef FLD_PATH_H #define FLD_PATH_H #include #include #include #include // Path helper functions using static buffers. // These are NOT thread-safe, but FLUID is single-threaded. // Each function uses its own buffer to allow nesting calls. // Get current working directory - returns pointer to static buffer inline const char *fld_getcwd(void) { static char buf[FL_PATH_MAX]; fl_getcwd(buf, FL_PATH_MAX); return buf; } // Get absolute path - returns pointer to static buffer inline const char *fld_filename_absolute(const char *from) { static char buf[FL_PATH_MAX]; fl_filename_absolute(buf, FL_PATH_MAX, from); return buf; } // Get absolute path with base directory - returns pointer to static buffer inline const char *fld_filename_absolute2(const char *from, const char *cwd) { static char buf[FL_PATH_MAX]; fl_filename_absolute(buf, FL_PATH_MAX, from, cwd); return buf; } // Get relative path - returns pointer to static buffer inline const char *fld_filename_relative(const char *from) { static char buf[FL_PATH_MAX]; fl_filename_relative(buf, FL_PATH_MAX, from); return buf; } // Get relative path with base directory - returns pointer to static buffer inline const char *fld_filename_relative2(const char *from, const char *cwd) { static char buf[FL_PATH_MAX]; fl_filename_relative(buf, FL_PATH_MAX, from, cwd); return buf; } // Get path component (directory) - returns pointer to static buffer // Note: fl_filename_name returns pointer to filename within the string, // so we need to copy the path portion inline const char *fld_filename_path(const char *filename) { static char buf[FL_PATH_MAX]; if (!filename || !*filename) { buf[0] = '\0'; return buf; } const char *name = fl_filename_name(filename); if (name == filename) { // no path component buf[0] = '\0'; return buf; } size_t len = name - filename; if (len >= FL_PATH_MAX) len = FL_PATH_MAX - 1; memcpy(buf, filename, len); buf[len] = '\0'; return buf; } // Set extension - returns pointer to static buffer inline const char *fld_filename_setext(const char *filename, const char *ext) { static char buf[FL_PATH_MAX]; if (!filename) { buf[0] = '\0'; return buf; } strlcpy(buf, filename, FL_PATH_MAX); fl_filename_setext(buf, FL_PATH_MAX, ext); return buf; } // Get filename without extension - returns pointer to static buffer inline const char *fld_filename_noext(const char *filename) { return fld_filename_setext(filename, ""); } // Ensure path ends with slash - returns pointer to static buffer inline const char *fld_end_with_slash(const char *path) { static char buf[FL_PATH_MAX]; if (!path || !*path) { buf[0] = '\0'; return buf; } size_t len = strlen(path); if (len >= FL_PATH_MAX - 1) len = FL_PATH_MAX - 2; memcpy(buf, path, len); if (buf[len - 1] != '/' && buf[len - 1] != '\\') { buf[len] = '/'; buf[len + 1] = '\0'; } else { buf[len] = '\0'; } return buf; } // Concatenate path and filename - returns pointer to static buffer inline const char *fld_path_concat(const char *path, const char *name) { static char buf[FL_PATH_MAX]; if (!path || !*path) { if (!name) { buf[0] = '\0'; } else { strlcpy(buf, name, FL_PATH_MAX); } return buf; } strlcpy(buf, path, FL_PATH_MAX); size_t len = strlen(buf); if (len > 0 && buf[len - 1] != '/' && buf[len - 1] != '\\') { if (len < FL_PATH_MAX - 1) { buf[len] = '/'; buf[len + 1] = '\0'; len++; } } if (name && len < FL_PATH_MAX - 1) { strlcat(buf, name, FL_PATH_MAX); } return buf; } #endif // FLD_PATH_H