summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-12-02 22:40:43 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2018-12-04 23:44:17 +0200
commit58b838a80bfe1d3307e730c293ce91cb93b332c9 (patch)
treed4a385b084b63872a0768a0f439a4ab9bc794932
parentc17a80f47b772d759aeb0878aa767a768a6fdd0c (diff)
downloadmeson-58b838a80bfe1d3307e730c293ce91cb93b332c9.tar.gz
Can specify keyword arguments with a dict.
-rw-r--r--docs/markdown/Syntax.md42
-rw-r--r--docs/markdown/snippets/kwargdict.md28
-rw-r--r--mesonbuild/interpreterbase.py16
-rw-r--r--test cases/common/208 kwarg entry/inc/prog.h3
-rw-r--r--test cases/common/208 kwarg entry/installed_files.txt2
-rw-r--r--test cases/common/208 kwarg entry/meson.build7
-rw-r--r--test cases/common/208 kwarg entry/prog.c7
-rw-r--r--test cases/failing/91 kwarg dupe/meson.build6
-rw-r--r--test cases/failing/91 kwarg dupe/prog.c6
9 files changed, 113 insertions, 4 deletions
diff --git a/docs/markdown/Syntax.md b/docs/markdown/Syntax.md
index 22b8be35e..9ea96c1d9 100644
--- a/docs/markdown/Syntax.md
+++ b/docs/markdown/Syntax.md
@@ -138,9 +138,9 @@ int main (int argc, char ** argv) {
}'''
```
-These are raw strings that do not support the escape sequences listed above.
-These strings can also be combined with the string formatting functionality
-described below.
+These are raw strings that do not support the escape sequences listed
+above. These strings can also be combined with the string formatting
+functionality described below.
#### String formatting
@@ -351,6 +351,42 @@ creating build objects.
executable('progname', 'prog.c')
```
+Most functions take only few positional arguments but several keyword
+arguments, which are specified like this:
+
+```meson
+executable('progname',
+ sources: 'prog.c',
+ c_args: '-DFOO=1')
+```
+
+Starting with version 0.49.0 keyword arguments can be specified
+dynamically. This is done by passing dictionary representing the
+keywords to set in the `kwargs` keyword. The previous example would be
+specified like this:
+
+```meson
+d = {'sources': 'prog.c',
+ 'c_args': '-DFOO=1'}
+
+executable('progname',
+ kwargs: d)
+```
+
+A single function can take keyword argumets both directly in the
+function call and indirectly via the `kwargs` keyword argument. The
+only limitation is that it is a hard error to pass any particular key
+both as a direct and indirect argument.
+
+```meson
+d = {'c_args': '-DFOO'}
+executable('progname', 'prog.c',
+ c_args: '-DBAZ=1',
+ kwargs: d) # This is an error!
+```
+
+Attempting to do this causes Meson to immediately exit with an error.
+
Method calls
--
diff --git a/docs/markdown/snippets/kwargdict.md b/docs/markdown/snippets/kwargdict.md
new file mode 100644
index 000000000..47c54d56e
--- /dev/null
+++ b/docs/markdown/snippets/kwargdict.md
@@ -0,0 +1,28 @@
+## Can specify keyword arguments with a dictionary
+
+You can now specify keyword arguments for any function and method call
+with the `kwargs` keyword argument. This is perhaps best described
+with an example.
+
+```meson
+options = {'include_directories': include_directories('inc')}
+
+...
+
+executable(...
+ kwargs: options)
+```
+
+The above code is identical to this:
+
+```meson
+executable(...
+ include_directories: include_directories('inc'))
+```
+
+That is, Mesn will expand the dictionary given to `kwargs` as if the
+entries in it had been given as keyword arguments directly.
+
+Note that any individual argument can be specified either directly or
+with the `kwarg`` dict but not both. If a key is specified twice, it
+is a hard error.
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index 66e9dd67e..159459436 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -749,6 +749,7 @@ The result of this is undefined and will become a hard error in a future Meson r
except IndexError:
raise InterpreterException('Index %d out of bounds of array of size %d.' % (index, len(iobject)))
+
def function_call(self, node):
func_name = node.func_name
(posargs, kwargs) = self.reduce_arguments(node.args)
@@ -990,7 +991,20 @@ The result of this is undefined and will become a hard error in a future Meson r
a = args.kwargs[key]
reduced_kw[key] = self.evaluate_statement(a)
self.argument_depth -= 1
- return reduced_pos, reduced_kw
+ final_kw = self.expand_default_kwargs(reduced_kw)
+ return reduced_pos, final_kw
+
+ def expand_default_kwargs(self, kwargs):
+ if 'kwargs' not in kwargs:
+ return kwargs
+ to_expand = kwargs.pop('kwargs')
+ if not isinstance(to_expand, dict):
+ raise InterpreterException('Value of "kwarg" must be dictionary.')
+ for k, v in to_expand.items():
+ if k in kwargs:
+ raise InterpreterException('Entry "{}" defined both as a keyword argument and in a "kwarg" entry.'.format(k))
+ kwargs[k] = v
+ return kwargs
def assignment(self, node):
assert(isinstance(node, mparser.AssignmentNode))
diff --git a/test cases/common/208 kwarg entry/inc/prog.h b/test cases/common/208 kwarg entry/inc/prog.h
new file mode 100644
index 000000000..665521dee
--- /dev/null
+++ b/test cases/common/208 kwarg entry/inc/prog.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define MESSAGE "Hello there.\n"
diff --git a/test cases/common/208 kwarg entry/installed_files.txt b/test cases/common/208 kwarg entry/installed_files.txt
new file mode 100644
index 000000000..5e796b0df
--- /dev/null
+++ b/test cases/common/208 kwarg entry/installed_files.txt
@@ -0,0 +1,2 @@
+usr/bin/prog?exe
+?msvc:usr/bin/prog.pdb
diff --git a/test cases/common/208 kwarg entry/meson.build b/test cases/common/208 kwarg entry/meson.build
new file mode 100644
index 000000000..564ec37fc
--- /dev/null
+++ b/test cases/common/208 kwarg entry/meson.build
@@ -0,0 +1,7 @@
+project('kwarg', 'c')
+
+default_kwargs = {'install': true,
+ 'include_directories': include_directories('inc')}
+
+executable('prog', 'prog.c',
+ kwargs: default_kwargs)
diff --git a/test cases/common/208 kwarg entry/prog.c b/test cases/common/208 kwarg entry/prog.c
new file mode 100644
index 000000000..0c57f661e
--- /dev/null
+++ b/test cases/common/208 kwarg entry/prog.c
@@ -0,0 +1,7 @@
+#include<prog.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf(MESSAGE);
+ return 0;
+}
diff --git a/test cases/failing/91 kwarg dupe/meson.build b/test cases/failing/91 kwarg dupe/meson.build
new file mode 100644
index 000000000..06821a278
--- /dev/null
+++ b/test cases/failing/91 kwarg dupe/meson.build
@@ -0,0 +1,6 @@
+project('dupe kwarg', 'c')
+
+dupedict = {'install': true}
+
+executable('prog', 'prog.c', install: true,
+ kwargs: dupedict)
diff --git a/test cases/failing/91 kwarg dupe/prog.c b/test cases/failing/91 kwarg dupe/prog.c
new file mode 100644
index 000000000..5f3fbe6a2
--- /dev/null
+++ b/test cases/failing/91 kwarg dupe/prog.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("I don't get built. It makes me saaaaaad. :(\n");
+ return 0;
+}