]> git.lyx.org Git - lyx.git/blob - src/support/Package.cpp
Fix initialisation bug introduced in r21788.
[lyx.git] / src / support / Package.cpp
1 // -*- C++ -*-
2 /**
3  * \file package.C
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Angus Leeming
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "support/Package.h"
15
16 #include "debug.h"
17 #include "gettext.h"
18
19 #include "support/environment.h"
20 #include "support/filetools.h"
21 #include "support/lstrings.h"
22 #include "support/ExceptionMessage.h"
23 #include "support/os.h"
24
25 #if defined (USE_WINDOWS_PACKAGING)
26 # include "support/os_win32.h"
27 #endif
28
29
30 #include <list>
31
32 #if !defined (USE_WINDOWS_PACKAGING) && \
33     !defined (USE_MACOSX_PACKAGING) && \
34     !defined (USE_POSIX_PACKAGING)
35 #error USE_FOO_PACKAGING must be defined for FOO = WINDOWS, MACOSX or POSIX.
36 #endif
37
38 #if defined (USE_MACOSX_PACKAGING)
39 # include <CoreServices/CoreServices.h> // FSFindFolder, FSRefMakePath
40 #endif
41
42 using std::string;
43
44 namespace lyx {
45 namespace support {
46
47 namespace {
48
49 Package package_;
50 bool initialised_ = false;
51
52 } // namespace anon
53
54
55 void init_package(string const & command_line_arg0,
56                   string const & command_line_system_support_dir,
57                   string const & command_line_user_support_dir,
58                   exe_build_dir_to_top_build_dir top_build_dir_location)
59 {
60         // Can do so only once.
61         if (initialised_)
62                 return;
63
64         package_ = Package(command_line_arg0,
65                            command_line_system_support_dir,
66                            command_line_user_support_dir,
67                            top_build_dir_location);
68         initialised_ = true;
69 }
70
71
72 Package const & package()
73 {
74         // Commented out because package().locale_dir() can be called
75         // from the message translation code in Messages.cpp before
76         // init_package() is called. Lars is on the case...
77         // BOOST_ASSERT(initialised_);
78         return package_;
79 }
80
81
82 namespace {
83
84 FileName const abs_path_from_binary_name(string const & exe);
85
86 void buildDirs(FileName const & abs_binary,
87         exe_build_dir_to_top_build_dir top_build_dir_location,
88         FileName &, FileName &);
89
90 FileName const get_document_dir(FileName const & home_dir);
91
92 FileName const get_home_dir();
93
94 FileName const get_locale_dir(FileName const & system_support_dir);
95
96 FileName const get_system_support_dir(FileName const & abs_binary,
97                                     string const & command_line_system_support_dir);
98
99 FileName const get_temp_dir();
100
101 FileName const get_default_user_support_dir(FileName const & home_dir);
102
103 bool userSupportDir(FileName const & default_user_support_dir,
104                      string const & command_line_user_support_dir, FileName & result);
105
106
107 string const & with_version_suffix();
108
109 } // namespace anon
110
111
112 Package::Package(string const & command_line_arg0,
113                  string const & command_line_system_support_dir,
114                  string const & command_line_user_support_dir,
115                  exe_build_dir_to_top_build_dir top_build_dir_location)
116         : explicit_user_support_dir_(false)
117 {
118         home_dir_ = get_home_dir();
119         system_temp_dir_ = get_temp_dir();
120         temp_dir_ = system_temp_dir_;
121         document_dir_ = get_document_dir(home_dir_);
122
123         FileName const abs_binary = abs_path_from_binary_name(command_line_arg0);
124         string const bdir = onlyPath(abs_binary.absFilename());
125         // We may be using libtools
126         if (suffixIs(bdir, ".libs/"))
127                 binary_dir_ = FileName(addPath(bdir, "../"));
128         else
129                 binary_dir_ = FileName(bdir);
130
131         // Is LyX being run in-place from the build tree?
132         buildDirs(abs_binary, top_build_dir_location,
133                 build_support_dir_, system_support_dir_);
134
135         if (build_support_dir_.empty())
136                 system_support_dir_ =
137                         get_system_support_dir(abs_binary,
138                                                command_line_system_support_dir);
139
140         locale_dir_ = get_locale_dir(system_support_dir_);
141
142         FileName const default_user_support_dir =
143                 get_default_user_support_dir(home_dir_);
144
145         explicit_user_support_dir_ = userSupportDir(default_user_support_dir,
146                                      command_line_user_support_dir, user_support_dir_);
147
148         FileName const configure_script(addName(system_support().absFilename(), "configure.py"));
149         configure_command_ = os::python() + ' ' +
150                         quoteName(configure_script.toFilesystemEncoding()) +
151                         with_version_suffix();
152
153         lyxerr[Debug::INIT]
154                 << "<package>\n"
155                 << "\tbinary_dir " << binary_dir().absFilename() << '\n'
156                 << "\tsystem_support " << system_support().absFilename() << '\n'
157                 << "\tbuild_support " << build_support().absFilename() << '\n'
158                 << "\tuser_support " << user_support().absFilename() << '\n'
159                 << "\tlocale_dir " << locale_dir().absFilename() << '\n'
160                 << "\tdocument_dir " << document_dir().absFilename() << '\n'
161                 << "\ttemp_dir " << temp_dir().absFilename() << '\n'
162                 << "\thome_dir " << home_dir().absFilename() << '\n'
163                 << "</package>\n" << std::endl;
164 }
165
166
167 namespace {
168
169 // These next functions contain the stuff that is substituted at
170 // configuration-time.
171 FileName const hardcoded_localedir()
172 {
173         // FIXME UNICODE
174         // The build system needs to make sure that this is in utf8 encoding.
175         return FileName(LYX_ABS_INSTALLED_LOCALEDIR);
176 }
177
178
179 FileName const hardcoded_system_support_dir()
180 {
181         // FIXME UNICODE
182         // The build system needs to make sure that this is in utf8 encoding.
183         return FileName(LYX_ABS_INSTALLED_DATADIR);
184 }
185
186
187 string const & with_version_suffix()
188 {
189         static string const program_suffix = PROGRAM_SUFFIX;
190         static string const with_version_suffix =
191                 " --with-version-suffix=" PROGRAM_SUFFIX;
192         return program_suffix.empty() ? program_suffix : with_version_suffix;
193 }
194
195 } // namespace anon
196
197
198 FileName const & Package::top_srcdir()
199 {
200         // FIXME UNICODE
201         // The build system needs to make sure that this is in utf8 encoding.
202         static FileName const dir(LYX_ABS_TOP_SRCDIR);
203         return dir;
204 }
205
206
207 namespace {
208
209 bool check_command_line_dir(string const & dir,
210                             string const & file,
211                             string const & command_line_switch);
212
213 FileName const extract_env_var_dir(string const & env_var);
214
215 bool check_env_var_dir(FileName const & dir,
216                        string const & env_var);
217
218 bool check_env_var_dir(FileName const & dir,
219                        string const & file,
220                        string const & env_var);
221
222 string const relative_locale_dir();
223
224 string const relative_system_support_dir();
225
226
227 /**
228  * Convert \p name to internal path and strip a trailing slash, since it
229  * comes from user input (commandline or environment).
230  * \p name is encoded in utf8.
231  */
232 string const fix_dir_name(string const & name)
233 {
234         return rtrim(os::internal_path(name), "/");
235 }
236
237
238 FileName buildSupportDir(string const & binary_dir,
239                       exe_build_dir_to_top_build_dir top_build_dir_location)
240 {
241         string indirection;
242         switch (top_build_dir_location) {
243         case top_build_dir_is_one_level_up:
244                 indirection = "../lib";
245                 break;
246         case top_build_dir_is_two_levels_up:
247                 indirection = "../../lib";
248                 break;
249         }
250         return FileName(normalizePath(addPath(binary_dir, indirection)));
251 }
252
253
254 void buildDirs(FileName const & abs_binary,
255   exe_build_dir_to_top_build_dir top_build_dir_location,
256         FileName & build_support_dir, FileName & system_support_dir)
257 {
258         string const check_text = "Checking whether LyX is run in place...";
259
260         // We're looking for "Makefile" in a directory
261         //   binary_dir/../lib
262         // We're also looking for "chkconfig.ltx" in a directory
263         //   top_srcdir()/lib
264         // If both are found, then we're running LyX in-place.
265
266         // Note that the name of the lyx binary may be a symbolic link.
267         // If that is the case, then we follow the links too.
268         FileName binary = abs_binary;
269         while (true) {
270                 // Try and find "lyxrc.defaults".
271                 string binary_dir = onlyPath(binary.absFilename());
272                 // We may be using libtools with static linking.
273                 if (suffixIs(binary_dir, ".libs/"))
274                         binary_dir = addPath(binary_dir, "../");
275                 build_support_dir = buildSupportDir(binary_dir, top_build_dir_location);
276                 if (!fileSearch(build_support_dir.absFilename(), "Makefile").empty()) {
277                         // Try and find "chkconfig.ltx".
278                         system_support_dir =
279                                 FileName(addPath(Package::top_srcdir().absFilename(), "lib"));
280
281                         if (!fileSearch(system_support_dir.absFilename(), "chkconfig.ltx").empty()) {
282                                 lyxerr[Debug::INIT] << check_text << " yes"
283                                                     << std::endl;
284                                 return;
285                         }
286                 }
287
288                 // Check whether binary is a symbolic link.
289                 // If so, resolve it and repeat the exercise.
290                 if (!binary.isSymLink())
291                         break;
292
293                 FileName link;
294                 if (readLink(binary, link)) {
295                         binary = link;
296                 } else {
297                         // Unable to resolve the link.
298                         break;
299                 }
300         }
301
302         lyxerr[Debug::INIT] << check_text << " no" << std::endl;
303         system_support_dir = FileName();
304         build_support_dir = FileName();
305 }
306
307
308 // Specification of document_dir_ may be reset by LyXRC,
309 // but the default is fixed for a given OS.
310 FileName const get_document_dir(FileName const & home_dir)
311 {
312 #if defined (USE_WINDOWS_PACKAGING)
313         (void)home_dir; // Silence warning about unused variable.
314         os::GetFolderPath win32_folder_path;
315         return FileName(win32_folder_path(os::GetFolderPath::PERSONAL));
316 #else // Posix-like.
317         return home_dir;
318 #endif
319 }
320
321
322 // The specification of home_dir_ is fixed for a given OS.
323 // A typical example on Windows: "C:/Documents and Settings/USERNAME"
324 // and on a Posix-like machine: "/home/USERNAME".
325 FileName const get_home_dir()
326 {
327 #if defined (USE_WINDOWS_PACKAGING)
328         string const home_dir = getEnv("USERPROFILE");
329 #else // Posix-like.
330         string const home_dir = getEnv("HOME");
331 #endif
332
333         return FileName(fix_dir_name(home_dir));
334 }
335
336
337 // Several sources are probed to ascertain the locale directory.
338 // The only requirement is that the result is indeed a directory.
339 FileName const get_locale_dir(FileName const & system_support_dir)
340 {
341         // 1. Use the "LYX_LOCALEDIR" environment variable.
342         FileName const path_env = extract_env_var_dir("LYX_LOCALEDIR");
343         if (!path_env.empty() && check_env_var_dir(path_env, "LYX_LOCALEDIR"))
344                 return path_env;
345
346         // 2. Search for system_support_dir / <relative locale dir>
347         // The <relative locale dir> is OS-dependent. (On Unix, it will
348         // be "../locale/".)
349         FileName path(normalizePath(addPath(system_support_dir.absFilename(),
350                                             relative_locale_dir())));
351
352         if (path.exists() && path.isDirectory())
353                 return path;
354
355         // 3. Fall back to the hard-coded LOCALEDIR.
356         path = hardcoded_localedir();
357         if (path.exists() && path.isDirectory())
358                 return path;
359
360         return FileName();
361 }
362
363
364 // Specification of temp_dir_ may be reset by LyXRC,
365 // but the default is fixed for a given OS.
366 FileName const get_temp_dir()
367 {
368 #if defined (USE_WINDOWS_PACKAGING)
369         // Typical example: C:/TEMP/.
370         char path[MAX_PATH];
371         GetTempPath(MAX_PATH, path);
372         return FileName(os::internal_path(to_utf8(from_local8bit(path))));
373 #else // Posix-like.
374         return FileName("/tmp");
375 #endif
376 }
377
378
379 // Extracts the absolute path from the foo of "-sysdir foo" or "-userdir foo"
380 FileName const abs_path_from_command_line(string const & command_line)
381 {
382         if (command_line.empty())
383                 return FileName();
384
385         string const path = fix_dir_name(command_line);
386         return os::is_absolute_path(path) ? FileName(path) : makeAbsPath(path);
387 }
388
389
390 // Does the grunt work for abs_path_from_binary_name()
391 FileName const get_binary_path(string const & exe)
392 {
393 #if defined (USE_WINDOWS_PACKAGING)
394         // The executable may have been invoked either with or
395         // without the .exe extension.
396         // Ensure that it is present.
397         string const as_internal_path = os::internal_path(exe);
398         string const exe_path = suffixIs(as_internal_path, ".exe") ?
399                 as_internal_path : as_internal_path + ".exe";
400 #else
401         string const exe_path = os::internal_path(exe);
402 #endif
403         if (os::is_absolute_path(exe_path))
404                 return FileName(exe_path);
405
406         // Two possibilities present themselves.
407         // 1. The binary is relative to the CWD.
408         FileName const abs_exe_path = makeAbsPath(exe_path);
409         if (abs_exe_path.exists())
410                 return abs_exe_path;
411
412         // 2. exe must be the name of the binary only and it
413         // can be found on the PATH.
414         string const exe_name = onlyFilename(exe_path);
415         if (exe_name != exe_path)
416                 return FileName();
417
418         std::vector<string> const path = getEnvPath("PATH");
419         std::vector<string>::const_iterator it = path.begin();
420         std::vector<string>::const_iterator const end = path.end();
421         for (; it != end; ++it) {
422                 // This will do nothing if *it is already absolute.
423                 string const exe_dir = makeAbsPath(*it).absFilename();
424
425                 FileName const exe_path(addName(exe_dir, exe_name));
426                 if (exe_path.exists())
427                         return exe_path;
428         }
429
430         // Didn't find anything.
431         return FileName();
432 }
433
434
435 // Extracts the absolute path to the binary name received as argv[0].
436 FileName const abs_path_from_binary_name(string const & exe)
437 {
438         FileName const abs_binary = get_binary_path(exe);
439         if (abs_binary.empty()) {
440                 // FIXME UNICODE
441                 throw ExceptionMessage(ErrorException,
442                         _("LyX binary not found"),
443                         bformat(_("Unable to determine the path to the LyX binary from the command line %1$s"),
444                                 from_utf8(exe)));
445         }
446         return abs_binary;
447 }
448
449
450 // A plethora of directories is searched to ascertain the system
451 // lyxdir which is defined as the first directory to contain
452 // "chkconfig.ltx".
453 FileName const
454 get_system_support_dir(FileName const & abs_binary,
455                   string const & command_line_system_support_dir)
456 {
457         string const chkconfig_ltx = "chkconfig.ltx";
458
459         // searched_dirs is used for diagnostic purposes only in the case
460         // that "chkconfig.ltx" is not found.
461         std::list<FileName> searched_dirs;
462
463         // 1. Use the -sysdir command line parameter.
464         FileName path = abs_path_from_command_line(command_line_system_support_dir);
465         if (!path.empty()) {
466                 searched_dirs.push_back(path);
467                 if (check_command_line_dir(path.absFilename(), chkconfig_ltx, "-sysdir"))
468                         return path;
469         }
470
471         // 2. Use the "LYX_DIR_15x" environment variable.
472         path = extract_env_var_dir("LYX_DIR_15x");
473         if (!path.empty()) {
474                 searched_dirs.push_back(path);
475                 if (check_env_var_dir(path, chkconfig_ltx, "LYX_DIR_15x"))
476                         return path;
477         }
478
479         // 3. Search relative to the lyx binary.
480         // We're looking for "chkconfig.ltx" in a directory
481         //   OnlyPath(abs_binary) / <relative dir> / PACKAGE /
482         // PACKAGE is hardcoded in config.h. Eg "lyx" or "lyx-1.3.6cvs".
483         // <relative dir> is OS-dependent; on Unix, it will be "../share/".
484         string const relative_lyxdir = relative_system_support_dir();
485
486         // One subtlety to be aware of. The name of the lyx binary may be
487         // a symbolic link. If that is the case, then we follow the links too.
488         FileName binary = abs_binary;
489         while (true) {
490                 // Try and find "chkconfig.ltx".
491                 string const binary_dir = onlyPath(binary.absFilename());
492
493                 FileName const lyxdir(
494                         normalizePath(addPath(binary_dir, relative_lyxdir)));
495                 searched_dirs.push_back(lyxdir);
496
497                 if (!fileSearch(lyxdir.absFilename(), chkconfig_ltx).empty()) {
498                         // Success! "chkconfig.ltx" has been found.
499                         return lyxdir;
500                 }
501
502                 // Check whether binary is a symbolic link.
503                 // If so, resolve it and repeat the exercise.
504                 if (!binary.isSymLink())
505                         break;
506
507                 FileName link;
508                 if (readLink(binary, link)) {
509                         binary = link;
510                 } else {
511                         // Unable to resolve the link.
512                         break;
513                 }
514         }
515
516         // 4. Repeat the exercise on the directory itself.
517         FileName binary_dir(onlyPath(abs_binary.absFilename()));
518         while (true) {
519                 // This time test whether the directory is a symbolic link
520                 // *before* looking for "chkconfig.ltx".
521                 // (We've looked relative to the original already.)
522                 if (!binary.isSymLink())
523                         break;
524
525                 FileName link;
526                 if (readLink(binary_dir, link)) {
527                         binary_dir = link;
528                 } else {
529                         // Unable to resolve the link.
530                         break;
531                 }
532
533                 // Try and find "chkconfig.ltx".
534                 FileName const lyxdir(
535                         normalizePath(addPath(binary_dir.absFilename(), relative_lyxdir)));
536                 searched_dirs.push_back(lyxdir);
537
538                 if (!fileSearch(lyxdir.absFilename(), chkconfig_ltx).empty()) {
539                         // Success! "chkconfig.ltx" has been found.
540                         return lyxdir;
541                 }
542         }
543
544         // 5. In desparation, try the hard-coded system support dir.
545         path = hardcoded_system_support_dir();
546         if (!fileSearch(path.absFilename(), chkconfig_ltx).empty())
547                 return path;
548
549         // Everything has failed :-(
550         // So inform the user and exit.
551         string searched_dirs_str;
552         typedef std::list<FileName>::const_iterator iterator;
553         iterator const begin = searched_dirs.begin();
554         iterator const end = searched_dirs.end();
555         for (iterator it = begin; it != end; ++it) {
556                 if (it != begin)
557                         searched_dirs_str += "\n\t";
558                 searched_dirs_str += it->absFilename();
559         }
560
561         // FIXME UNICODE
562         throw ExceptionMessage(ErrorException, _("No system directory"),
563                 bformat(_("Unable to determine the system directory "
564                                          "having searched\n"
565                                          "\t%1$s\n"
566                                          "Use the '-sysdir' command line parameter or "
567                                          "set the environment variable LYX_DIR_15x to "
568                                          "the LyX system directory containing the file "
569                                          "`chkconfig.ltx'."),
570                           from_utf8(searched_dirs_str)));
571
572         // Keep the compiler happy.
573         return FileName();
574 }
575
576
577 // Returns the absolute path to the user lyxdir, together with a flag
578 // indicating whether this directory was specified explicitly (as -userdir
579 // or through an environment variable) or whether it was deduced.
580 bool userSupportDir(FileName const & default_user_support_dir,
581         string const & command_line_user_support_dir, FileName & result)
582 {
583         // 1. Use the -userdir command line parameter.
584         result = abs_path_from_command_line(command_line_user_support_dir);
585         if (!result.empty())
586                 return true;
587
588         // 2. Use the LYX_USERDIR_15x environment variable.
589         result = extract_env_var_dir("LYX_USERDIR_15x");
590         if (!result.empty())
591                 return true;
592
593         // 3. Use the OS-dependent default_user_support_dir
594         result = default_user_support_dir;
595         return false;
596 }
597
598
599 // $HOME/.lyx on POSIX but on Win32 it will be something like
600 // "C:/Documents and Settings/USERNAME/Application Data/LyX"
601 FileName const get_default_user_support_dir(FileName const & home_dir)
602 {
603 #if defined (USE_WINDOWS_PACKAGING)
604         (void)home_dir; // Silence warning about unused variable.
605
606         os::GetFolderPath win32_folder_path;
607         return FileName(addPath(win32_folder_path(os::GetFolderPath::APPDATA), PACKAGE));
608
609 #elif defined (USE_MACOSX_PACKAGING)
610         (void)home_dir; // Silence warning about unused variable.
611
612         FSRef fsref;
613         OSErr const error_code =
614                 FSFindFolder(kUserDomain, kApplicationSupportFolderType,
615                              kDontCreateFolder, &fsref);
616         if (error_code != 0)
617                 return FileName();
618
619         // FSRefMakePath returns the result in utf8
620         char store[PATH_MAX + 1];
621         OSStatus const status_code =
622                 FSRefMakePath(&fsref,
623                               reinterpret_cast<UInt8*>(store), PATH_MAX);
624         if (status_code != 0)
625                 return FileName();
626
627         return FileName(addPath(reinterpret_cast<char const *>(store), PACKAGE));
628
629 #else // USE_POSIX_PACKAGING
630         return FileName(addPath(home_dir.absFilename(), string(".") + PACKAGE));
631 #endif
632 }
633
634
635 // Check that directory @c dir contains @c file.
636 // Else emit a warning about an invalid @c command_line_switch.
637 bool check_command_line_dir(string const & dir,
638                             string const & file,
639                             string const & command_line_switch)
640 {
641         FileName const abs_path = fileSearch(dir, file);
642         if (abs_path.empty()) {
643                 // FIXME UNICODE
644                 throw ExceptionMessage(WarningException, _("File not found"), bformat(
645                         _("Invalid %1$s switch.\nDirectory %2$s does not contain %3$s."),
646                         from_utf8(command_line_switch), from_utf8(dir),
647                         from_utf8(file)));
648         }
649
650         return !abs_path.empty();
651 }
652
653
654 // The environment variable @c env_var expands to a (single) file path.
655 FileName const extract_env_var_dir(string const & env_var)
656 {
657         string const dir = fix_dir_name(getEnv(env_var));
658         return dir.empty() ? FileName() : makeAbsPath(dir);
659 }
660
661
662 // Check that directory @c dir contains @c file.
663 // Else emit a warning about an invalid @c env_var.
664 bool check_env_var_dir(FileName const & dir,
665                        string const & file,
666                        string const & env_var)
667 {
668         FileName const abs_path = fileSearch(dir.absFilename(), file);
669         if (abs_path.empty()) {
670                 // FIXME UNICODE
671                 throw ExceptionMessage(WarningException, _("File not found"), bformat(
672                         _("Invalid %1$s environment variable.\n"
673                                 "Directory %2$s does not contain %3$s."),
674                         from_utf8(env_var), from_utf8(dir.absFilename()),
675                         from_utf8(file)));
676         }
677
678         return !abs_path.empty();
679 }
680
681
682 // Check that directory @c dir is indeed a directory.
683 // Else emit a warning about an invalid @c env_var.
684 bool check_env_var_dir(FileName const & dir,
685                        string const & env_var)
686 {
687         bool const success = dir.exists() && dir.isDirectory();
688
689         if (!success) {
690                 // Put this string on a single line so that the gettext
691                 // search mechanism in po/Makefile.in.in will register
692                 // Package.cpp.in as a file containing strings that need
693                 // translation.
694                 // FIXME UNICODE
695                 docstring const fmt =
696                         _("Invalid %1$s environment variable.\n%2$s is not a directory.");
697
698                 throw ExceptionMessage(WarningException, _("Directory not found"), bformat(
699                         fmt, from_utf8(env_var), from_utf8(dir.absFilename())));
700         }
701
702         return success;
703 }
704
705
706 // The locale directory relative to the LyX system directory.
707 string const relative_locale_dir()
708 {
709 #if defined (USE_WINDOWS_PACKAGING) || defined (USE_MACOSX_PACKAGING)
710         return "locale/";
711 #else
712         return "../locale/";
713 #endif
714 }
715
716
717 // The system lyxdir is relative to the directory containing the LyX binary.
718 string const relative_system_support_dir()
719 {
720         string result;
721
722 #if defined (USE_WINDOWS_PACKAGING) || defined (USE_MACOSX_PACKAGING)
723         result = "../Resources/";
724 #else // Posix-like.
725         result = addPath("../share/", PACKAGE);
726 #endif
727
728         return result;
729 }
730
731 } // namespace anon
732
733 } // namespace support
734 } // namespace lyx