On Mon, 26 Jul 1999 19:00:33 +0200 (MET DST), Jean-Marc Lasgouttes
wrote:
>Could you use that in your patches, you can do either
> name = CleanupPath(name);
>or
> LString temp = CleanupPath(name);
>
You've asked for it...
>I did not try it, but it should obviously work, and the overhead for
>unices, while non-null, is not important.
Compiles without warnings (-Wall) on my box. It works; the only
exception I could find are files with sole trailing dots in their name.
>Hopefully, this should allow you to remove *all* the EMX ifdefs which
>are related to this. ...
Tu es optimiste, .... :)
No, this would mean writing an OS-specific support library, which fakes
e.g. a POSIX file system. This should not be too difficult, but
involves many hours of concentrated work...
Encore une fois, toute l'histoire:
------------snip-------------------
diff -p -N -r -U 4 -X excl.tmp src/original/filetools.C
src/modified/filetools.C
--- src/original/filetools.C Wed May 12 06:51:18 1999
+++ src/modified/filetools.C Tue Jul 27 22:06:10 1999
@@ -72,34 +72,19 @@ bool IsSGMLFilename(LString const & file
return filename.contains(".sgml");
}
-// Substitutes spaces with underscores in filename (and path)
+// Substitute chars that LaTeX or shell can't handle with safe ones
LString SpaceLess(LString const & file)
{
- LString name = OnlyFilename(file);
- LString path = OnlyPath(file);
- // Substitute chars that LaTeX can't handle with safe ones
- name.subst('~','-');
- name.subst('$','S');
- name.subst('%','_');
- name.subst('\'','_');
-
- // Substitute some more chars that LaTeX or /bin/sh can't
handle -ck-
- name.subst('`', '_');
- name.subst('"', '_');
- name.subst('&', 'G');
- name.subst('|', 'I');
- name.subst(';', ':');
- name.subst('(', 'c');
- name.subst(')', 'C');
- name.subst('<', 'k');
- name.subst('>', 'K');
-
- LString temp = AddName(path, name);
+ LString temp = OnlyFilename(file);
+ temp.toAsciiAlnum(); /* AHanses: if >127, subtract
+ ** 128, 256, etc., put REPLACER */
+
+ temp = AddName(OnlyPath(file), temp);
+
// Replace spaces with underscores, also in directory
temp.subst(' ','_');
-
return temp;
}
@@ -202,15 +187,16 @@ int IsDirWriteable (LString const & path
// Can't cope with pathnames with a ';' in them. Returns full path to
file.
// If path entry begins with $$LyX/, use system_lyxdir
// If path entry begins with $$User/, use user_lyxdir
// Example: "$$User/doc;$$LyX/doc"
-LString FileOpenSearch (LString const & path, LString const & name,
+LString FileOpenSearch (LString const & path, LString const & oldname,
LString const & ext)
{
LString real_file, path_element;
- LString tmppath = path;
+ LString tmppath = CleanupPath(path);
+ LString const name = CleanupPath(oldname);
bool notfound = true;
-
+
tmppath.split(path_element, ';');
while (notfound && !path_element.empty()) {
@@ -241,22 +227,20 @@ LString FileOpenSearch (LString const &
// extension ext.
LString FileSearch(LString const & path, LString const & name,
LString const & ext)
{
- LString fullname;
- LString tmp;
-
// if `name' is an absolute path, we ignore the setting of
`path'
// Expand Environmentvariables in 'name'
- LString tmpname = ReplaceEnvironmentPath(name);
- fullname = MakeAbsPath(tmpname,path);
+ LString tmpname = ReplaceEnvironmentPath(CleanupPath(name));
+ LString fullname = MakeAbsPath(tmpname, CleanupPath(path));
// search first without extension, then with it.
if (IsFileReadable(fullname))
return fullname;
else if(ext.empty())
return LString();
- else { // Is it not more reasonable to use ChangeExtension()?
(SMiyata)
+ else {
+#warning Is it not more reasonable to use ChangeExtension()? (SMiyata)
fullname += '.';
fullname += ext;
if (IsFileReadable(fullname))
return fullname;
@@ -269,11 +253,12 @@ LString FileSearch(LString const & path,
// Search the file name.ext in the subdirectory dir of
// 1) user_lyxdir
// 2) build_lyxdir (if not empty)
// 3) system_lyxdir
-LString LibFileSearch(LString const & dir, LString const & name,
+LString LibFileSearch(LString const & dir, LString const & oldname,
LString const & ext)
{
+ LString const name = CleanupPath(oldname);
LString fullname = FileSearch(AddPath(user_lyxdir,dir), name,
ext);
if (!fullname.empty())
return fullname;
@@ -286,13 +271,13 @@ LString LibFileSearch(LString const & di
return FileSearch(AddPath(system_lyxdir,dir), name, ext);
}
-LString i18nLibFileSearch(LString const & dir, LString const & name,
+LString i18nLibFileSearch(LString const & dir, LString const &
oldname,
LString const & ext)
{
LString lang = LString(getenv("LANG")).token('_',0);
-
+ LString const name = CleanupPath(oldname);
if (lang.empty())
return LibFileSearch(dir, name, ext);
else {
LString tmp = LibFileSearch(dir, lang + '_' + name,
@@ -305,12 +290,14 @@ LString i18nLibFileSearch(LString const
}
static
-int DeleteAllFilesInDir (LString const & path)
+int DeleteAllFilesInDir (LString const & oldpath)
{
- DIR * dir;
+ DIR *dir;
struct dirent *de;
+ LString const path = CleanupPath(oldpath);
+
dir = opendir(path.c_str());
if (!dir) {
WriteFSAlert (_("Error! Cannot open directory:"),
path);
return -1;
@@ -414,9 +401,9 @@ int DestroyLyXTmpDir (LString const & tm
// Creates directory. Returns true if succesfull
bool createDirectory(LString const & path, int permission)
{
- LString temp = path;
+ LString temp = CleanupPath(path);
// Cut off trailing /s
temp.strip('/');
@@ -459,29 +446,34 @@ LString GetCWD ()
// Strip filename from path name
LString OnlyPath(LString const &Filename)
{
// If empty filename, return empty
- if (Filename.empty()) return Filename;
+ if (Filename.empty())
+ return Filename;
+
+ LString temp = CleanupPath(Filename);
// Find last / or start of filename
- int j = Filename.length() - 1;
- for (; j > 0 && Filename[j] != '/'; j--);
+ int j = temp.length() - 1;
+ for (; j > 0 && temp[j] != '/'; j--);
- if (Filename[j] != '/')
+ if (temp[j] != '/')
return "./";
else {
// Strip to pathname
- LString temp = Filename;
return temp.substring(0, j);
}
}
// Convert relative path into absolute path based on a basepath.
// If relpath is absolute, just use that.
// If basepath is empty, use CWD as base.
-LString MakeAbsPath(LString const &RelPath, LString const &BasePath)
+LString MakeAbsPath(LString const &oldRelPath, LString const
&oldBasePath)
{
+ LString const RelPath = CleanupPath(oldRelPath);
+ LString const BasePath = CleanupPath(oldBasePath);
+
// checks for already absolute path
if (AbsolutePath(RelPath))
#ifdef __EMX__
if(RelPath[0]!='/')
@@ -575,17 +567,18 @@ LString OnlyFilename(LString const &File
{
// If empty filename, return empty
if (Filename.empty()) return Filename;
+ LString temp = CleanupPath(Filename);
+
int j;
// Find last / or start of filename
- for (j=Filename.length()-1; Filename[j] != '/' && j>0; j--);
+ for (j=temp.length()-1; temp[j] != '/' && j>0; j--);
// Skip potential /
if (j!=0) j++;
// Strip to basename
- LString temp = Filename;
return temp.substring(j, temp.length()-1);
}
@@ -593,10 +586,15 @@ LString OnlyFilename(LString const &File
bool AbsolutePath(LString const &path)
{
#ifndef __EMX__
return (!path.empty() && path[0]=='/');
-#else
- return (!path.empty() && (path[0]=='/' || (isalpha((unsigned
char) path[0]) && path[1]==':')));
+#else /* AHanses: Handle DOS-style paths ('\') */
+ return (!path.empty() &&
(
+
(path[0]=='/' || path[0]=='\\'
||
+
(isalpha((unsigned char)
path[0])
&&
+
path[1]==':'))
+
)
+ );
#endif
}
@@ -609,8 +607,9 @@ LString ExpandPath(LString const &path)
if (AbsolutePath(RTemp))
return RTemp;
LString Temp;
+
LString copy(RTemp);
// Split by next /
RTemp.split(Temp, '/');
@@ -635,15 +634,17 @@ LString NormalizePath(LString const &pat
LString TempBase;
LString RTemp;
LString Temp;
- if (AbsolutePath(path))
- RTemp = path;
- else
+ if (AbsolutePath(path)) {
+ RTemp = CleanupPath(path);
+ }
+ else {
// Make implicit current directory explicit
- RTemp = "./" +path;
-
+ RTemp = "./" + CleanupPath(path);
+ }
while (!RTemp.empty()) {
+
// Split by next /
RTemp.split(Temp, '/');
if (Temp==".") {
@@ -683,22 +684,25 @@ LString ReplaceEnvironmentPath(LString c
// Split String with PathChar
// Search Environmentvariable
// if found: Replace Strings
//
- const char CompareChar = '$';
- const char FirstChar = '{';
- const char EndChar = '}';
- const char UnderscoreChar = '_';
+ const char CompareChar = COMPARE_CHAR;
+ const char FirstChar = FIRST_CHAR;
+ const char EndChar = END_CHAR;
+ const char UnderscoreChar = UNDERSCORE_CHAR;
const LString EndString(EndChar);
const LString FirstString(FirstChar);
const LString CompareString(CompareChar);
- const LString RegExp("*}*"); // Exist EndChar inside a String?
+ const LString RegExp(REGEX); // Exist EndChar inside a String?
- if (path.empty()) return path; // nothing to do.
+ if (path.empty())
+ return path; // nothing to do.
+ LString temppath = CleanupPath(path);
+
// first: Search for a '$' - Sign.
- LString copy(path);
- LString result1(copy); // for split-calls
+ LString copy(temppath);
+ LString result1(copy); // for split-calls
LString result0 = copy.split(result1, CompareChar);
while (!result0.empty()) {
LString copy1(result0); // contains String after $
@@ -771,46 +775,50 @@ LString MakeRelPath(LString const & absp
{
// This is a hack. It should probaly be done in another way.
Lgb.
if (abspath.empty())
return "<unknown_path>";
+
+/* This should fix searchpath bug. */
+ LString tempabspath=CleanupPath(abspath);
+ LString tempbasepath=CleanupPath(basepath);
- const int abslen = abspath.length();
- const int baselen = basepath.length();
-
- // Find first different character
+ const int abslen = tempabspath.length();
+ const int baselen = tempbasepath.length();
int i = 0;
- while (i < abslen && i < baselen && abspath[i] == basepath[i])
++i;
+
+ // Find first different character
+ while (i < abslen && i < baselen && tempabspath[i] ==
tempbasepath[i]) ++i;
// Go back to last /
if (i < abslen && i < baselen
- || (i<abslen && abspath[i] != '/' && i==baselen)
- || (i<baselen && basepath[i] != '/' && i==abslen))
+ || (i<abslen && tempabspath[i] != '/' && i==baselen)
+ || (i<baselen && tempbasepath[i] != '/' && i==abslen))
{
if (i) --i; // here was the last match
- while (i && abspath[i] != '/') --i;
+ while (i && tempabspath[i] != '/') --i;
}
if (i == 0) {
// actually no match - cannot make it relative
- return abspath;
+ return tempabspath;
}
// Count how many dirs there are in basepath above match
// and append as many '..''s into relpath
LString buf;
int j = i;
while (j < baselen) {
- if (basepath[j] == '/') {
+ if (tempbasepath[j] == '/') {
if (j+1 == baselen) break;
buf += "../";
}
++j;
}
// Append relative stuff from common directory to abspath
- if (abspath[i] == '/') ++i;
+ if (tempabspath[i] == '/') ++i;
for (; i<abslen; ++i)
- buf += abspath[i];
+ buf += tempabspath[i];
// Remove trailing /
if (buf.suffixIs('/'))
buf.substring(0,buf.length()-2);
// Substitute empty with .
@@ -818,30 +826,38 @@ LString MakeRelPath(LString const & absp
buf = '.';
return buf;
}
-
// Append sub-directory(ies) to a path in an intelligent way
LString AddPath(LString const & path, LString const & path2)
-{
+{
LString buf;
-
- if (!path.empty() && path != "." && path != "./") {
- buf = path;
+ /* AHanses: Handle DOS-style paths ('\') */
+ if ( !path.empty() && path != "." && path != "./" &&
+ path != ".\\" )
+ {
+ /* This should fix searchpath bug. */
+ buf = CleanupPath(path);
+ buf.subst('\\', '/');
+ buf.lowercase();
if (!path.suffixIs('/'))
buf += '/';
}
- if (!path2.empty()){
- int p2start = 0;
- while (path2[p2start] == '/') p2start++;
-
- int p2end = path2.length()-1;
- while (path2[p2end] == '/') p2end--;
-
- LString tmp = path2;
- tmp.substring(p2start,p2end);
- buf += tmp + '/';
+ if (!path2.empty())
+ {
+ /* SMiyata: This should fix searchpath bug. */
+ LString tmppath2 = CleanupPath(path2);
+ tmppath2.subst('\\', '/');
+ tmppath2.lowercase();
+ int p2start = 0;
+ while (tmppath2[p2start] == '/') p2start++;
+
+ int p2end = tmppath2.length()-1;
+ while (tmppath2[p2end] == '/') p2end--;
+
+ tmppath2.substring(p2start,p2end);
+ buf += tmppath2 + '/';
}
return buf;
}
@@ -853,9 +869,10 @@ LString AddPath(LString const & path, LS
*/
LString ChangeExtension(LString const & oldname, LString const &
extension,
bool no_path)
{
- int n = oldname.length()-1;
+ LString old = CleanupPath(oldname);
+ int n = old.length()-1;
int dot;
// Make sure the extension includes the dot, if not empty
LString ext;
@@ -864,52 +881,52 @@ LString ChangeExtension(LString const &
else
ext = extension;
// Go back to the first dot not crossing any /
- for (dot=n; dot>=0 && oldname[dot]!='.' && oldname[dot]!='/';
dot--);
+ for (dot=n; dot>=0 && old[dot]!='.' && old[dot]!='/'; dot--);
- if (dot==-1 || oldname[dot]!='.')
+ if (dot==-1 || old[dot]!='.')
// If no extension was found, we use the end of the
string
dot = n;
else
+#warning: AHanses: Check if this works with all single trailing dots!
// Remove the dot, because the new extension includes
it
dot--;
// "path" points to last / or 0 if path is wanted
int path = 0;
if (no_path) {
- for (path=dot; path && oldname[path]!='/';path--);
- if (oldname[path]=='/')
+ for (path=dot; path && old[path]!='/'; path--);
+ if (old[path]=='/')
path++;
} else
path = 0;
- LString result = oldname;
- result.substring(path,dot);
+ old.substring(path, dot);
if (!ext.empty())
- result += ext;
- return result;
+ old += ext; /* now new! */
+ return old;
}
// Creates a nice compact path for displaying
LString MakeDisplayPath (LString const & path, int threshold)
{
- const int l1 = path.length();
+ LString tmppath = CleanupPath(path);
+ const int l1 = tmppath.length();
// First, we try a relative path compared to home
- LString home = getEnvPath("HOME");
- LString relhome = MakeRelPath(path, home);
-
+ LString home = CleanupPath(getEnvPath("HOME"));
+ LString relhome = MakeRelPath(tmppath, home);
int l2 = relhome.length();
LString prefix;
// If we backup from home or don't have a relative path,
// this try is no good
if (relhome.prefixIs("../") || AbsolutePath(relhome)) {
// relative path was no good, just use the original
path
- relhome = path;
+ relhome = tmppath;
l2 = l1;
} else {
prefix = "~/";
}
diff -p -N -r -U 4 -X excl.tmp src/original/filetools.h
src/modified/filetools.h
--- src/original/filetools.h Wed May 12 06:51:22 1999
+++ src/modified/filetools.h Tue Jul 27 21:32:16 1999
@@ -214,13 +214,13 @@ LString AddName(LString const &Path, LSt
/// Append sub-directory(ies) to path in an intelligent way
LString AddPath(LString const & path, LString const & path2);
-/** Change extension of oldname to extension.
- If no_path is true, the path is stripped from the filename.
- If oldname does not have an extension, it is appended.
- If the extension is empty, any extension is removed from the name.
- */
+/* Change extension of oldname to extension.
+** If no_path is true, the path is stripped from the filename.
+** If oldname does not have an extension, it is appended.
+** If the extension is empty, any extension is removed from the name.
+*/
LString ChangeExtension(LString const & oldname, LString const &
extension,
bool no_path);
/// Create absolute path. If impossible, don't do anything
@@ -228,8 +228,26 @@ LString ExpandPath(LString const &path);
/// gets current working directory
LString GetCWD();
+
+
+//OS specific hacks to get a cleaner code base.
+
+//Should fix DOS-style path handling.
+inline
+LString CleanupPath(LString const &path)
+{
+#ifdef __EMX__ /* SMiyata: This should fix searchpath bug. */
+ LString temppath(path);
+ temppath.subst('\\', '/');
+ temppath.lowercase();
+ return temppath;
+#else // On unix, nothing to do
+ return path;
+#endif
+}
+
/// A helper function.
inline LString getEnvPath(char const *name)
{
LString pathlist;
@@ -276,8 +294,25 @@ LString OnlyFilename(LString const &File
Replaces all occurences of these, if they are found in the
environment.
Variables are defined by Var := '${' [a-zA-Z_][a-zA-Z_0-9]* '}'
*/
+//
+// CompareChar: Environmentvariables starts with this character
+// PathChar: Next path component start with this character
+// while CompareChar found do:
+// Split String with PathChar
+// Search Environmentvariable
+// if found: Replace Strings
+//
+// first: Search for a '$' - Sign.
+#define COMPARE_CHAR '$'
+#define FIRST_CHAR '{'
+
+// Check, if there is an EndChar inside original String.
+#define END_CHAR '}'
+#define UNDERSCORE_CHAR '_'
+#define REGEX "*}*" // Exist EndChar inside a String?
+
LString ReplaceEnvironmentPath(LString const &path);
/* Set Link to the path File Points to as a symbolic link.
Return True if succesfull, False other wise */
diff -p -N -r -U 4 -X excl.tmp src/original/LString.C
src/modified/LString.C
--- src/original/LString.C Mon Oct 26 15:17:18 1998
+++ src/modified/LString.C Tue Jul 27 21:50:58 1999
@@ -162,9 +162,10 @@ LString &LString::clean()
char& LString::operator[](int i)
{
#ifdef DEVEL_VERSION
if (i < 0 || i >= length()) {
- fprintf(stderr,"LString::operator[]: Index out of
range: '%s' %d\n", p->s, i);
+ fprintf(stderr,"LString::operator[]: Index out of
range: '%s' %d\n",
+ p->s, i);
abort();
}
#endif
@@ -493,8 +494,25 @@ bool LString::suffixIs(char const * suf)
return strncmp(p->s + (length()-suflen), suf,
suflen)==0;
}
+/* SMiyata: To bitwise AND 0x7f a string is more efficient than
subst();
+** ISO-8859-x and EUC (Extended Unix Code) works just fine with this.
+** The only remaining problem is that Microsoft/IBM codepages,
+** Shift-JIS and Big5 utilizes the region 0x80-0x9f which will be
+** converted to non-printable control characters.
+*/
+LString& LString::toAsciiAlnum()
+{
+ for (int i=0; i<length(); i++) {
+ p->s[i] &= MASK_RANGE; /* make test result
foreseeable */
+ if (!(isalnum(p->s[i])) && p->s[i] !=
EXTENSION_MARKER)
+ p->s[i] = REPLACER;
+ }
+ return *this;
+}
+
+
LString& LString::subst(char oldchar, char newchar)
{
for (int i=0; i<length() ; i++)
if (p->s[i]==oldchar)
@@ -524,9 +542,28 @@ LString& LString::subst(char const * old
LString& LString::lowercase()
{
for (int i=0; i<length() ; i++)
+#ifdef _EMX_
+/* AHanses: This macro handles non ASCII characters according to
locale */
+/* AHanses: DBCS unsafe */
+ p->s[i] = _nls_tolower((unsigned char) p->s[i]);
+#else
p->s[i] = tolower((unsigned char) p->s[i]);
+#endif
+ return *this;
+}
+
+LString& LString::uppercase() /* just in case.. */
+{
+ for (int i=0; i<length() ; i++)
+#ifdef _EMX_
+/* AHanses: This macro handles non ASCII characters according to
locale */
+/* AHanses: DBCS unsafe */
+ p->s[i] = _nls_toupper((unsigned char) p->s[i]);
+#else
+ p->s[i] = toupper((unsigned char) p->s[i]);
+#endif
return *this;
}
diff -p -N -r -U 4 -X excl.tmp src/original/LString.h
src/modified/LString.h
--- src/original/LString.h Mon Oct 26 15:17:20 1998
+++ src/modified/LString.h Tue Jul 27 21:54:06 1999
@@ -26,8 +26,12 @@
// should go (JMarc)
#include <strings.h>
#else
#include <string.h>
+# ifdef __EMX__
+/* AHanses: Macros handling non ASCII chars according to locale */
+# include <sys/nls.h>
+# endif
#endif
/** A string class for LyX
@@ -208,8 +212,20 @@ public:
/// Does the string end with this suffix?
bool suffixIs(char const *) const;
+ /// Convert whole string bit-wise to printable ASCII
+ /* SMiyata: Bitwise AND 0x7f the string, then replace
+ ** AHanses: non-alpanumeric characters with REPLACER.
+ ** Exception: Preserve non alnum EXTENSION_MARKER.
+ ** More efficient than subst() per char.
+ */
+ #define MASK_RANGE 0x7f /* ASCII range */
+ #define REPLACER 120 /* ASCII 'x' */
+ #define EXTENSION_MARKER 46 /* ASCII '.' */
+
+ LString& toAsciiAlnum();
+
/// Substitute all "oldchar"s with "newchar"
LString& subst(char oldchar, char newchar);
/// Substitutes all instances of oldstr with newstr
@@ -221,8 +237,11 @@ public:
bool regexMatch(LString const & pattern) const;
/// Lowercases a string
LString& lowercase();
+
+ /// Uppercases a string
+ LString& uppercase(); /* just in case.. */
/// Counts how many of character c there is in string
int countChar(const char c) const;
-----------------snap----------------------