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