Skip to content

Commit 0b76416

Browse files
authored
fix: properly parse all types of command line arg values (#103)
* fix: properly parse all types of command line arg values * refactor: adjust code line in doc comments * refactor: add cmdline arg fixing wrapper function * fix: also cover args without =
1 parent 47b75e2 commit 0b76416

File tree

1 file changed

+63
-8
lines changed

1 file changed

+63
-8
lines changed

addons/mod_loader/mod_loader_utils.gd

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,25 +188,80 @@ static func _get_verbosity() -> int:
188188
# Check if the provided command line argument was present when launching the game
189189
static func is_running_with_command_line_arg(argument: String) -> bool:
190190
for arg in OS.get_cmdline_args():
191-
if arg == argument:
191+
if argument == arg.split("=")[0]:
192192
return true
193193

194194
return false
195195

196196

197197
# Get the command line argument value if present when launching the game
198198
static func get_cmd_line_arg_value(argument: String) -> String:
199-
for arg in OS.get_cmdline_args():
200-
if (arg as String).find("=") > -1:
201-
var key_value := (arg as String).split("=")
202-
# True if the checked argument matches a user-specified arg key
203-
# (eg. checking `--mods-path` will match with `--mods-path="C://mods"`
204-
if key_value[0] == argument:
205-
return key_value[1]
199+
var args := get_fixed_cmdline_args()
200+
201+
for arg_index in args.size():
202+
var arg := args[arg_index] as String
203+
204+
var key := arg.split("=")[0]
205+
if key == argument:
206+
# format: `--arg=value` or `--arg="value"`
207+
if "=" in arg:
208+
var value := arg.trim_prefix(argument + "=")
209+
value = value.trim_prefix('"').trim_suffix('"')
210+
value = value.trim_prefix("'").trim_suffix("'")
211+
return value
212+
213+
# format: `--arg value` or `--arg "value"`
214+
elif arg_index +1 < args.size() and not args[arg_index +1].begins_with("--"):
215+
return args[arg_index + 1]
206216

207217
return ""
208218

209219

220+
static func get_fixed_cmdline_args() -> PoolStringArray:
221+
return fix_godot_cmdline_args_string_space_splitting(OS.get_cmdline_args())
222+
223+
224+
# Reverses a bug in Godot, which splits input strings at spaces even if they are quoted
225+
# e.g. `--arg="some value" --arg-two 'more value'` becomes `[ --arg="some, value", --arg-two, 'more, value' ]`
226+
static func fix_godot_cmdline_args_string_space_splitting(args: PoolStringArray) -> PoolStringArray:
227+
if not OS.has_feature("editor"): # only happens in editor builds
228+
return args
229+
if OS.has_feature("Windows"): # windows is unaffected
230+
return args
231+
232+
var fixed_args := PoolStringArray([])
233+
var fixed_arg := ""
234+
# if we encounter an argument that contains `=` followed by a quote,
235+
# or an argument that starts with a quote, take all following args and
236+
# concatenate them into one, until we find the closing quote
237+
for arg in args:
238+
var arg_string := arg as String
239+
if '="' in arg_string or '="' in fixed_arg or \
240+
arg_string.begins_with('"') or fixed_arg.begins_with('"'):
241+
if not fixed_arg == "":
242+
fixed_arg += " "
243+
fixed_arg += arg_string
244+
if arg_string.ends_with('"'):
245+
fixed_args.append(fixed_arg.trim_prefix(" "))
246+
fixed_arg = ""
247+
continue
248+
# same thing for single quotes
249+
elif "='" in arg_string or "='" in fixed_arg \
250+
or arg_string.begins_with("'") or fixed_arg.begins_with("'"):
251+
if not fixed_arg == "":
252+
fixed_arg += " "
253+
fixed_arg += arg_string
254+
if arg_string.ends_with("'"):
255+
fixed_args.append(fixed_arg.trim_prefix(" "))
256+
fixed_arg = ""
257+
continue
258+
259+
else:
260+
fixed_args.append(arg_string)
261+
262+
return fixed_args
263+
264+
210265
# Returns the current time as a string in the format hh:mm:ss
211266
static func get_time_string() -> String:
212267
var date_time = Time.get_datetime_dict_from_system()

0 commit comments

Comments
 (0)