On Thu, 22 Jul 1999 19:11:17 +0200 (MET DST), Jean-Marc Lasgouttes
wrote:

>Arnd> Well, this works on my box. (Did not test every
>Arnd> possible 8 bit combination, too lazy to write a test program).

Yes, for me it works well, as it seems.

>Arnd> Is this safe on all UNICES?
>
>Arnd> Better ideas someone?
>
>Arnd> More generic approach desirable?
>
>What I do not understand is that the sign is not discarded, but
>replaced with some apparently random letter... Why not replace all
>letters larger than 127 with 'X' or whatever?
>
>Arnd> Shall I submit a patch or better wait?
>
>I'd rather have Asger and/or Lars ideas about that. You can submit a
>patch anyway, so that we have something concrete to discuss...

This is something concrete I hope. 

Please have a close look, I understand
only some 80% of what I've written here, especially LString class (as
C++ class) is a bit too complicated for me... ;)


Greets,

        Arnd


patch against lyx103:

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    Fri Jul 23 01:18:56 1999
@@ -78,8 +78,9 @@ LString SpaceLess(LString const & file)
 {
        LString name = OnlyFilename(file);
        LString path = OnlyPath(file);
        // Substitute chars that LaTeX can't handle with safe ones
+       name.toAsciiPrintable(); /* AHanses: Set bit 0, unset bit >= 5
*/
        name.subst('~','-');
        name.subst('$','S');
        name.subst('%','_');
        name.subst('\'','_');
@@ -88,17 +89,21 @@ LString SpaceLess(LString const & file)
        name.subst('`', '_');
        name.subst('"', '_');
        name.subst('&', 'G');
        name.subst('|', 'I');
-       name.subst(';', ':');
+       name.subst(';', ','); /* AHanses: Murphy-circle
':'/';'/':'/... fix! */
        name.subst('(', 'c');
        name.subst(')', 'C');
        name.subst('<', 'k');
        name.subst('>', 'K');
-       
+
+//     name.subst(' ', 'z'); /* AHanses: no more trouble with
'umlauts'? */
+// #warning AHanses: List is incomplete. Please find a more generic
solution. */
+
        LString temp = AddName(path, name);
        // Replace spaces with underscores, also in directory
        temp.subst(' ','_');
+               /* AHanses: Seems to handle 'umlauts' in directory
correctly, too */
 
        return temp;
 }
 
@@ -208,8 +213,13 @@ LString FileOpenSearch (LString const & 
 {
        LString real_file, path_element;
        LString tmppath = path;
        bool notfound = true;
+       
+#ifdef __EMX__   /* SMiyata: This should fix searchpath bug. */
+       tmppath.subst('\\', '/');
+       tmppath.lowercase();
+#endif
 
        tmppath.split(path_element, ';');
        
        while (notfound && !path_element.empty()) {
@@ -461,17 +471,22 @@ LString OnlyPath(LString const &Filename
 {
        // If empty filename, return empty
        if (Filename.empty()) return Filename;
 
+       LString temp = Filename;
+
+#ifdef __EMX__   /* SMiyata: This should fix searchpath bug. */
+       temp.subst('\\', '/');
+       temp.lowercase();
+#endif
        // 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);
        }
 }
 
@@ -575,17 +590,24 @@ LString OnlyFilename(LString const &File
 {
        // If empty filename, return empty
        if (Filename.empty()) return Filename;
 
+       LString temp = Filename;
+
+#ifdef __EMX__   /* SMiyata: This should fix searchpath bug. */
+       temp.subst('\\', '/');
+       temp.lowercase();
+#endif
+
        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;
+//     LString temp = Filename;
        return temp.substring(j, temp.length()-1);
 }
 
 
@@ -593,10 +615,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 +636,9 @@ LString ExpandPath(LString const &path)
        if (AbsolutePath(RTemp))
                return RTemp;
 
        LString Temp;
+
        LString copy(RTemp);
 
        // Split by next /
        RTemp.split(Temp, '/');
@@ -635,15 +663,22 @@ LString NormalizePath(LString const &pat
        LString TempBase;
        LString RTemp;
        LString Temp;
 
-       if (AbsolutePath(path))
+       if (AbsolutePath(path)) {
                RTemp = path;
-       else
+       }
+       else {
                // Make implicit current directory explicit
                RTemp = "./" +path;
-
+       }
        while (!RTemp.empty()) {
+       
+#ifdef __EMX__   /* SMiyata: This should fix searchpath bug. */
+               RTemp.subst('\\', '/');
+               RTemp.lowercase();
+#endif
+       
                // Split by next /
                RTemp.split(Temp, '/');
                
                if (Temp==".") {
@@ -694,10 +729,17 @@ LString ReplaceEnvironmentPath(LString c
        const LString RegExp("*}*"); // Exist EndChar inside a String?
 
        if (path.empty()) return path; // nothing to do.
 
+       LString temppath = path;
+       
+#ifdef __EMX__   /* SMiyata: This should fix searchpath bug. */
+       temppath.subst('\\', '/');
+       temppath.lowercase();
+#endif
+
 // first: Search for a '$' - Sign.
-       LString copy(path);
+       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,9 +813,57 @@ LString MakeRelPath(LString const & absp
 {
        // This is a hack. It should probaly be done in another way.
Lgb.
        if (abspath.empty())
                return "<unknown_path>";
+               
+               /* AHanses: Duplicating instead of cluttering with
#ifdef */
+#ifdef __EMX__   /* SMiyata: This should fix searchpath bug. */
 
+       const int abslen = abspath.length();            /*
AHanses: I use the 'const'                      */
+       const int baselen = basepath.length();  /*      as
far as possible, for speed */
+       
+       int i = 0;
+       LString tempabspath=abspath;
+       LString tempbasepath=basepath;
+       tempabspath.subst('\\', '/');
+       tempabspath.lowercase();
+       tempbasepath.subst('\\', '/');
+       tempbasepath.lowercase();
+
+       // 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 && tempabspath[i] != '/' && i==baselen)
+           || (i<baselen && tempbasepath[i] != '/' && i==abslen))
+       {
+               if (i) --i;     // here was the last match
+               while (i && tempabspath[i] != '/') --i;
+       }
+
+       if (i == 0) {
+               // actually no match - cannot make it relative
+               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 (tempbasepath[j] == '/') {
+                       if (j+1 == baselen) break;
+                       buf += "../";
+               }
+               ++j;
+       }
+
+       // Append relative stuff from common directory to abspath
+       if (tempabspath[i] == '/') ++i;
+       for (; i<abslen; ++i)
+               buf += tempabspath[i];
+#else
        const int abslen = abspath.length();
        const int baselen = basepath.length();
        
        // Find first different character
@@ -809,8 +899,9 @@ LString MakeRelPath(LString const & absp
        // Append relative stuff from common directory to abspath
        if (abspath[i] == '/') ++i;
        for (; i<abslen; ++i)
                buf += abspath[i];
+#endif
        // Remove trailing /
        if (buf.suffixIs('/'))
                buf.substring(0,buf.length()-2);
        // Substitute empty with .
@@ -818,30 +909,56 @@ 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;
+       
+#ifdef __EMX__ /* AHanses: Handle DOS-style paths ('\') */
+       if ( !path.empty() && path != "." && (path != "./" || path !=
".\\") )
+       {
+               buf = path;
+               /* SMiyata: This should fix searchpath bug. */
+               buf.subst('\\', '/');
+               buf.lowercase();
+               if (!path.suffixIs('/'))
+                       buf += '/';
+       }
+
+       if (!path2.empty())
+       {
+               /* SMiyata: This should fix searchpath bug. */
+               LString tmppath2 = 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 + '/';
+#else
        if (!path.empty() && path != "." && path != "./") {
                buf = path;
                if (!path.suffixIs('/'))
                        buf += '/';
        }
 
        if (!path2.empty()){
-               int p2start = 0;
+               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 + '/';
+               LString tmppath2 = path2;
+               tmppath2.substring(p2start,p2end);
+               buf += tmppath2 + '/';
+#endif
        }
        return buf;
 }
 
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      Fri Jul 23 02:10:42 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,24 @@ 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::toAsciiPrintable()
+{
+        for (int i=0; i<length(); i++) {
+               p->s[i] &= 0x7f;
+               p->s[i] |= 0x20;
+       }
+        return *this;
+}
+
+
 LString& LString::subst(char oldchar, char newchar)
 {
        for (int i=0; i<length() ; i++)
                if (p->s[i]==oldchar)
@@ -524,9 +541,13 @@ 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 */
+               p->s[i] = _nls_tolower((unsigned char) p->s[i]); /*
AHanses: DBCS unsafe */
+#else
                p->s[i] = tolower((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      Fri Jul 23 02:07:48 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,15 @@ 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 apply
+       ** AHanses: Bitwise  OR 0x21 to all the string bits;
+       ** more efficient than subst() per char 
+       */
+       LString& toAsciiPrintable();
+
        /// Substitute all "oldchar"s with "newchar"
        LString& subst(char oldchar, char newchar);
 
        /// Substitutes all instances of oldstr with newstr

Reply via email to