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----------------------

Reply via email to