On Sun, Apr 02, 2006 at 10:20:35PM +0200, Georg Baum wrote:

> Am Sonntag, 2. April 2006 17:57 schrieb Enrico Forestieri:
> > Well, I am facing a problem related to it now. Please, help this
> > C++ newbie to solve the following problem.
> > 
> > I had already the need to add an enum argument to internal_path.
> > Its natural declaration was in "support/os.h" in the
> > lyx::support::os namespace:
> > 
> > enum path_target {
> >     DEFAULT,
> >     LATEX
> > }
> > 
> > std::string internal_path(std::string const & p,
> >                             path_target target = DEFAULT);
> 
> May I ask you why you need it? Is that for conversion of paths that come 
> from latex?

No, it is for conversion of paths going to .tex files. See below
the reason I need it.

> > Now I have the need to add the same argument to ChangeExtension()
> > which is declared in support/filetools.h. This is because
> > ChangeExtension() is called either when the path is intended to
> > go in a .tex file or not. So I need to change the call to
> > ChangeExtension() in lyx::support::latex_path by adding the enum
> > argument with value LATEX.
> 
> I don't see the need for it. Regardless how paths are represented 
> externally, all internal paths on all platforms have always forward 
> slashes, so ChangeExtension should just work.

No, it is not because of that. The point is that
lyx::support::latex_path() calls ChangeExtensions, which in turn
calls internal_path(), which would turn the path into posix in
cygwin.

Please, attached find the patch satifying your requests. All
internal paths are in posix style. External and latex paths may
be posix or windows style depending on cygwin_path_fix, exactly
as it was.

I have not introduced any new boolean and substantially left
things as they were. Only, all bugs are now corrected and there
is no mess of internal paths.

I strongly believe that external and latex path styles should be
selected independently. If you think that the user should be able
to subvert the decision of the configure script about latex
paths, I think that another checkbox can be added along the one
already existing. They could be labelled "Use cygwin-style paths
in latex files" and "Use cygwin-style paths for external
programs". If you think that someone can be confused by those
labels, well, I don't know what to say (I really know, but won't
tell ;-))

The possibility of deciding the style of paths used for external
programs is quite user friendly and I think it is a must. After
all cygwin runs on windows.

-- 
Enrico
Index: src/frontends/qt2/QPrefs.C
===================================================================
--- src/frontends/qt2/QPrefs.C  (revision 13547)
+++ src/frontends/qt2/QPrefs.C  (working copy)
@@ -148,6 +148,11 @@ string const internal_path(QString const
        return lyx::support::os::internal_path(fromqstr(input));
 }
 
+string const internal_path_list(QString const & input)
+{
+       return lyx::support::os::internal_path_list(fromqstr(input));
+}
+
 }
 
 
@@ -253,7 +258,7 @@ void QPrefs::apply()
        rc.template_path = internal_path(pathsmod->templateDirED->text());
        rc.backupdir_path = internal_path(pathsmod->backupDirED->text());
        rc.tempdir_path = internal_path(pathsmod->tempDirED->text());
-       rc.path_prefix = fromqstr(pathsmod->pathPrefixED->text());
+       rc.path_prefix = internal_path_list(pathsmod->pathPrefixED->text());
        // FIXME: should be a checkbox only
        rc.lyxpipes = internal_path(pathsmod->lyxserverDirED->text());
 
@@ -467,6 +472,11 @@ QString const external_path(string const
        return toqstr(lyx::support::os::external_path(input));
 }
 
+QString const external_path_list(string const & input)
+{
+       return toqstr(lyx::support::os::external_path_list(input));
+}
+
 }
 
 
@@ -583,7 +593,7 @@ void QPrefs::update_contents()
        pathsmod->templateDirED->setText(external_path(rc.template_path));
        pathsmod->backupDirED->setText(external_path(rc.backupdir_path));
        pathsmod->tempDirED->setText(external_path(rc.tempdir_path));
-       pathsmod->pathPrefixED->setText(toqstr(rc.path_prefix));
+       pathsmod->pathPrefixED->setText(external_path_list(rc.path_prefix));
        // FIXME: should be a checkbox only
        pathsmod->lyxserverDirED->setText(external_path(rc.lyxpipes));
 
Index: src/frontends/qt2/ChangeLog
===================================================================
--- src/frontends/qt2/ChangeLog (revision 13547)
+++ src/frontends/qt2/ChangeLog (working copy)
@@ -1,3 +1,8 @@
+2006-04-03  Enrico Forestieri <[EMAIL PROTECTED]>
+
+       * QPrefs.C: Handle the PATH prefix style according to the
+       user-prefs style.
+
 2006-03-10  Martin Vermeer  <[EMAIL PROTECTED]>
 
        * QChanges.C: fix bug 2212: First change is skipped in
Index: src/support/os_unix.C
===================================================================
--- src/support/os_unix.C       (revision 13547)
+++ src/support/os_unix.C       (working copy)
@@ -57,7 +57,19 @@ string external_path(string const & p)
 }
 
 
-string internal_path(string const & p)
+string internal_path(string const & p, path_target)
+{
+       return p;
+}
+
+
+string external_path_list(string const & p)
+{
+       return p;
+}
+
+
+string internal_path_list(string const & p)
 {
        return p;
 }
Index: src/support/os.h
===================================================================
--- src/support/os.h    (revision 13547)
+++ src/support/os.h    (working copy)
@@ -26,6 +26,11 @@ enum shell_type {
        CMD_EXE
 };
 
+enum path_target {
+       DEFAULT,
+       LATEX
+};
+
 /// Do some work just once.
 void init(int argc, char * argv[]);
 
@@ -45,7 +50,13 @@ std::string::size_type common_path(std::
 std::string external_path(std::string const & p);
 
 /// Converts a host OS style path to unix style.
-std::string internal_path(std::string const & p);
+std::string internal_path(std::string const & p, path_target target = DEFAULT);
+
+/// Converts a unix style path list to host OS style.
+std::string external_path_list(std::string const & p);
+
+/// Converts a host OS style path list to unix style.
+std::string internal_path_list(std::string const & p);
 
 /**
  * Converts a unix style path into a form suitable for inclusion in a LaTeX
Index: src/support/filetools.C
===================================================================
--- src/support/filetools.C     (revision 13547)
+++ src/support/filetools.C     (working copy)
@@ -86,15 +86,15 @@ string const latex_path(string const & o
                latex_path_extension extension,
                latex_path_dots dots)
 {
-       string path = subst(original_path, "\\", "/");
        // On cygwin, we may need windows or posix style paths.
-       path = os::latex_path(path);
+       string path = os::latex_path(original_path);
        path = subst(path, "~", "\\string~");
        if (path.find(' ') != string::npos) {
                // We can't use '"' because " is sometimes active (e.g. if
                // babel is loaded with the "german" option)
                if (extension == EXCLUDE_EXTENSION) {
-                       string const base = ChangeExtension(path, string());
+                       string const base = ChangeExtension(path, string(),
+                                                               os::LATEX);
                        string const ext = GetExtension(path);
                        // ChangeExtension calls os::internal_path internally
                        // so don't use it to re-add the extension.
@@ -726,7 +726,8 @@ string const AddPath(string const & path
  Strips path off if no_path == true.
  If no extension on oldname, just appends.
  */
-string const ChangeExtension(string const & oldname, string const & extension)
+string const ChangeExtension(string const & oldname, string const & extension,
+                                                       os::path_target target)
 {
        string::size_type const last_slash = oldname.rfind('/');
        string::size_type last_dot = oldname.rfind('.');
@@ -740,7 +741,7 @@ string const ChangeExtension(string cons
        else
                ext = extension;
 
-       return os::internal_path(oldname.substr(0, last_dot) + ext);
+       return os::internal_path(oldname.substr(0, last_dot) + ext, target);
 }
 
 
Index: src/support/os_win32.C
===================================================================
--- src/support/os_win32.C      (revision 13547)
+++ src/support/os_win32.C      (working copy)
@@ -210,15 +210,27 @@ string const get_long_path(string const 
 } // namespace anon
 
 
-string internal_path(string const & p)
+string internal_path(string const & p, path_target)
 {
        return subst(get_long_path(p), "\\", "/");
 }
 
 
-string latex_path(string const & p)
+string external_path_list(string const & p)
+{
+       return p;
+}
+
+
+string internal_path_list(string const & p)
 {
        return p;
+}
+
+
+string latex_path(string const & p)
+{
+       return subst(p, '\\', '/');
 }
 
 
Index: src/support/ChangeLog
===================================================================
--- src/support/ChangeLog       (revision 13547)
+++ src/support/ChangeLog       (working copy)
@@ -1,3 +1,14 @@
+2006-04-03  Enrico Forestieri <[EMAIL PROTECTED]>
+
+       * os.h: New declarations to deal with PATH lists.
+       * os_cygwin.C: Major rewrite to account for path style problems.
+       * os_unix.C:
+       * os_win32.C: Stub functions for PATH lists.
+       * environment.C: fix bug 2344: Wrong path_prefix handling in cygwin
+       * filetools.h: ChangeExtension declaration
+       * filetools.C (latex_path, ChangeExtension): fix for the path
+       style to be written in .tex files (cygwin related).
+
 2006-03-15  Georg Baum  <[EMAIL PROTECTED]>
 
        * filename.C (mangledFilename): truncate filename to 140 characters
Index: src/support/os_cygwin.C
===================================================================
--- src/support/os_cygwin.C     (revision 13547)
+++ src/support/os_cygwin.C     (working copy)
@@ -27,6 +27,8 @@
 using std::endl;
 using std::string;
 
+using lyx::support::contains;
+
 
 namespace lyx {
 namespace support {
@@ -66,39 +68,104 @@ namespace {
 
 bool cygwin_path_fix_ = false;
 
+// In both is_posix_path() and is_windows_path() it is assumed that
+// a valid posix or windows path is passed. They simply tell whether
+// the path looks posix/windows or not.
+
+bool is_posix_path(string const & p)
+{
+       return  p.empty() ||
+               (!contains(p, '\\') && (p.length() < 1 || p[1] != ':'));
+}
+
+// This is a test for a win32 style path with forward slashes.
+
+bool is_windows_path(string const & p)
+{
+       return p.empty() ||
+               (!contains(p, '\\') && (p.length() < 1 || p[1] == ':'));
+}
+
+
+enum PathStyle {
+    posix,
+    windows
+};
+
+
+string convert_path(string const & p, PathStyle const & target)
+{
+       char path_buf[PATH_MAX];
+
+       if ((target == posix && is_posix_path(p)) ||
+           (target == windows && is_windows_path(p)))
+               return p;
+
+       path_buf[0] = '\0';
+
+       if (target == posix)
+               cygwin_conv_to_posix_path(p.c_str(), path_buf);
+       else
+               cygwin_conv_to_win32_path(p.c_str(), path_buf);
+
+       return subst(path_buf[0] ? path_buf : p, '\\', '/');
+}
+
+
+string convert_path_list(string const & p, PathStyle const & target)
+{
+       char const * const pc = p.c_str();
+       PathStyle const actual = cygwin_posix_path_list_p(pc) ? posix : windows;
+
+       if (target != actual) {
+               int const target_size = (target == posix) ?
+                               cygwin_win32_to_posix_path_list_buf_size(pc) :
+                               cygwin_posix_to_win32_path_list_buf_size(pc);
+
+               char * ptr = new char[target_size];
+
+               if (ptr) {
+                       if (target == posix)
+                               cygwin_win32_to_posix_path_list(pc, ptr);
+                       else
+                               cygwin_posix_to_win32_path_list(pc, ptr);
+
+                       string path_list = subst(ptr, '\\', '/');
+                       delete ptr;
+                       return path_list;
+               }
+       }
+
+       return (contains(p, '\\') ? subst(p, '\\', '/') : p);
+}
+
 } // namespace anon
 
 
 string external_path(string const & p)
 {
-       string dos_path;
+       return convert_path(p, cygwin_path_fix_ ? PathStyle(windows)
+                                               : PathStyle(posix));
+}
 
-       // Translate from cygwin path syntax to dos path syntax
-       if (cygwin_path_fix_ && is_absolute_path(p)) {
-               char dp[PATH_MAX];
-               cygwin_conv_to_full_win32_path(p.c_str(), dp);
-               dos_path = !dp ? "" : dp;
-       }
 
-       else return p;
+string internal_path(string const & p, path_target target)
+{
+       return (target == LATEX) ? latex_path(p)
+                                : convert_path(p, PathStyle(posix));
+}
 
-       //No backslashes in LaTeX files
-       dos_path = subst(dos_path,'\\','/');
 
-       lyxerr[Debug::LATEX]
-               << "<Cygwin path correction> ["
-               << p << "]->>["
-               << dos_path << ']' << endl;
-       return dos_path;
+string external_path_list(string const & p)
+{
+       return convert_path_list(p, cygwin_path_fix_ ? PathStyle(windows)
+                                                    : PathStyle(posix));
 }
 
 
-string internal_path(string const & p)
+string internal_path_list(string const & p)
 {
-       char posix_path[PATH_MAX];
-       posix_path[0] = '\0';
-       cygwin_conv_to_posix_path(p.c_str(), posix_path);
-       return posix_path;
+       return convert_path_list(p, PathStyle(posix));
 }
 
 
@@ -107,7 +174,17 @@ string latex_path(string const & p)
        // We may need a posix style path or a windows style path (depending
        // on cygwin_path_fix_), but we use always forward slashes, since it
        // gets written into a .tex file.
-       return external_path(p);
+
+       if (cygwin_path_fix_ && is_absolute_path(p)) {
+               string dos_path = convert_path(p, PathStyle(windows));
+               lyxerr[Debug::LATEX]
+                       << "<Cygwin path correction> ["
+                       << p << "]->>["
+                       << dos_path << ']' << endl;
+               return dos_path;
+       }
+
+       return convert_path(p, PathStyle(posix));
 }
 
 
Index: src/support/environment.C
===================================================================
--- src/support/environment.C   (revision 13547)
+++ src/support/environment.C   (working copy)
@@ -95,7 +95,11 @@ void setEnvPath(string const & name, vec
        for (; it != end; ++it) {
                if (it != begin)
                        ss << separator;
+#if defined(__CYGWIN__) || defined(__CYGWIN32__)
+               ss << os::internal_path(*it);
+#else
                ss << os::external_path(*it);
+#endif
        }
        setEnv(name, ss.str());
 }
Index: src/support/filetools.h
===================================================================
--- src/support/filetools.h     (revision 13547)
+++ src/support/filetools.h     (working copy)
@@ -16,6 +16,9 @@
 #include <utility>
 #include <string>
 
+/// For os::path_target
+#include <support/os.h>
+
 namespace lyx {
 namespace support {
 
@@ -152,7 +155,8 @@ std::string const AddPath(std::string co
  If the extension is empty, any extension is removed from the name.
  */
 std::string const
-ChangeExtension(std::string const & oldname, std::string const & extension);
+ChangeExtension(std::string const & oldname, std::string const & extension,
+               os::path_target target = os::DEFAULT);
 
 /// Remove the extension from \p name
 std::string const removeExtension(std::string const & name);

Reply via email to