Skip to content

Commit 75bd98c

Browse files
authored
Add support for simplified -s list parsing (#13747)
With this change the opening and closing braced are no longer required. `e.g. -s EXPORTED_FUNCTIONS=_foo,_bar` This form is more inline with traditional compiler arguments where lists of C symbols are to be passed.
1 parent e9a8431 commit 75bd98c

File tree

5 files changed

+50
-24
lines changed

5 files changed

+50
-24
lines changed

ChangeLog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ See docs/process.md for more on how version tagging works.
2020

2121
Current Trunk
2222
-------------
23+
- Lists that are passed on the command line can now skip the opening an closing
24+
braces, allowing for simpler, more readable settings. e.g.
25+
`-s EXPORTED_FUNCTIONS=foo,bar`
2326
- Values returned from `sysconf` now more closely match the definitions found in
2427
header files and in upstream musl (#13713).
2528
- `DISABLE_EXCEPTION_CATCHING=2` is now deprecated since it can be inferred from

docs/emcc.txt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,20 @@ Options that are modified or new in *emcc* are listed below:
104104

105105
Note:
106106

107-
For options that are lists, you need quotation marks (") around
108-
the list in most shells (to avoid errors being raised). Two
109-
examples are shown below:
107+
Lists can be specified without or without quotes around each
108+
element and with or without brackets around the list. For
109+
example all the following are equivelent:
110+
111+
-s EXPORTED_FUNCTIONS=foo,bar
112+
-s EXPORTED_FUNCTIONS="foo","bar"
113+
-s EXPORTED_FUNCTIONS=["foo","bar"]
114+
-s EXPORTED_FUNCTIONS=[foo,bar]
115+
116+
Note:
117+
118+
For lists that include brackets or quote, you need quotation
119+
marks (") around the list in most shells (to avoid errors being
120+
raised). Two examples are shown below:
110121

111122
-s RUNTIME_LINKED_LIBS="['liblib.so']"
112123
-s "RUNTIME_LINKED_LIBS=['liblib.so']"

emcc.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -368,19 +368,22 @@ def standardize_setting_change(key, value):
368368
value = open(filename).read()
369369
else:
370370
value = value.replace('\\', '\\\\')
371+
372+
existing = getattr(shared.Settings, user_key, None)
373+
expect_list = type(existing) == list
374+
371375
try:
372-
value = parse_value(value)
376+
value = parse_value(value, expect_list)
373377
except Exception as e:
374378
exit_with_error('a problem occurred in evaluating the content after a "-s", specifically "%s=%s": %s', key, value, str(e))
375379

376380
# Do some basic type checking by comparing to the existing settings.
377381
# Sadly we can't do this generically in the SettingsManager since there are settings
378382
# that so change types internally over time.
379-
existing = getattr(shared.Settings, user_key, None)
380-
if existing is not None:
381-
# We only currently worry about lists vs non-lists.
382-
if (type(existing) == list) != (type(value) == list):
383-
exit_with_error('setting `%s` expects `%s` but got `%s`' % (user_key, type(existing), type(value)))
383+
# We only currently worry about lists vs non-lists.
384+
if expect_list != (type(value) == list):
385+
exit_with_error('setting `%s` expects `%s` but got `%s`' % (user_key, type(existing), type(value)))
386+
384387
setattr(shared.Settings, user_key, value)
385388

386389
if key == 'EXPORTED_FUNCTIONS':
@@ -2570,7 +2573,7 @@ def consume_arg_file():
25702573
logger.warning('--js-opts ignored when using llvm backend')
25712574
consume_arg()
25722575
elif check_arg('--llvm-opts'):
2573-
options.llvm_opts = parse_value(consume_arg())
2576+
options.llvm_opts = parse_value(consume_arg(), expect_list=True)
25742577
elif arg.startswith('-flto'):
25752578
if '=' in arg:
25762579
shared.Settings.LTO = arg.split('=')[1]
@@ -3368,10 +3371,7 @@ def in_directory(root, child):
33683371
return False
33693372

33703373

3371-
def parse_value(text):
3372-
if not text:
3373-
return text
3374-
3374+
def parse_value(text, expect_list):
33753375
# Note that using response files can introduce whitespace, if the file
33763376
# has a newline at the end. For that reason, we rstrip() in relevant
33773377
# places here.
@@ -3418,14 +3418,15 @@ def parse_string_list_members(text):
34183418

34193419
def parse_string_list(text):
34203420
text = text.rstrip()
3421-
if text[-1] != ']':
3422-
exit_with_error('unclosed opened string list. expected final character to be "]" in "%s"' % (text))
3423-
inner = text[1:-1]
3424-
if inner.strip() == "":
3421+
if text and text[0] == '[':
3422+
if text[-1] != ']':
3423+
exit_with_error('unclosed opened string list. expected final character to be "]" in "%s"' % (text))
3424+
text = text[1:-1]
3425+
if text.strip() == "":
34253426
return []
3426-
return parse_string_list_members(inner)
3427+
return parse_string_list_members(text)
34273428

3428-
if text[0] == '[':
3429+
if expect_list or (text and text[0] == '['):
34293430
# if json parsing fails, we fall back to our own parser, which can handle a few
34303431
# simpler syntaxes
34313432
try:

site/source/docs/tools_reference/emcc.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,16 @@ Options that are modified or new in *emcc* are listed below:
9696

9797
.. note:: If no value is specifed it will default to ``1``.
9898

99-
.. note:: For options that are lists, you need quotation marks (") around the list in most shells (to avoid errors being raised). Two examples are shown below:
99+
.. note:: Lists can be specified without or without quotes around each element and with or without brackets around the list. For example all the following are equivelent:
100+
101+
::
102+
103+
-s EXPORTED_FUNCTIONS=foo,bar
104+
-s EXPORTED_FUNCTIONS="foo","bar"
105+
-s EXPORTED_FUNCTIONS=["foo","bar"]
106+
-s EXPORTED_FUNCTIONS=[foo,bar]
107+
108+
.. note:: For lists that include brackets or quote, you need quotation marks (") around the list in most shells (to avoid errors being raised). Two examples are shown below:
100109

101110
::
102111

tests/test_other.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6210,8 +6210,6 @@ def test_dash_s_valid_list(self):
62106210
self.assertNotContained('a problem occurred in evaluating the content after a "-s", specifically', err)
62116211

62126212
def test_dash_s_wrong_type(self):
6213-
err = self.expect_fail([EMCC, test_file('hello_world.cpp'), '-s', 'EXPORTED_FUNCTIONS=foo'])
6214-
self.assertContained("error: setting `EXPORTED_FUNCTIONS` expects `<class 'list'>` but got `<class 'str'>`", err)
62156213
err = self.expect_fail([EMCC, test_file('hello_world.cpp'), '-s', 'EXIT_RUNTIME=[foo,bar]'])
62166214
self.assertContained("error: setting `EXIT_RUNTIME` expects `<class 'int'>` but got `<class 'list'>`", err)
62176215

@@ -7956,7 +7954,7 @@ def test_is_ar(self):
79567954
f.write(b'!<arch>\n')
79577955
self.assertTrue(building.is_ar(fname))
79587956

7959-
def test_emcc_parsing(self):
7957+
def test_dash_s_list_parsing(self):
79607958
create_file('src.c', r'''
79617959
#include <stdio.h>
79627960
void a() { printf("a\n"); }
@@ -7977,6 +7975,10 @@ def test_emcc_parsing(self):
79777975
('EXPORTED_FUNCTIONS=[_a,_b,_c,_d]', ''),
79787976
# No quotes with spaces
79797977
('EXPORTED_FUNCTIONS=[_a, _b, _c, _d]', ''),
7978+
# No brackets needed either
7979+
('EXPORTED_FUNCTIONS=_a,_b,_c,_d', ''),
7980+
# No brackets with spaced
7981+
('EXPORTED_FUNCTIONS=_a, _b, _c, _d', ''),
79807982
# extra space at end - should be ignored
79817983
("EXPORTED_FUNCTIONS=['_a', '_b', '_c', '_d' ]", ''),
79827984
# extra newline in response file - should be ignored

0 commit comments

Comments
 (0)