Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64158 - in trunk/tools/build/v2: build engine/src util
From: ghost_at_[hidden]
Date: 2010-07-19 09:20:53


Author: vladimir_prus
Date: 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
New Revision: 64158
URL: http://svn.boost.org/trac/boost/changeset/64158

Log:
Implemented a mechanism for parameter translation from bjam to python
signatures.

This allows to expose the same interface to Jamfiles as before, e.g.

     rule toolset.flags ( rule variable condition * : values * )

and use natural interface in the Python side, where, 'rule', 'variable',
'condition' and 'values' are parameters, and the first two of them
will get string, not list of strings.

Text files modified:
   trunk/tools/build/v2/build/feature.py | 3 +
   trunk/tools/build/v2/build/project.py | 6 ++-
   trunk/tools/build/v2/build/toolset.py | 6 ++-
   trunk/tools/build/v2/engine/src/builtins.c | 28 ++++++++++++++++--
   trunk/tools/build/v2/engine/src/compile.c | 59 +++++++++++++++++++++++++++++++--------
   trunk/tools/build/v2/engine/src/lists.c | 34 +++++++++++++++++++++++
   trunk/tools/build/v2/engine/src/lists.h | 11 +++++++
   trunk/tools/build/v2/engine/src/rules.c | 1
   trunk/tools/build/v2/engine/src/rules.h | 1
   trunk/tools/build/v2/util/__init__.py | 8 +++++
   10 files changed, 136 insertions(+), 21 deletions(-)

Modified: trunk/tools/build/v2/build/feature.py
==============================================================================
--- trunk/tools/build/v2/build/feature.py (original)
+++ trunk/tools/build/v2/build/feature.py 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -14,7 +14,7 @@
 
 import re
 
-from b2.util import set, utility
+from b2.util import set, utility, bjam_signature
 from b2.util.utility import add_grist, get_grist, ungrist, replace_grist, to_seq
 from b2.exceptions import *
 
@@ -83,6 +83,7 @@
 
 # FIXME: prepare-test/finish-test?
 
+@bjam_signature((["name"], ["values", "*"], ["attributes", "*"]))
 def feature (name, values, attributes = []):
     """ Declares a new feature with the given name, values, and attributes.
         name: the feature name

Modified: trunk/tools/build/v2/build/project.py
==============================================================================
--- trunk/tools/build/v2/build/project.py (original)
+++ trunk/tools/build/v2/build/project.py 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -978,7 +978,6 @@
                 "Tool module '%s' does not define the 'init' method" % toolset[0])
         m.init(*args)
 
-
     def import_(self, name, names_to_import=None, local_names=None):
 
         name = name[0]
@@ -991,7 +990,10 @@
         for f in m.__dict__:
             v = m.__dict__[f]
             if callable(v):
- bjam.import_rule(jamfile_module, name + "." + f, v)
+ if hasattr(v, "bjam_signature"):
+ bjam.import_rule(jamfile_module, name + "." + f, v, v.bjam_signature)
+ else:
+ bjam.import_rule(jamfile_module, name + "." + f, v)
 
         if names_to_import:
             if not local_names:

Modified: trunk/tools/build/v2/build/toolset.py
==============================================================================
--- trunk/tools/build/v2/build/toolset.py (original)
+++ trunk/tools/build/v2/build/toolset.py 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -12,7 +12,7 @@
 
 import feature, property, generators, property_set
 from b2.util.utility import *
-from b2.util import set
+from b2.util import set, bjam_signature
 
 __re_split_last_segment = re.compile (r'^(.+)\.([^\.])*')
 __re_two_ampersands = re.compile ('(&&)')
@@ -87,7 +87,9 @@
 # FIXME push-checking-for-flags-module ....
 # FIXME: investigate existing uses of 'hack-hack' parameter
 # in jam code.
-
+
+@bjam_signature((["rule_or_module", "variable_name", "condition", "*"],
+ ["values", "*"]))
 def flags (rule_or_module, variable_name, condition, values = []):
     """ Specifies the flags (variables) that must be set on targets under certain
         conditions, described by arguments.

Modified: trunk/tools/build/v2/engine/src/builtins.c
==============================================================================
--- trunk/tools/build/v2/engine/src/builtins.c (original)
+++ trunk/tools/build/v2/engine/src/builtins.c 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -1902,8 +1902,12 @@
 
 
 /*
- * Accepts three arguments: module name, rule name and Python callable. Creates
- * a bjam rule with the specified name in the specified module, which will
+ * Accepts four arguments:
+ * - module name
+ * - rule name,
+ * - Python callable.
+ * - (optional) bjam language function signature.
+ * Creates a bjam rule with the specified name in the specified module, which will
  * invoke the Python callable.
  */
 
@@ -1912,10 +1916,12 @@
     char * module;
     char * rule;
     PyObject * func;
+ PyObject * bjam_signature = NULL;
     module_t * m;
     RULE * r;
 
- if ( !PyArg_ParseTuple( args, "ssO:import_rule", &module, &rule, &func ) )
+ if ( !PyArg_ParseTuple( args, "ssO|O:import_rule",
+ &module, &rule, &func, &bjam_signature ) )
         return NULL;
 
     if ( !PyCallable_Check( func ) )
@@ -1932,6 +1938,22 @@
     Py_INCREF( func );
 
     r->python_function = func;
+ r->arguments = 0;
+
+ if (bjam_signature)
+ {
+ argument_list * arg_list = args_new();
+ Py_ssize_t i;
+
+ Py_ssize_t s = PySequence_Size (bjam_signature);
+ for (i = 0; i < s; ++i)
+ {
+ PyObject* v = PySequence_GetItem (bjam_signature, i);
+ lol_add(arg_list->data, list_from_python (v));
+ Py_DECREF(v);
+ }
+ r->arguments = arg_list;
+ }
 
     Py_INCREF( Py_None );
     return Py_None;

Modified: trunk/tools/build/v2/engine/src/compile.c
==============================================================================
--- trunk/tools/build/v2/engine/src/compile.c (original)
+++ trunk/tools/build/v2/engine/src/compile.c 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -707,6 +707,7 @@
                     LIST* value = 0;
                     char modifier;
                     LIST* arg_name = formal; /* hold the argument name for type checking */
+ int multiple = 0;
 
                     /* Stop now if a variable number of arguments are specified */
                     if ( name[0] == '*' && name[1] == 0 )
@@ -722,6 +723,7 @@
                     case '+':
                     case '*':
                         value = list_copy( 0, actual );
+ multiple = 1;
                         actual = 0;
                         /* skip an extra element for the modifier */
                         formal = formal->next;
@@ -738,7 +740,8 @@
                         }
                     }
 
- locals = addsettings( locals, VAR_SET, name, value );
+ locals = addsettings(locals, VAR_SET, name, value);
+ locals->multiple = multiple;
                     type_check( type_name, value, frame, rule, arg_name );
                     type_name = 0;
                 }
@@ -764,28 +767,58 @@
 call_python_function(RULE* r, FRAME* frame)
 {
     LIST * result = 0;
- PyObject * arguments = PyTuple_New( frame->args->count );
+ PyObject * arguments = 0;
+ PyObject * kw = NULL;
     int i ;
     PyObject * py_result;
 
- for ( i = 0; i < frame->args->count; ++i )
+ if (r->arguments)
     {
- PyObject * arg = PyList_New(0);
- LIST* l = lol_get( frame->args, i);
+ SETTINGS * args;
 
- for ( ; l; l = l->next )
+ arguments = PyTuple_New(0);
+ kw = PyDict_New();
+
+ for (args = collect_arguments(r, frame); args; args = args->next)
+ {
+ PyObject *key = PyString_FromString(args->symbol);
+ PyObject *value = 0;
+ if (args->multiple)
+ value = list_to_python(args->value);
+ else {
+ if (args->value)
+ value = PyString_FromString(args->value->string);
+ }
+
+ if (value)
+ PyDict_SetItem(kw, key, value);
+ Py_DECREF(key);
+ Py_XDECREF(value);
+ }
+ }
+ else
+ {
+ arguments = PyTuple_New( frame->args->count );
+ for ( i = 0; i < frame->args->count; ++i )
         {
- PyObject * v = PyString_FromString(l->string);
- PyList_Append( arg, v );
- Py_DECREF(v);
+ PyObject * arg = PyList_New(0);
+ LIST* l = lol_get( frame->args, i);
+
+ for ( ; l; l = l->next )
+ {
+ PyObject * v = PyString_FromString(l->string);
+ PyList_Append( arg, v );
+ Py_DECREF(v);
+ }
+ /* Steals reference to 'arg' */
+ PyTuple_SetItem( arguments, i, arg );
         }
- /* Steals reference to 'arg' */
- PyTuple_SetItem( arguments, i, arg );
     }
 
     frame_before_python_call = frame;
- py_result = PyObject_CallObject( r->python_function, arguments );
- Py_DECREF( arguments );
+ py_result = PyObject_Call( r->python_function, arguments, kw );
+ Py_DECREF(arguments);
+ Py_XDECREF(kw);
     if ( py_result != NULL )
     {
         if ( PyList_Check( py_result ) )

Modified: trunk/tools/build/v2/engine/src/lists.c
==============================================================================
--- trunk/tools/build/v2/engine/src/lists.c (original)
+++ trunk/tools/build/v2/engine/src/lists.c 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -303,3 +303,37 @@
         list_print( lol->list[ i ] );
     }
 }
+
+#ifdef HAVE_PYTHON
+
+PyObject *list_to_python(LIST *l)
+{
+ PyObject *result = PyList_New(0);
+
+ for (; l; l = l->next)
+ {
+ PyObject* s = PyString_FromString(l->string);
+ PyList_Append(result, s);
+ Py_DECREF(s);
+ }
+
+ return result;
+}
+
+LIST *list_from_python(PyObject *l)
+{
+ LIST * result = 0;
+
+ Py_ssize_t i, n;
+ n = PySequence_Size(l);
+ for (i = 0; i < n; ++i)
+ {
+ PyObject *v = PySequence_GetItem(l, i);
+ result = list_new (result, newstr (PyString_AsString(v)));
+ Py_DECREF(v);
+ }
+
+ return result;
+}
+
+#endif

Modified: trunk/tools/build/v2/engine/src/lists.h
==============================================================================
--- trunk/tools/build/v2/engine/src/lists.h (original)
+++ trunk/tools/build/v2/engine/src/lists.h 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -45,6 +45,10 @@
 #ifndef LISTS_DWA20011022_H
 # define LISTS_DWA20011022_H
 
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif
+
 /*
  * LIST - list of strings
  */
@@ -93,5 +97,12 @@
 void lol_print( LOL *lol );
 void lol_build( LOL* lol, char** elements );
 
+#ifdef HAVE_PYTHON
+
+PyObject *list_to_python(LIST *l);
+LIST *list_from_python(PyObject *l);
+
+#endif
+
 #endif
 

Modified: trunk/tools/build/v2/engine/src/rules.c
==============================================================================
--- trunk/tools/build/v2/engine/src/rules.c (original)
+++ trunk/tools/build/v2/engine/src/rules.c 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -421,6 +421,7 @@
         v->symbol = newstr( symbol );
         v->value = value;
         v->next = head;
+ v->multiple = 0;
         head = v;
     }
     else if ( flag == VAR_APPEND )

Modified: trunk/tools/build/v2/engine/src/rules.h
==============================================================================
--- trunk/tools/build/v2/engine/src/rules.h (original)
+++ trunk/tools/build/v2/engine/src/rules.h 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -119,6 +119,7 @@
     SETTINGS * next;
     char * symbol; /* symbol name for var_set() */
     LIST * value; /* symbol value for var_set() */
+ int multiple;
 };
 
 /* TARGETS - a chain of TARGETs. */

Modified: trunk/tools/build/v2/util/__init__.py
==============================================================================
--- trunk/tools/build/v2/util/__init__.py (original)
+++ trunk/tools/build/v2/util/__init__.py 2010-07-19 09:20:51 EDT (Mon, 19 Jul 2010)
@@ -0,0 +1,8 @@
+
+def bjam_signature(s):
+
+ def wrap(f):
+ f.bjam_signature = s
+ return f
+
+ return wrap


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk