152 satır
3.4 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #if defined HAVE_UNISTD_H
  14. # include <unistd.h>
  15. #endif
  16. #ifdef _WIN32
  17. # define WIN32_LEAN_AND_MEAN
  18. # include <direct.h>
  19. #endif
  20. #include "core.h"
  21. namespace lol
  22. {
  23. namespace System
  24. {
  25. #if defined _WIN32
  26. # define SEPARATOR '\\'
  27. #else
  28. # define SEPARATOR '/'
  29. #endif
  30. static Array<String> data_dir;
  31. void Init(int argc, char *argv[],
  32. String const &projectdir,
  33. String const &solutiondir,
  34. String const &sourcesubdir)
  35. {
  36. using namespace std;
  37. /*
  38. * Retrieve binary directory, defaulting to current dir.
  39. */
  40. #if defined HAVE_GETCWD
  41. char *cwd = getcwd(nullptr, 0);
  42. #elif defined HAVE__GETCWD || (defined _WIN32 && !defined _XBOX)
  43. char *cwd = _getcwd(nullptr, 0);
  44. #else
  45. char *cwd = nullptr;
  46. #endif
  47. String binarydir = String(cwd ? cwd : ".") + SEPARATOR;
  48. free(cwd);
  49. if (argc > 0)
  50. {
  51. char const *last_sep = strrchr(argv[0], SEPARATOR);
  52. if (last_sep)
  53. binarydir = String(argv[0], last_sep - argv[0] + 1);
  54. }
  55. /*
  56. * Find the common prefix between project dir and solution dir.
  57. */
  58. bool got_rootdir = false;
  59. for (int i = 0; ; i++)
  60. {
  61. if (projectdir[i] != solutiondir[i] || projectdir[i] == '\0')
  62. {
  63. /* FIXME: at this point we should check whether the binary
  64. * was launched from this subdirectory; from now we just
  65. * assume it was. */
  66. if (i)
  67. {
  68. String rootdir = solutiondir;
  69. if (rootdir.Last() != SEPARATOR)
  70. rootdir += SEPARATOR;
  71. rootdir += "../../src/"; /* FIXME: use SEPARATOR? */
  72. AddDataDir(rootdir);
  73. rootdir = projectdir;
  74. if (rootdir.Last() != SEPARATOR)
  75. rootdir += SEPARATOR;
  76. AddDataDir(rootdir);
  77. got_rootdir = true;
  78. }
  79. break;
  80. }
  81. }
  82. /* If no rootdir found, use the executable location */
  83. if (!got_rootdir)
  84. {
  85. String rootdir = binarydir;
  86. if (rootdir.Last() != SEPARATOR)
  87. rootdir += SEPARATOR;
  88. for (int i = 1; i < sourcesubdir.Count(); ++i)
  89. {
  90. if ((sourcesubdir[i] == SEPARATOR
  91. && sourcesubdir[i - 1] != SEPARATOR)
  92. || i == sourcesubdir.Count() - 1)
  93. rootdir += "../";
  94. }
  95. rootdir += "src/";
  96. AddDataDir(rootdir);
  97. rootdir = binarydir;
  98. AddDataDir(rootdir);
  99. got_rootdir = true;
  100. }
  101. Log::Debug("binary dir: %s\n", binarydir.C());
  102. for (int i = 0; i < data_dir.Count(); ++i)
  103. Log::Debug("data dir %d/%d: %s\n", i + 1, data_dir.Count(),
  104. data_dir[i].C());
  105. }
  106. /*
  107. * Data directory handling
  108. */
  109. void AddDataDir(String const &dir)
  110. {
  111. data_dir << dir;
  112. }
  113. Array<String> GetPathList(String const &file)
  114. {
  115. Array<String> ret;
  116. for (int i = 0; i < data_dir.Count(); ++i)
  117. ret << data_dir[i] + file;
  118. if (ret.Count() == 0)
  119. ret << file;
  120. return ret;
  121. }
  122. } /* namespace System */
  123. } /* namespace lol */