Rewrite filename_absolute.cxx for the driver model.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11554 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
19b98e40de
commit
62952ea295
@ -98,10 +98,14 @@ public:
|
||||
virtual int get_key(int k) {return 0;}
|
||||
// implement scandir-like function
|
||||
virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) {return -1;}
|
||||
// the default implementation of filename_expand may be enough
|
||||
// the default implementation of filename_expand() may be enough
|
||||
virtual int filename_expand(char *to, int tolen, const char *from);
|
||||
// to implement
|
||||
virtual const char *getpwnam(const char *login) {return NULL;}
|
||||
// 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);
|
||||
};
|
||||
|
||||
#endif // FL_SYSTEM_DRIVER_H
|
||||
|
@ -70,6 +70,8 @@ public:
|
||||
virtual int get_key(int k);
|
||||
virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) );
|
||||
virtual int filename_expand(char *to,int tolen, const char *from);
|
||||
virtual int filename_relative(char *to, int tolen, const char *from, const char *base);
|
||||
virtual int filename_absolute(char *to, int tolen, const char *from);
|
||||
};
|
||||
|
||||
#endif // FL_WINAPI_SYSTEM_DRIVER_H
|
||||
|
@ -486,6 +486,134 @@ int Fl_WinAPI_System_Driver::filename_expand(char *to,int tolen, const char *fro
|
||||
return ret;
|
||||
}
|
||||
|
||||
int // O - 0 if no change, 1 if changed
|
||||
Fl_WinAPI_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
|
||||
{
|
||||
char *newslash; // Directory separator
|
||||
const char *slash; // Directory separator
|
||||
char *cwd = 0L, *cwd_buf = 0L;
|
||||
if (base) cwd = cwd_buf = strdup(base);
|
||||
|
||||
// return if "from" is not an absolute path
|
||||
if (from[0] == '\0' ||
|
||||
(!isdirsep(*from) && !isalpha(*from) && from[1] != ':' &&
|
||||
!isdirsep(from[2]))) {
|
||||
strlcpy(to, from, tolen);
|
||||
if (cwd_buf) free(cwd_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return if "cwd" is not an absolute path
|
||||
if (!cwd || cwd[0] == '\0' ||
|
||||
(!isdirsep(*cwd) && !isalpha(*cwd) && cwd[1] != ':' &&
|
||||
!isdirsep(cwd[2]))) {
|
||||
strlcpy(to, from, tolen);
|
||||
if (cwd_buf) free(cwd_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// convert all backslashes into forward slashes
|
||||
for (newslash = strchr(cwd, '\\'); newslash; newslash = strchr(newslash + 1, '\\'))
|
||||
*newslash = '/';
|
||||
|
||||
// test for the exact same string and return "." if so
|
||||
if (!strcasecmp(from, cwd)) {
|
||||
strlcpy(to, ".", tolen);
|
||||
free(cwd_buf);
|
||||
return (1);
|
||||
}
|
||||
|
||||
// test for the same drive. Return the absolute path if not
|
||||
if (tolower(*from & 255) != tolower(*cwd & 255)) {
|
||||
// Not the same drive...
|
||||
strlcpy(to, from, tolen);
|
||||
free(cwd_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// compare the path name without the drive prefix
|
||||
from += 2; cwd += 2;
|
||||
|
||||
// compare both path names until we find a difference
|
||||
for (slash = from, newslash = cwd;
|
||||
*slash != '\0' && *newslash != '\0';
|
||||
slash ++, newslash ++)
|
||||
if (isdirsep(*slash) && isdirsep(*newslash)) continue;
|
||||
else if (tolower(*slash & 255) != tolower(*newslash & 255)) break;
|
||||
|
||||
// skip over trailing slashes
|
||||
if ( *newslash == '\0' && *slash != '\0' && !isdirsep(*slash)
|
||||
&&(newslash==cwd || !isdirsep(newslash[-1])) )
|
||||
newslash--;
|
||||
|
||||
// now go back to the first character of the first differing paths segment
|
||||
while (!isdirsep(*slash) && slash > from) slash --;
|
||||
if (isdirsep(*slash)) slash ++;
|
||||
|
||||
// do the same for the current dir
|
||||
if (isdirsep(*newslash)) newslash --;
|
||||
if (*newslash != '\0')
|
||||
while (!isdirsep(*newslash) && newslash > cwd) newslash --;
|
||||
|
||||
// prepare the destination buffer
|
||||
to[0] = '\0';
|
||||
to[tolen - 1] = '\0';
|
||||
|
||||
// now add a "previous dir" sequence for every following slash in the cwd
|
||||
while (*newslash != '\0') {
|
||||
if (isdirsep(*newslash)) strlcat(to, "../", tolen);
|
||||
newslash ++;
|
||||
}
|
||||
|
||||
// finally add the differing path from "from"
|
||||
strlcat(to, slash, tolen);
|
||||
|
||||
free(cwd_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_WinAPI_System_Driver::filename_absolute(char *to, int tolen, const char *from) {
|
||||
if (isdirsep(*from) || *from == '|' || from[1]==':') {
|
||||
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;
|
||||
}
|
||||
for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha
|
||||
if (isdirsep(*(a-1))) a--;
|
||||
/* remove intermediate . and .. names: */
|
||||
while (*start == '.') {
|
||||
if (start[1]=='.' && isdirsep(start[2])) {
|
||||
char *b;
|
||||
for (b = a-1; b >= temp && !isdirsep(*b); b--) {/*empty*/}
|
||||
if (b < temp) break;
|
||||
a = b;
|
||||
start += 3;
|
||||
} else if (isdirsep(start[1])) {
|
||||
start += 2;
|
||||
} else if (!start[1]) {
|
||||
start ++; // Skip lone "."
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
*a++ = '/';
|
||||
strlcpy(a,start,tolen - (a - temp));
|
||||
strlcpy(to, temp, tolen);
|
||||
delete[] temp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
@ -23,21 +23,12 @@
|
||||
*/
|
||||
|
||||
#include <FL/filename.H>
|
||||
#include <FL/fl_utf8.h>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_System_Driver.H>
|
||||
#include <stdlib.h>
|
||||
#include "flstring.h"
|
||||
#include <ctype.h>
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# include <direct.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
|
||||
inline int isdirsep(char c) {return c=='/' || c=='\\';}
|
||||
#else
|
||||
#define isdirsep(c) ((c)=='/')
|
||||
#endif
|
||||
inline int isdirsep(char c) {return c == '/';}
|
||||
|
||||
/** Makes a filename absolute from a relative filename.
|
||||
\code
|
||||
@ -54,30 +45,25 @@ inline int isdirsep(char c) {return c=='/' || c=='\\';}
|
||||
\return 0 if no change, non zero otherwise
|
||||
*/
|
||||
int fl_filename_absolute(char *to, int tolen, const char *from) {
|
||||
if (isdirsep(*from) || *from == '|'
|
||||
#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
|
||||
|| from[1]==':'
|
||||
#endif
|
||||
) {
|
||||
return Fl::system_driver()->filename_absolute(to, tolen, from);
|
||||
}
|
||||
|
||||
|
||||
int Fl_System_Driver::filename_absolute(char *to, int tolen, const char *from) {
|
||||
if (isdirsep(*from) || *from == '|') {
|
||||
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;
|
||||
}
|
||||
#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
|
||||
for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha
|
||||
#else
|
||||
a = temp+strlen(temp);
|
||||
#endif
|
||||
if (isdirsep(*(a-1))) a--;
|
||||
/* remove intermediate . and .. names: */
|
||||
while (*start == '.') {
|
||||
@ -95,14 +81,10 @@ int fl_filename_absolute(char *to, int tolen, const char *from) {
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
*a++ = '/';
|
||||
strlcpy(a,start,tolen - (a - temp));
|
||||
|
||||
strlcpy(to, temp, tolen);
|
||||
|
||||
delete[] temp;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -151,113 +133,80 @@ 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
|
||||
|
||||
return Fl::system_driver()->filename_relative(to, tolen, from, base);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
char *newslash; // Directory separator
|
||||
const char *slash; // Directory separator
|
||||
char *cwd = 0L, *cwd_buf = 0L;
|
||||
if (base) cwd = cwd_buf = strdup(base);
|
||||
|
||||
// return if "from" is not an absolute path
|
||||
#if defined(WIN32) || defined(__EMX__)
|
||||
if (from[0] == '\0' ||
|
||||
(!isdirsep(*from) && !isalpha(*from) && from[1] != ':' &&
|
||||
!isdirsep(from[2]))) {
|
||||
#else
|
||||
if (from[0] == '\0' || !isdirsep(*from)) {
|
||||
#endif // WIN32 || __EMX__
|
||||
strlcpy(to, from, tolen);
|
||||
if (cwd_buf) free(cwd_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// return if "cwd" is not an absolute path
|
||||
#if defined(WIN32) || defined(__EMX__)
|
||||
if (!cwd || cwd[0] == '\0' ||
|
||||
(!isdirsep(*cwd) && !isalpha(*cwd) && cwd[1] != ':' &&
|
||||
!isdirsep(cwd[2]))) {
|
||||
#else
|
||||
if (!cwd || cwd[0] == '\0' || !isdirsep(*cwd)) {
|
||||
#endif // WIN32 || __EMX__
|
||||
strlcpy(to, from, tolen);
|
||||
if (cwd_buf) free(cwd_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(WIN32) || defined(__EMX__)
|
||||
// convert all backslashes into forward slashes
|
||||
for (newslash = strchr(cwd, '\\'); newslash; newslash = strchr(newslash + 1, '\\'))
|
||||
*newslash = '/';
|
||||
|
||||
// test for the exact same string and return "." if so
|
||||
if (!strcasecmp(from, cwd)) {
|
||||
strlcpy(to, ".", tolen);
|
||||
free(cwd_buf);
|
||||
return (1);
|
||||
}
|
||||
|
||||
// test for the same drive. Return the absolute path if not
|
||||
if (tolower(*from & 255) != tolower(*cwd & 255)) {
|
||||
// Not the same drive...
|
||||
strlcpy(to, from, tolen);
|
||||
free(cwd_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// compare the path name without the drive prefix
|
||||
from += 2; cwd += 2;
|
||||
#else
|
||||
|
||||
// test for the exact same string and return "." if so
|
||||
if (!strcmp(from, cwd)) {
|
||||
strlcpy(to, ".", tolen);
|
||||
free(cwd_buf);
|
||||
return (1);
|
||||
}
|
||||
#endif // WIN32 || __EMX__
|
||||
|
||||
|
||||
// compare both path names until we find a difference
|
||||
for (slash = from, newslash = cwd;
|
||||
*slash != '\0' && *newslash != '\0';
|
||||
*slash != '\0' && *newslash != '\0';
|
||||
slash ++, newslash ++)
|
||||
if (isdirsep(*slash) && isdirsep(*newslash)) continue;
|
||||
#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__) // PORTME: Fl_System_Driver - filename stuff
|
||||
else if (tolower(*slash & 255) != tolower(*newslash & 255)) break;
|
||||
#else
|
||||
else if (*slash != *newslash) break;
|
||||
#endif // WIN32 || __EMX__ || __APPLE__ // PORTME: Fl_System_Driver - filename stuff
|
||||
|
||||
|
||||
// skip over trailing slashes
|
||||
if ( *newslash == '\0' && *slash != '\0' && !isdirsep(*slash)
|
||||
&&(newslash==cwd || !isdirsep(newslash[-1])) )
|
||||
&&(newslash==cwd || !isdirsep(newslash[-1])) )
|
||||
newslash--;
|
||||
|
||||
|
||||
// now go back to the first character of the first differing paths segment
|
||||
while (!isdirsep(*slash) && slash > from) slash --;
|
||||
if (isdirsep(*slash)) slash ++;
|
||||
|
||||
|
||||
// do the same for the current dir
|
||||
if (isdirsep(*newslash)) newslash --;
|
||||
if (*newslash != '\0')
|
||||
while (!isdirsep(*newslash) && newslash > cwd) newslash --;
|
||||
|
||||
|
||||
// prepare the destination buffer
|
||||
to[0] = '\0';
|
||||
to[tolen - 1] = '\0';
|
||||
|
||||
|
||||
// now add a "previous dir" sequence for every following slash in the cwd
|
||||
while (*newslash != '\0') {
|
||||
if (isdirsep(*newslash)) strlcat(to, "../", tolen);
|
||||
|
||||
|
||||
newslash ++;
|
||||
}
|
||||
|
||||
|
||||
// finally add the differing path from "from"
|
||||
strlcat(to, slash, tolen);
|
||||
|
||||
|
||||
free(cwd_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user