]> git.lyx.org Git - lyx.git/blobdiff - src/support/os_unix.cpp
Add default output format for pLaTeX
[lyx.git] / src / support / os_unix.cpp
index 0378e369a3f651ae298ca0163e8e62b412ddf52b..5a6c21fe63e72e98ca31e278e1c56ab3b8ba5d5f 100644 (file)
 
 #include <config.h>
 
+#include "LyXRC.h"
+
 #include "support/os.h"
+#include "support/docstring.h"
+#include "support/environment.h"
+#include "support/FileName.h"
+#include "support/filetools.h"
+#include "support/lstrings.h"
+#include "support/lassert.h"
+
+#include <limits.h>
+#include <locale.h>
+#include <stdlib.h>
 
 #ifdef __APPLE__
-#include "debug.h"
-#include <Carbon/Carbon.h>
-#include <ApplicationServices/ApplicationServices.h>
-using std::endl;
+#include <CoreServices/CoreServices.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFArray.h>
 #endif
 
-using std::string;
-
+using namespace std;
 
 namespace lyx {
 namespace support {
 namespace os {
 
-void init(int, char *[])
+namespace {
+
+int argc_ = 0;
+char ** argv_ = 0;
+
+} // namespace
+
+void init(int argc, char ** argv[])
+{
+       argc_ = argc;
+       argv_ = *argv;
+
+       // Set environment's default locale
+       setlocale(LC_ALL, "");
+       setlocale(LC_NUMERIC, "C");
+}
+
+
+string utf8_argv(int i)
+{
+       LASSERT(i < argc_, return "");
+       return to_utf8(from_local8bit(argv_[i]));
+}
+
+
+void remove_internal_args(int, int)
 {}
 
 
@@ -38,13 +73,28 @@ string current_root()
 }
 
 
+bool isFilesystemCaseSensitive()
+{
+#ifdef __APPLE__
+       return false;
+#else
+       return true;
+#endif
+}
+
+
 docstring::size_type common_path(docstring const & p1, docstring const & p2)
 {
        docstring::size_type i = 0;
        docstring::size_type const p1_len = p1.length();
        docstring::size_type const p2_len = p2.length();
+#ifdef __APPLE__
+       while (i < p1_len && i < p2_len && uppercase(p1[i]) == uppercase(p2[i]))
+               ++i;
+#else
        while (i < p1_len && i < p2_len && p1[i] == p2[i])
                ++i;
+#endif
        if ((i < p1_len && i < p2_len)
            || (i < p1_len && p1[i] != '/' && i == p2_len)
            || (i < p2_len && p2[i] != '/' && i == p1_len))
@@ -58,6 +108,49 @@ docstring::size_type common_path(docstring const & p1, docstring const & p2)
 }
 
 
+bool path_prefix_is(string const & path, string const & pre)
+{
+#ifdef __APPLE__
+       return path_prefix_is(const_cast<string &>(path), pre, CASE_UNCHANGED);
+#else
+       return prefixIs(path, pre);
+#endif
+}
+
+
+bool path_prefix_is(string & path, string const & pre, path_case how)
+{
+#ifdef __APPLE__
+       docstring const p1 = from_utf8(path);
+       docstring const p2 = from_utf8(pre);
+       docstring::size_type const p1_len = p1.length();
+       docstring::size_type const p2_len = p2.length();
+       docstring::size_type common_len = common_path(p1, p2);
+
+       if (p2[p2_len - 1] == '/' && p1_len != p2_len)
+               ++common_len;
+
+       if (common_len != p2_len)
+               return false;
+
+       if (how == CASE_ADJUSTED && !prefixIs(path, pre)) {
+               if (p1_len < common_len)
+                       path = to_utf8(p2.substr(0, p1_len));
+               else
+                       path = to_utf8(p2 + p1.substr(common_len,
+                                                       p1_len - common_len));
+       }
+
+       return true;
+#else
+       // silence compiler warnings
+       (void)how;
+
+       return prefixIs(path, pre);
+#endif
+}
+
+
 string external_path(string const & p)
 {
        return p;
@@ -70,6 +163,12 @@ string internal_path(string const & p)
 }
 
 
+string safe_internal_path(string const & p, file_access)
+{
+       return p;
+}
+
+
 string external_path_list(string const & p)
 {
        return p;
@@ -88,9 +187,26 @@ string latex_path(string const & p)
 }
 
 
-bool is_absolute_path(string const & p)
+string latex_path_list(string const & p)
 {
-       return !p.empty() && p[0] == '/';
+       return p;
+}
+
+
+bool is_valid_strftime(string const & p)
+{
+       string::size_type pos = p.find_first_of('%');
+       while (pos != string::npos) {
+               if (pos + 1 == string::npos)
+                       break;
+               if (!containsOnly(p.substr(pos + 1, 1),
+                       "aAbBcCdDeEFgGhHIjklmMnOpPrRsStTuUVwWxXyYzZ%+"))
+                       return false;
+               if (pos + 2 == string::npos)
+                     break;
+               pos = p.find_first_of('%', pos + 2);
+       }
+       return true;
 }
 
 
@@ -113,7 +229,7 @@ shell_type shell()
 }
 
 
-char path_separator()
+char path_separator(path_type)
 {
        return ':';
 }
@@ -135,7 +251,7 @@ bool canAutoOpenFile(string const & ext, auto_open_mode const mode)
        (void)mode;
        LSRolesMask role = kLSRolesAll;
        FSRef outAppRef;
-       OSStatus status = 
+       OSStatus status =
                LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator,
                                        cfs_ext, role, &outAppRef, NULL);
        CFRelease(cfs_ext);
@@ -153,41 +269,64 @@ bool canAutoOpenFile(string const & ext, auto_open_mode const mode)
 }
 
 
-bool autoOpenFile(string const & filename, auto_open_mode const mode)
+bool autoOpenFile(string const & filename, auto_open_mode const mode,
+                 string const & path)
 {
 #ifdef __APPLE__
 // Reference: http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
-       FSRef fileref;
-       OSStatus status = 
-               FSPathMakeRef((UInt8 *) filename.c_str(), &fileref, NULL);
-       if (status != 0)
-               return false;
-        
        // this is what we would like to do but it seems that the
        // viewer for PDF is often quicktime...
        //LSRolesMask role = (mode == VIEW) ? kLSRolesViewer :  kLSRolesEditor;
        (void)mode;
        LSRolesMask role = kLSRolesAll;
-       FSRef outAppRef;
 
-       status = LSGetApplicationForItem(&fileref, role, &outAppRef, NULL);
+       CFURLRef docURL = CFURLCreateFromFileSystemRepresentation(
+               NULL, (UInt8 *) filename.c_str(), filename.size(), false);
+       CFURLRef appURL;
+       OSStatus status = LSGetApplicationForURL(docURL, role, NULL, &appURL);
        if (status == kLSApplicationNotFoundErr)
                return false;
 
-       LSLaunchFSRefSpec inLaunchSpec;
-       inLaunchSpec.appRef = &outAppRef;
-       inLaunchSpec.numDocs = 1;
-       inLaunchSpec.itemRefs = &fileref;
-       inLaunchSpec.passThruParams = NULL;
-       inLaunchSpec.launchFlags = kLSLaunchDefaults;
-       inLaunchSpec.asyncRefCon = NULL;
-       status = LSOpenFromRefSpec(&inLaunchSpec, NULL);
-
-       return status != kLSApplicationNotFoundErr;     
+       CFURLRef docURLs[] = { docURL };
+       CFArrayRef launchItems = CFArrayCreate(
+               NULL,
+               (const void**)docURLs, sizeof(docURLs) / sizeof(CFURLRef),
+               NULL);
+       LSLaunchURLSpec launchUrlSpec = {
+               appURL, launchItems, NULL, kLSLaunchDefaults, NULL
+       };
+
+       string const texinputs = os::latex_path_list(
+               replaceCurdirPath(path, lyxrc.texinputs_prefix));
+       string const otherinputs = os::latex_path_list(path);
+       string const oldtexinputs = getEnv("TEXINPUTS");
+       string const newtexinputs = ".:" + texinputs + ":" + oldtexinputs;
+       string const oldbibinputs = getEnv("BIBINPUTS");
+       string const newbibinputs = ".:" + otherinputs + ":" + oldbibinputs;
+       string const oldbstinputs = getEnv("BSTINPUTS");
+       string const newbstinputs = ".:" + otherinputs + ":" + oldbstinputs;
+       string const oldtexfonts = getEnv("TEXFONTS");
+       string const newtexfonts = ".:" + otherinputs + ":" + oldtexfonts;
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty()) {
+               setEnv("TEXINPUTS", newtexinputs);
+               setEnv("BIBINPUTS", newbibinputs);
+               setEnv("BSTINPUTS", newbstinputs);
+               setEnv("TEXFONTS", newtexfonts);
+       }
+       status = LSOpenFromURLSpec (&launchUrlSpec, NULL);
+       CFRelease(launchItems);
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty()) {
+               setEnv("TEXINPUTS", oldtexinputs);
+               setEnv("BIBINPUTS", oldbibinputs);
+               setEnv("BSTINPUTS", oldbstinputs);
+               setEnv("TEXFONTS", oldtexfonts);
+       }
+       return status == 0;
 #else
        // silence compiler warnings
        (void)filename;
        (void)mode;
+       (void)path;
 
        // currently, no default viewer is tried for non-windows system
        // support for KDE/Gnome/Macintosh may be added later
@@ -196,41 +335,20 @@ bool autoOpenFile(string const & filename, auto_open_mode const mode)
 }
 
 
-void addFontResources()
+string real_path(string const & path)
 {
-#ifdef __APPLE__
-       CFBundleRef  myAppBundle = CFBundleGetMainBundle();
-       CFURLRef  myAppResourcesURL, FontsURL;
-       FSRef  fontDirRef;
-       FSSpec  fontDirSpec;
-       CFStringRef  filePath = CFStringCreateWithBytes(kCFAllocatorDefault,
-                                       (UInt8 *) "fonts", strlen("fonts"),
-                                       kCFStringEncodingISOLatin1, false);
-
-       myAppResourcesURL = CFBundleCopyResourcesDirectoryURL(myAppBundle);
-       FontsURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
-                       myAppResourcesURL, filePath, true);
-       if (lyxerr.debugging(Debug::FONT)) {
-               UInt8  buf[255];
-               if (CFURLGetFileSystemRepresentation(FontsURL, true, buf, 255))
-                       lyxerr << "Adding Fonts directory: " << buf << endl;
-       }
-       CFURLGetFSRef (FontsURL, &fontDirRef);
-       OSStatus err = FSGetCatalogInfo (&fontDirRef, kFSCatInfoNone,
-                                        NULL, NULL, &fontDirSpec, NULL);
-       if (err)
-               lyxerr << "FSGetCatalogInfo err = " << err << endl;
-       err = FMActivateFonts (&fontDirSpec, NULL, NULL,
-                              kFMLocalActivationContext);
-       if (err)
-               lyxerr << "FMActivateFonts err = " << err << endl;
+#ifdef HAVE_DEF_PATH_MAX
+       char rpath[PATH_MAX + 1];
+       char * result = realpath(path.c_str(), rpath);
+       return FileName::fromFilesystemEncoding(result ? rpath : path).absFileName();
+#else
+       char * result = realpath(path.c_str(), NULL);
+       string ret = FileName::fromFilesystemEncoding(result ? result : path).absFileName();
+       free(result);
+       return ret;
 #endif
 }
 
-
-void restoreFontResources()
-{}
-
 } // namespace os
 } // namespace support
 } // namespace lyx