When LyX 1.2.0 is started in Turkish locale ~$ LANG=tr_TR lyx
one receives lots of error messages like LyX: menubar::read: Unknown menu tag: `Item' [around line 28 of file /usr/share/lyx/ui/default.ui] LyX: menubar::read: Unknown menu tag: `New...|N' [around line 28 of file /usr/share/lyx/ui/default.ui] [...] And then the LyX-window pops up with a broken menu bar. The reason for this is as stated in a comment in file lyxlex_pimpl.C around line 26: struct compare_tags { // used by lower_bound, sort and sorted inline int operator()(keyword_item const & a, keyword_item const & b) const { // we use the ascii version, because in turkish, 'i' // is not the lowercase version of 'I', and thus // turkish locale breaks parsing of tags. return compare_ascii_no_case(a.tag, b.tag) < 0; } }; But there are many other places in the current LyX source code where tags are converted to lowercase with the locale dependent tolower() function before conversion and the subsequent comparison fails because of the above mentioned problem. The attached lyx-1.2.0-turkish.patch fixes this problem by using special ASCII only, locale independent routine for lowercasing not only in lyxlex_pimpl.C but also at all the other places where this problem occured. Please review this patch and apply if it is an appropriate fix. After applying this patch, LyX starts without error message and the menu bar is correct. Then the problem remains that some Turkish characters cannot by typed into LyX when using the Turkish keyboard mapping ('setxkbmap tr'). For example one cannot type the character ğ ("gbreve"): KeyRelease event, serial 24, synthetic NO, window 0x1800001, root 0x35, subw 0x0, time 160488520, (107,161), root:(435,741), state 0x0, keycode 34 (keysym 0x2bb, gbreve), same_screen YES, XLookupString gives 2 characters: "ğ" and several other characters. The reason for that is in the kb_keymap::getiso method in file kbmap.C. The attached lyx-1.2.0-turkish-iso.patch fixes this problem as well. Is this a proper solution? It looks a bit like a strange hack, but it works.
diff -ru lyx-1.2.0.orig/src/LColor.C lyx-1.2.0/src/LColor.C --- lyx-1.2.0.orig/src/LColor.C Thu Mar 21 18:25:07 2002 +++ lyx-1.2.0/src/LColor.C Fri Jun 14 15:39:24 2002 @@ -186,7 +186,7 @@ InfoTab::const_iterator ici = infotab.begin(); InfoTab::const_iterator end = infotab.end(); for (; ici != end; ++ici) { - if (!compare_no_case(_(ici->second.guiname), guiname)) + if (!compare_ascii_no_case(_(ici->second.guiname), guiname)) return ici->first; } return LColor::inherit; @@ -199,7 +199,7 @@ InfoTab::const_iterator ici = infotab.begin(); InfoTab::const_iterator end = infotab.end(); for (; ici != end; ++ici) { - if (!compare_no_case(ici->second.lyxname, lyxname)) + if (!compare_ascii_no_case(ici->second.lyxname, lyxname)) return ici->first; } return LColor::inherit; diff -ru lyx-1.2.0.orig/src/MenuBackend.C lyx-1.2.0/src/MenuBackend.C --- lyx-1.2.0.orig/src/MenuBackend.C Mon Apr 29 11:50:33 2002 +++ lyx-1.2.0/src/MenuBackend.C Fri Jun 14 15:39:05 2002 @@ -237,7 +237,7 @@ << "\" does not contain shortcut `" << shortcut << '\'' << endl; for (const_iterator it2 = begin(); it2 != it1 ; ++it2) { - if (!compare_no_case(it2->shortcut(), shortcut)) { + if (!compare_ascii_no_case(it2->shortcut(), shortcut)) { lyxerr << "Menu warning: menu entries " << '"' << it1->fulllabel() << "\" and \"" << it2->fulllabel() @@ -451,7 +451,7 @@ }; //consistency check - if (compare_no_case(lex.getString(), "menuset")) { + if (compare_ascii_no_case(lex.getString(), "menuset")) { lyxerr << "Menubackend::read: ERROR wrong token:`" << lex.getString() << '\'' << endl; } diff -ru lyx-1.2.0.orig/src/ToolbarDefaults.C lyx-1.2.0/src/ToolbarDefaults.C --- lyx-1.2.0.orig/src/ToolbarDefaults.C Thu Mar 21 18:25:09 2002 +++ lyx-1.2.0/src/ToolbarDefaults.C Fri Jun 14 15:43:52 2002 @@ -98,7 +98,7 @@ void ToolbarDefaults::read(LyXLex & lex) { //consistency check - if (compare_no_case(lex.getString(), "toolbar")) { + if (compare_ascii_no_case(lex.getString(), "toolbar")) { lyxerr << "Toolbar::read: ERROR wrong token:`" << lex.getString() << '\'' << endl; } Only in lyx-1.2.0/src: ToolbarDefaults.C.~1~ diff -ru lyx-1.2.0.orig/src/buffer.C lyx-1.2.0/src/buffer.C --- lyx-1.2.0.orig/src/buffer.C Tue May 21 15:10:23 2002 +++ lyx-1.2.0/src/buffer.C Fri Jun 14 21:32:34 2002 @@ -533,7 +533,7 @@ layoutname = tclass.defaultLayoutName(); } #ifndef NO_COMPABILITY - if (compare_no_case(layoutname, "latex") == 0) { + if (compare_ascii_no_case(layoutname, "latex") == 0) { ert_comp.active = true; ert_comp.fromlayout = true; ert_comp.font = font; @@ -554,7 +554,7 @@ #ifdef USE_CAPTION // The is the compability reading of layout caption. // It can be removed in LyX version 1.3.0. (Lgb) - if (compare_no_case(layoutname, "caption") == 0) { + if (compare_ascii_no_case(layoutname, "caption") == 0) { // We expect that the par we are now working on is // really inside a InsetText inside a InsetFloat. // We also know that captions can only be @@ -1566,7 +1566,7 @@ // This strange command allows LyX to recognize "natbib" style // citations: citet, citep, Citet etc. - if (compare_no_case(cmdName, "cite", 4) == 0) { + if (compare_ascii_no_case(cmdName, "cite",4) == 0) { inset = new InsetCitation(inscmd); } else if (cmdName == "bibitem") { lex.printError("Wrong place for bibitem"); @@ -1933,10 +1933,10 @@ // First write the layout string const & tmp = par->layout(); - if (compare_no_case(tmp, "itemize") == 0) { + if (compare_ascii_no_case(tmp, "itemize") == 0) { ltype = 1; ltype_depth = depth + 1; - } else if (compare_no_case(tmp, "enumerate") == 0) { + } else if (compare_ascii_no_case(tmp, "enumerate") == 0) { ltype = 2; ltype_depth = depth + 1; } else if (contains(lowercase(tmp), "ection")) { @@ -1945,13 +1945,13 @@ } else if (contains(lowercase(tmp), "aragraph")) { ltype = 4; ltype_depth = depth + 1; - } else if (compare_no_case(tmp, "description") == 0) { + } else if (compare_ascii_no_case(tmp, "description") == 0) { ltype = 5; ltype_depth = depth + 1; - } else if (compare_no_case(tmp, "abstract") == 0) { + } else if (compare_ascii_no_case(tmp, "abstract") == 0) { ltype = 6; ltype_depth = 0; - } else if (compare_no_case(tmp, "bibliography") == 0) { + } else if (compare_ascii_no_case(tmp, "bibliography") == 0) { ltype = 7; ltype_depth = 0; } else { diff -ru lyx-1.2.0.orig/src/converter.C lyx-1.2.0/src/converter.C --- lyx-1.2.0.orig/src/converter.C Wed Mar 27 01:05:28 2002 +++ lyx-1.2.0/src/converter.C Fri Jun 14 15:03:32 2002 @@ -260,10 +260,13 @@ bool operator<(Converter const & a, Converter const & b) { - int const i = compare_no_case(a.From->prettyname(), - b.From->prettyname()); + // use the compare_ascii_no_case instead of compare_no_case, + // because in turkish, 'i' is not the lowercase version of 'I', + // and thus turkish locale breaks parsing of tags. + int const i = compare_ascii_no_case(a.From->prettyname(), + b.From->prettyname()); if (i == 0) - return compare_no_case(a.To->prettyname(), b.To->prettyname()) + return compare_ascii_no_case(a.To->prettyname(), b.To->prettyname()) < 0; else return i < 0; diff -ru lyx-1.2.0.orig/src/converter.h lyx-1.2.0/src/converter.h --- lyx-1.2.0.orig/src/converter.h Thu Mar 21 18:25:09 2002 +++ lyx-1.2.0/src/converter.h Fri Jun 14 15:03:53 2002 @@ -77,7 +77,11 @@ inline bool operator<(Format const & a, Format const & b) { - return compare_no_case(a.prettyname(), b.prettyname()) < 0; + // use the compare_ascii_no_case instead of compare_no_case, + // because in turkish, 'i' is not the lowercase version of 'I', + // and thus turkish locale breaks parsing of tags. + + return compare_ascii_no_case(a.prettyname(), b.prettyname()) < 0; } diff -ru lyx-1.2.0.orig/src/frontends/controllers/biblio.C lyx-1.2.0/src/frontends/controllers/biblio.C --- lyx-1.2.0.orig/src/frontends/controllers/biblio.C Mon May 13 15:23:29 2002 +++ lyx-1.2.0/src/frontends/controllers/biblio.C Fri Jun 14 15:48:29 2002 @@ -265,7 +265,7 @@ struct compareNoCase: public std::binary_function<string, string, bool> { bool operator()(string const & s1, string const & s2) const { - return compare_no_case(s1, s2) < 0; + return compare_ascii_no_case(s1, s2) < 0; } }; Only in lyx-1.2.0/src/frontends/controllers: biblio.C.~1~ diff -ru lyx-1.2.0.orig/src/lyxlex.C lyx-1.2.0/src/lyxlex.C --- lyx-1.2.0.orig/src/lyxlex.C Thu Mar 21 18:25:14 2002 +++ lyx-1.2.0/src/lyxlex.C Fri Jun 14 15:37:47 2002 @@ -168,7 +168,7 @@ // We do a case independent comparison, like search_kw // does. - if (compare_no_case(token, endtoken) != 0) { + if (compare_ascii_no_case(token, endtoken) != 0) { string tmpstr = getString(); if (firstline) { unsigned int i = 0; diff -ru lyx-1.2.0.orig/src/lyxlex_pimpl.C lyx-1.2.0/src/lyxlex_pimpl.C --- lyx-1.2.0.orig/src/lyxlex_pimpl.C Thu Mar 21 18:25:14 2002 +++ lyx-1.2.0/src/lyxlex_pimpl.C Thu Jun 13 18:02:39 2002 @@ -379,8 +379,11 @@ keyword_item * res = lower_bound(table, table + no_items, search_tag, compare_tags()); + // use the compare_ascii_no_case instead of compare_no_case, + // because in turkish, 'i' is not the lowercase version of 'I', + // and thus turkish locale breaks parsing of tags. if (res != table + no_items - && !compare_no_case(res->tag, tag)) + && !compare_ascii_no_case(res->tag, tag)) return res->code; return LEX_UNDEF; } diff -ru lyx-1.2.0.orig/src/support/lstrings.C lyx-1.2.0/src/support/lstrings.C --- lyx-1.2.0.orig/src/support/lstrings.C Mon Apr 15 14:05:07 2002 +++ lyx-1.2.0/src/support/lstrings.C Fri Jun 14 21:33:55 2002 @@ -111,6 +111,28 @@ return 1; } +int compare_ascii_no_case(string const & s, string const & s2, unsigned int len) +{ + string::const_iterator p = s.begin(); + string::const_iterator p2 = s2.begin(); + unsigned int i = 0; + while (i < len && p != s.end() && p2 != s2.end()) { + int const lc1 = ascii_tolower(*p); + int const lc2 = ascii_tolower(*p2); + if (lc1 != lc2) + return (lc1 < lc2) ? -1 : 1; + ++i; + ++p; + ++p2; + } + + if (s.size() >= len && s2.size() >= len) + return 0; + if (s.size() < s2.size()) + return -1; + return 1; +} + bool isStrInt(string const & str) { @@ -218,13 +240,19 @@ char lowercase(char c) { - return char(tolower(c)); + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + return c; + // return char(tolower(c)); } char uppercase(char c) { - return char(toupper(c)); + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + return c; + // return char(toupper(c)); } @@ -235,13 +263,19 @@ struct local_lowercase { char operator()(char c) const { - return tolower(c); + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + return c; + // return tolower(c); } }; struct local_uppercase { char operator()(char c) const { - return toupper(c); + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + return c; + // return toupper(c); } }; Only in lyx-1.2.0/src/support: lstrings.C.~1~ diff -ru lyx-1.2.0.orig/src/support/lstrings.h lyx-1.2.0/src/support/lstrings.h --- lyx-1.2.0.orig/src/support/lstrings.h Mon Apr 15 14:05:07 2002 +++ lyx-1.2.0/src/support/lstrings.h Fri Jun 14 21:34:39 2002 @@ -35,6 +35,9 @@ int compare_no_case(string const & s, string const & s2, unsigned int len); /// +int compare_ascii_no_case(string const & s, string const & s2, unsigned int len); + +/// inline int compare(char const * a, char const * b) { Only in lyx-1.2.0/src/support: lstrings.h.~1~
--- lyx-1.2.0/src/kbmap.C.orig Thu Jun 20 01:39:24 2002 +++ lyx-1.2.0/src/kbmap.C Thu Jun 20 01:40:44 2002 @@ -10,6 +10,8 @@ #include <config.h> +#include <locale.h> +#include <langinfo.h> #include <X11/Xlib.h> #ifdef __GNUG__ @@ -45,6 +46,38 @@ char kb_keymap::getiso(unsigned int c) { + if (strcmp(nl_langinfo(CODESET),"ISO-8859-9") == 0) { + // we are running in a latin 5 locale (e.g. Turkish) + // ox2b9: idotless + // 0x2bb: gbreve + // 0x2ab: Gbreve + // 0x2a9: Iabovedot + // 0x1ba: scedilla + // 0x1aa: Scedilla + switch (c) { + case 0x2b9: + c = 0xfd; + break; + case 0x2bb: + c = 0xf0; + break; + case 0x2ab: + c = 0xd0; + break; + case 0x2a9: + c = 0xdd; + break; + case 0x1ba: + c = 0xfe; + break; + case 0x1aa: + c = 0xde; + default: + break; + } + } + + switch (c & 0x0000FF00) { // latin 1 byte 3 = 0 case 0x00000000: break;
-- Mike Fabian <[EMAIL PROTECTED]> http://www.suse.de/~mfabian $B?gL2ITB-$O$$$$;E;v$NE($@!#(B