Skip to content

Commit aa64903

Browse files
committed
feat: canonicalize script paths to Unicode paths
Script paths are now Unicode and canonicalized to remove any extraneous "./" and "../" segments, resolving the full path, these typically arise from how the program is lauched during development. Most API functions that use these are updated to use the new path types.
1 parent 6603d7c commit aa64903

File tree

6 files changed

+45
-59
lines changed

6 files changed

+45
-59
lines changed

engine/system/sys_main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ class sys_IMain {
7272
virtual bool IsKeyDown(byte key) = 0;
7373
virtual void ClipboardCopy(const char* str) = 0;
7474
virtual char* ClipboardPaste() = 0;
75-
virtual bool SetWorkDir(const char* newCwd = NULL) = 0;
7675
virtual void SpawnProcess(const char* cmdName, const char* argList) = 0;
76+
virtual bool SetWorkDir(std::filesystem::path const& newCwd = {}) = 0;
7777
virtual void OpenURL(const char* url) = 0;
7878
virtual void Error(const char* fmt, ...) = 0;
7979
virtual void Exit(const char* msg = NULL) = 0;

engine/system/win/sys_local.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class sys_main_c: public sys_IMain {
3535
bool IsKeyDown(byte key);
3636
void ClipboardCopy(const char* str);
3737
char* ClipboardPaste();
38-
bool SetWorkDir(const char* newCwd = NULL);
3938
void SpawnProcess(const char* cmdName, const char* argList);
39+
bool SetWorkDir(std::filesystem::path const& newCwd = {});
4040
void OpenURL(const char* url);
4141
void Error(const char* fmt, ...);
4242
void Exit(const char* msg = NULL);

engine/system/win/sys_main.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ char* sys_main_c::ClipboardPaste()
380380
return AllocString(glfwGetClipboardString(nullptr));
381381
}
382382

383-
bool sys_main_c::SetWorkDir(const char* newCwd)
383+
bool sys_main_c::SetWorkDir(std::filesystem::path const& newCwd)
384384
{
385385
#ifdef _WIN32
386386
auto changeDir = [](std::filesystem::path const& p) {
@@ -391,10 +391,10 @@ bool sys_main_c::SetWorkDir(const char* newCwd)
391391
return _chdir(p.c_str());
392392
};
393393
#endif
394-
if (newCwd) {
395-
return changeDir(newCwd) != 0;
394+
if (newCwd.empty()) {
395+
return changeDir(basePath) != 0;
396396
} else {
397-
return changeDir(basePath.c_str()) != 0;
397+
return changeDir(newCwd) != 0;
398398
}
399399
}
400400

ui_api.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,7 +1611,7 @@ static int l_GetTime(lua_State* L)
16111611
static int l_GetScriptPath(lua_State* L)
16121612
{
16131613
ui_main_c* ui = GetUIPtr(L);
1614-
lua_pushstring(L, ui->scriptPath);
1614+
lua_pushstring(L, ui->scriptPath.u8string().c_str());
16151615
return 1;
16161616
}
16171617

@@ -1702,27 +1702,25 @@ static int l_RenameFile(lua_State* L)
17021702

17031703
return luaL_fileresult(L, rc == 0, srcStr);
17041704
}
1705-
1706-
static int l_SetWorkDir(lua_State* L)
1705+
SG_LUA_CPP_FUN_BEGIN(SetWorkDir)
17071706
{
17081707
ui_main_c* ui = GetUIPtr(L);
17091708
int n = lua_gettop(L);
1710-
ui->LAssert(L, n >= 1, "Usage: SetWorkDir(path)");
1711-
ui->LAssert(L, lua_isstring(L, 1), "SetWorkDir() argument 1: expected string, got %s", luaL_typename(L, 1));
1712-
const char* newWorkDir = lua_tostring(L, 1);
1709+
ui->LExpect(L, n >= 1, "Usage: SetWorkDir(path)");
1710+
ui->LExpect(L, lua_isstring(L, 1), "SetWorkDir() argument 1: expected string, got %s", luaL_typename(L, 1));
1711+
auto newWorkDir = std::filesystem::u8path(lua_tostring(L, 1));
1712+
17131713
if (!ui->sys->SetWorkDir(newWorkDir)) {
1714-
if (ui->scriptWorkDir) {
1715-
FreeString(ui->scriptWorkDir);
1716-
}
1717-
ui->scriptWorkDir = AllocString(newWorkDir);
1714+
ui->scriptWorkDir = newWorkDir;
17181715
}
17191716
return 0;
17201717
}
1718+
SG_LUA_CPP_FUN_END()
17211719

17221720
static int l_GetWorkDir(lua_State* L)
17231721
{
17241722
ui_main_c* ui = GetUIPtr(L);
1725-
lua_pushstring(L, ui->scriptWorkDir);
1723+
lua_pushstring(L, ui->scriptWorkDir.u8string().c_str());
17261724
return 1;
17271725
}
17281726

ui_main.cpp

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,17 @@ void ui_main_c::PCall(int narg, int nret)
152152
inLua = true;
153153
int err = lua_pcall(L, narg, nret, 1);
154154
inLua = false;
155-
sys->SetWorkDir(NULL);
155+
sys->SetWorkDir();
156156
if (err && !didExit) {
157157
DoError("Runtime error in", lua_tostring(L, -1));
158158
}
159159
}
160160

161161
void ui_main_c::DoError(const char* msg, const char* error)
162162
{
163-
char* errText = AllocStringLen(strlen(msg) + strlen(scriptName) + strlen(error) + 30);
164-
sprintf(errText, "--- SCRIPT ERROR ---\n%s '%s':\n%s\n", msg, scriptName, error);
163+
auto scriptStr = scriptName.u8string();
164+
char* errText = AllocStringLen(strlen(msg) + scriptStr.size() + strlen(error) + 30);
165+
sprintf(errText, "--- SCRIPT ERROR ---\n%s '%s':\n%s\n", msg, scriptStr.c_str(), error);
165166
sys->Exit(errText);
166167
FreeString(errText);
167168
didExit = true;
@@ -203,29 +204,19 @@ static int l_panicFunc(lua_State* L)
203204
void ui_main_c::Init(int argc, char** argv)
204205
{
205206
// Find paths
206-
scriptName = AllocString(argv[0]);
207-
scriptCfg = AllocStringLen(strlen(scriptName) + 4);
208-
strcpy(scriptCfg, scriptName);
209-
char* ext = strrchr(scriptCfg, '.');
210-
if (ext) {
211-
strcpy(ext, ".cfg");
212-
} else {
213-
strcat(scriptCfg, ".cfg");
214-
}
215-
char tmpDir[512];
216-
strcpy(tmpDir, scriptName);
217-
char* ls = strrchr(tmpDir, '\\');
218-
if ( !ls ) {
219-
ls = strrchr(tmpDir, '/');
220-
}
221-
if (ls) {
222-
*ls = 0;
223-
scriptPath = AllocString(tmpDir);
224-
scriptWorkDir = AllocString(tmpDir);
225-
} else {
226-
scriptPath = AllocString(sys->basePath.u8string().c_str());
227-
scriptWorkDir = AllocString(sys->basePath.u8string().c_str());
207+
scriptName = std::filesystem::u8path(argv[0]);
208+
if (scriptName.is_relative()) {
209+
scriptName = sys->basePath / scriptName;
228210
}
211+
scriptName = canonical(scriptName);
212+
213+
scriptCfg = scriptName;
214+
scriptCfg.replace_extension(".cfg");
215+
216+
auto scriptParent = scriptName.parent_path();
217+
scriptPath = scriptParent;
218+
scriptWorkDir = scriptParent;
219+
229220
scriptArgc = argc;
230221
scriptArgv = new char*[argc];
231222
for (int a = 0; a < argc; a++) {
@@ -236,8 +227,7 @@ void ui_main_c::Init(int argc, char** argv)
236227
core->config->LoadConfig("SimpleGraphic/SimpleGraphic.cfg");
237228
core->config->LoadConfig("SimpleGraphic/SimpleGraphicAuto.cfg");
238229
if (core->config->LoadConfig(scriptCfg)) {
239-
FreeString(scriptCfg);
240-
scriptCfg = NULL;
230+
scriptCfg.clear();
241231
}
242232

243233
// Initialise script
@@ -254,7 +244,7 @@ void ui_main_c::RenderInit(r_featureFlag_e features)
254244
return;
255245
}
256246

257-
sys->SetWorkDir(NULL);
247+
sys->SetWorkDir();
258248

259249
sys->con->ExecCommands(true);
260250

@@ -276,11 +266,11 @@ void ui_main_c::ScriptInit()
276266
{
277267
sys->con->PrintFunc("UI Init");
278268

279-
sys->con->Printf("Script: %s\n", scriptName);
280-
if (scriptPath) {
281-
sys->con->Printf("Script working directory: %s\n", scriptWorkDir);
269+
sys->con->Printf("Script: %s\n", scriptName.u8string().c_str());
270+
if (!scriptPath.empty()) {
271+
sys->con->Printf("Script working directory: %s\n", scriptWorkDir.u8string().c_str());
282272
}
283-
sys->video->SetTitle(scriptName);
273+
sys->video->SetTitle(scriptName.u8string().c_str());
284274

285275
restartFlag = false;
286276
didExit = false;
@@ -322,11 +312,13 @@ void ui_main_c::ScriptInit()
322312
}
323313

324314
// Load the script file
325-
err = luaL_loadfile(L, scriptName);
315+
sys->SetWorkDir(scriptWorkDir);
316+
err = luaL_loadfile(L, scriptName.filename().u8string().c_str());
326317
if (err) {
327318
DoError("Error loading", lua_tostring(L, -1));
328319
return;
329320
}
321+
sys->SetWorkDir();
330322

331323
// Run the script
332324
sys->con->Printf("Running script...\n");
@@ -467,16 +459,12 @@ void ui_main_c::Shutdown()
467459
}
468460

469461
// Save config
470-
if (scriptCfg) {
462+
if (!scriptCfg.empty()) {
471463
core->config->SaveConfig(scriptCfg);
472464
} else {
473465
core->config->SaveConfig("SimpleGraphic/SimpleGraphic.cfg");
474466
}
475467

476-
FreeString(scriptName);
477-
FreeString(scriptCfg);
478-
FreeString(scriptPath);
479-
FreeString(scriptWorkDir);
480468
for (int a = 0; a < scriptArgc; a++) {
481469
FreeString(scriptArgv[a]);
482470
}

ui_main.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ class ui_main_c: public ui_IMain {
3636

3737
std::optional<sol::state> solState;
3838
lua_State* L = nullptr;
39-
char* scriptName = nullptr;
40-
char* scriptCfg = nullptr;
41-
char* scriptPath = nullptr;
42-
char* scriptWorkDir = nullptr;
39+
std::filesystem::path scriptName;
40+
std::filesystem::path scriptCfg;
41+
std::filesystem::path scriptPath;
42+
std::filesystem::path scriptWorkDir;
4343
int scriptArgc = 0;
4444
char** scriptArgv = nullptr;
4545
bool restartFlag = false;

0 commit comments

Comments
 (0)