]> git.lyx.org Git - lyx.git/blobdiff - src/client/client.C
A better fix for bug 675:
[lyx.git] / src / client / client.C
index 64c2fcc711d76df3e2bb7f4b51bd4645806f557c..b4dc9ab435ba3e0d6a5154eeddf36112aef3e419 100644 (file)
@@ -13,7 +13,7 @@
 #include <config.h>
 
 #include "debug.h"
-#include "format.h"
+#include "support/unicode.h"
 #include "support/lstrings.h"
 
 #include <boost/filesystem/operations.hpp>
 #include <boost/scoped_ptr.hpp>
 
 // getpid(), getppid()
-#include <sys/types.h>
-#include <unistd.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+// struct timeval
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
 
 // select()
-#include <sys/select.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
 
 // socket(), connect()
-#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
 #include <sys/un.h>
 
 // fcntl()
@@ -41,6 +54,9 @@
 #include <map>
 #include <iostream>
 
+
+namespace lyx {
+
 using lyx::support::prefixIs;
 
 using boost::scoped_ptr;
@@ -54,8 +70,11 @@ using std::cin;
 using std::endl;
 
 
-// hack to link in libsupport 
-Formats formats;
+IconvProcessor & utf8ToUcs4()
+{
+       static IconvProcessor iconv(ucs4_codeset, "UTF-8");
+       return iconv;
+}
 
 
 namespace support {
@@ -66,8 +85,9 @@ string itoa(unsigned int i)
 }
 
 
-// Parts stolen from lyx::support::DirList()
-// Returns the absolute pathnames of all lyx local sockets
+/// Returns the absolute pathnames of all lyx local sockets in
+/// file system encoding.
+/// Parts stolen from lyx::support::DirList().
 vector<fs::path> lyxSockets(string const & dir, string const & pid)
 {
        vector<fs::path> dirlist;
@@ -85,7 +105,7 @@ vector<fs::path> lyxSockets(string const & dir, string const & pid)
 
        for (; beg != end; ++beg) {
                if (prefixIs(beg->leaf(), "lyx_tmpdir" + pid)) {
-                       fs::path lyxsocket = *beg / "lyxsocket";
+                       fs::path lyxsocket = beg->path() / "lyxsocket";
                        if (fs::exists(lyxsocket)) {
                                dirlist.push_back(lyxsocket);
                        }
@@ -99,6 +119,8 @@ vector<fs::path> lyxSockets(string const & dir, string const & pid)
 namespace socktools {
 
 
+/// Connect to the socket \p name.
+/// Caution: \p name is in filesystem encoding
 int connect(string const & name)
 {
        int fd; // File descriptor for the socket
@@ -316,7 +338,7 @@ void LyXDataSocket::writeln(string const & line)
 // Class CmdLineParser -------------------------------------------------------
 class CmdLineParser {
 public:
-       typedef int (*optfunc)(vector<char *> const & args);
+       typedef int (*optfunc)(vector<docstring> const & args);
        std::map<string, optfunc> helper;
        std::map<string, bool> isset;
        bool parse(int, char * []);
@@ -328,12 +350,12 @@ bool CmdLineParser::parse(int argc, char * argv[])
 {
        int opt = 1;
        while (opt < argc) {
-               vector<char *> args;
+               vector<docstring> args;
                if (helper[argv[opt]]) {
                        isset[argv[opt]] = true;
                        int arg = opt + 1;
                        while ((arg < argc) && (!helper[argv[arg]])) {
-                               args.push_back(argv[arg]);
+                               args.push_back(from_local8bit(argv[arg]));
                                ++arg;
                        }
                        int taken = helper[argv[opt]](args);
@@ -388,16 +410,16 @@ void usage()
 }
 
 
-int h(vector<char *> const &)
+int h(vector<docstring> const &)
 {
        usage();
        exit(0);
 }
 
 
-string clientName(support::itoa(::getppid()) + ">" + support::itoa(::getpid()));
+docstring clientName(from_ascii(support::itoa(::getppid()) + ">" + support::itoa(::getpid())));
 
-int n(vector<char *> const & arg)
+int n(vector<docstring> const & arg)
 {
        if (arg.size() < 1) {
                cerr << "lyxclient: The option -n requires 1 argument."
@@ -409,10 +431,10 @@ int n(vector<char *> const & arg)
 }
 
 
-string singleCommand;
+docstring singleCommand;
 
 
-int c(vector<char *> const & arg)
+int c(vector<docstring> const & arg)
 {
        if (arg.size() < 1) {
                cerr << "lyxclient: The option -c requires 1 argument."
@@ -424,7 +446,7 @@ int c(vector<char *> const & arg)
 }
 
 
-int g(vector<char *> const & arg)
+int g(vector<docstring> const & arg)
 {
        if (arg.size() < 2) {
                cerr << "lyxclient: The option -g requires 2 arguments."
@@ -432,17 +454,17 @@ int g(vector<char *> const & arg)
                return -1;
        }
        singleCommand = "LYXCMD:server-goto-file-row "
-               + string(arg[0]) + ' '
-               + string(arg[1]);
+               + arg[0] + ' '
+               + arg[1];
        return 2;
 }
 
 
-// 0 if LYXSOCKET is not set in the environment
-char * serverAddress = getenv("LYXSOCKET");
+// empty if LYXSOCKET is not set in the environment
+docstring serverAddress;
 
 
-int a(vector<char *> const & arg)
+int a(vector<docstring> const & arg)
 {
        if (arg.size() < 1) {
                cerr << "lyxclient: The option -a requires 1 argument."
@@ -455,10 +477,10 @@ int a(vector<char *> const & arg)
 }
 
 
-string mainTmp("/tmp");
+docstring mainTmp(from_ascii("/tmp"));
 
 
-int t(vector<char *> const & arg)
+int t(vector<docstring> const & arg)
 {
        if (arg.size() < 1) {
                cerr << "lyxclient: The option -t requires 1 argument."
@@ -473,28 +495,32 @@ int t(vector<char *> const & arg)
 string serverPid; // Init to empty string
 
 
-int p(vector<char *> const & arg)
+int p(vector<docstring> const & arg)
 {
        if (arg.size() < 1) {
                cerr << "lyxclient: The option -p requires 1 argument."
                     << endl;
                return -1;
        }
-       serverPid = arg[0];
+       serverPid = to_ascii(arg[0]);
        return 1;
 }
 
 
 } // namespace cmdline
 
-
-
+} // namespace lyx
 
 
 int main(int argc, char * argv[])
 {
+       using namespace lyx;
        lyxerr.rdbuf(cerr.rdbuf());
 
+       char const * const lyxsocket = getenv("LYXSOCKET");
+       if (lyxsocket)
+               cmdline::serverAddress = from_local8bit(lyxsocket);
+
        CmdLineParser args;
        args.helper["-h"] = cmdline::h;
        args.helper["-c"] = cmdline::c;
@@ -514,20 +540,21 @@ int main(int argc, char * argv[])
 
        scoped_ptr<LyXDataSocket> server;
 
-       if (cmdline::serverAddress) {
-               server.reset(new LyXDataSocket(cmdline::serverAddress));
+       if (!cmdline::serverAddress.empty()) {
+               server.reset(new LyXDataSocket(to_utf8(cmdline::serverAddress)));
                if (!server->connected()) {
                        cerr << "lyxclient: " << "Could not connect to "
-                            << cmdline::serverAddress << endl;
+                            << to_utf8(cmdline::serverAddress) << endl;
                        return EXIT_FAILURE;
                }
        } else {
                // We have to look for an address.
                // serverPid can be empty.
-               vector<fs::path> addrs = support::lyxSockets(cmdline::mainTmp, cmdline::serverPid);
+               vector<fs::path> addrs = support::lyxSockets(to_utf8(cmdline::mainTmp), cmdline::serverPid);
                vector<fs::path>::const_iterator addr = addrs.begin();
                vector<fs::path>::const_iterator end = addrs.end();
                for (; addr != end; ++addr) {
+                       // Caution: addr->string() is in filesystem encoding
                        server.reset(new LyXDataSocket(addr->string()));
                        if (server->connected())
                                break;
@@ -551,7 +578,7 @@ int main(int argc, char * argv[])
        string answer;
 
        // Send greeting
-       server->writeln("HELLO:" + cmdline::clientName);
+       server->writeln("HELLO:" + to_utf8(cmdline::clientName));
        // wait at most 2 seconds until server responds
        iowatch.wait(2.0);
        if (iowatch.isset(serverfd) && server->readln(answer)) {
@@ -566,7 +593,7 @@ int main(int argc, char * argv[])
        }
 
        if (args.isset["-g"] || args.isset["-c"]) {
-               server->writeln(cmdline::singleCommand);
+               server->writeln(to_utf8(cmdline::singleCommand));
                iowatch.wait(2.0);
                if (iowatch.isset(serverfd) && server->readln(answer)) {
                        cout << answer;
@@ -602,3 +629,15 @@ int main(int argc, char * argv[])
 
        return EXIT_SUCCESS;
 }
+
+
+namespace boost {
+
+void assertion_failed(char const* a, char const* b, char const* c, long d)
+{
+       lyx::lyxerr << "Assertion failed: " << a << ' ' << b << ' ' << c << ' '
+               << d << '\n';
+}
+
+} // namespace boost
+