You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by gi...@apache.org on 2020/12/29 13:02:14 UTC

[buildstream] 24/27: _variables.pyx: Move the meat of value resolution to ValueClass

This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch tristan/partial-variables-manual-string-join
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit c61359c3c7d7c927ba84bc8b4377cefe429ba476
Author: Tristan van Berkom <tr...@codethink.co.uk>
AuthorDate: Sat Jul 11 15:35:52 2020 +0900

    _variables.pyx: Move the meat of value resolution to ValueClass
---
 src/buildstream/_variables.pyx | 127 +++++++++++++++++++++++------------------
 1 file changed, 70 insertions(+), 57 deletions(-)

diff --git a/src/buildstream/_variables.pyx b/src/buildstream/_variables.pyx
index 1958dd0..36708c9 100644
--- a/src/buildstream/_variables.pyx
+++ b/src/buildstream/_variables.pyx
@@ -382,6 +382,14 @@ cdef class Variables:
             iter_value = <Value>values.array[idx]
 
             if iter_value._resolved is None:
+
+                # For the first iteration, we pass an invalid pointer
+                # outside the bounds of the array.
+                #
+                # The first iteration cannot require any variable
+                # expansion though, because of how variables are
+                # sorted.
+                #
                 iter_value.resolve(&values, idx + 1)
 
             values.array[idx] = <PyObject *>iter_value._resolved
@@ -555,69 +563,15 @@ cdef class Value:
     # it will fail due to an undefined variable.
     #
     # Args:
-    #    values (dict): The full value table for resolving dependencies
+    #    values (PyObject **): Array of resolved strings to fill in the values
     #
     # Returns:
     #    (str): The resolved value
     #
-    cdef str resolve(self, ObjectArray *resolved_values, Py_ssize_t values_idx):
-        cdef ValuePart *part
-        cdef Py_UCS4 maxchar = 0
-        cdef Py_UCS4 part_maxchar
-        cdef Py_ssize_t full_length = 0
-        cdef Py_ssize_t idx
-        cdef Py_ssize_t offset
-        cdef Py_ssize_t part_length
-        cdef PyObject *resolved
-        cdef PyObject *part_object
+    cdef str resolve(self, ObjectArray *values, Py_ssize_t value_idx):
 
         if self._resolved is None:
-
-            # Calculate the number of codepoints and maximum character width
-            # required for the strings involved.
-            idx = values_idx
-            part = self._value_class.parts
-            while part:
-                if part.is_variable:
-                    part_object = resolved_values.array[idx]
-                    idx += 1
-                else:
-                    part_object = part.text
-
-                full_length += PyUnicode_GET_LENGTH(part_object)
-                part_maxchar = PyUnicode_MAX_CHAR_VALUE(part_object)
-                if part_maxchar > maxchar:
-                    maxchar = part_maxchar
-
-                part = part.next_part
-
-            # Do the stringy thingy
-            resolved = PyUnicode_New(full_length, maxchar)
-            part = self._value_class.parts
-            idx = values_idx
-            offset = 0
-
-            # This time copy characters as we loop through the parts
-            while part:
-                if part.is_variable:
-                    part_object = resolved_values.array[idx]
-                    idx += 1
-                else:
-                    part_object = part.text
-
-                part_length = PyUnicode_GET_LENGTH(part_object)
-
-                # Does this need to be in a loop and have a maximum copy length ?
-                #
-                # Should we be doing the regular posix thing, handling an exception indicating
-                # a SIGINT or such which means we should resume our copy instead of consider an error ?
-                #
-                PyUnicode_CopyCharacters(resolved, offset, part_object, 0, part_length)
-
-                offset += part_length
-                part = part.next_part
-
-            self._resolved = <str> resolved
+            self._resolved = self._value_class.resolve(values, value_idx)
 
         return self._resolved
 
@@ -697,6 +651,65 @@ cdef class ValueClass:
         self.parts = NULL
         self._parse_string(string)
 
+    # resolve()
+    #
+    #
+    cdef str resolve(self, ObjectArray *values, Py_ssize_t value_idx):
+        cdef ValuePart *part
+        cdef Py_UCS4 maxchar = 0
+        cdef Py_UCS4 part_maxchar
+        cdef Py_ssize_t full_length = 0
+        cdef Py_ssize_t idx
+        cdef Py_ssize_t offset = 0
+        cdef Py_ssize_t part_length
+        cdef PyObject *resolved
+        cdef PyObject *part_object
+
+        # Calculate the number of codepoints and maximum character width
+        # required for the strings involved.
+        idx = value_idx
+        part = self.parts
+        while part:
+            if part.is_variable:
+                part_object = values.array[idx]
+                idx += 1
+            else:
+                part_object = part.text
+
+            full_length += PyUnicode_GET_LENGTH(part_object)
+            part_maxchar = PyUnicode_MAX_CHAR_VALUE(part_object)
+            if part_maxchar > maxchar:
+                maxchar = part_maxchar
+
+            part = part.next_part
+
+        # Do the stringy thingy
+        resolved = PyUnicode_New(full_length, maxchar)
+
+        # This time copy characters as we loop through the parts
+        idx = value_idx
+        part = self.parts
+        while part:
+            if part.is_variable:
+                part_object = values.array[idx]
+                idx += 1
+            else:
+                part_object = part.text
+
+            part_length = PyUnicode_GET_LENGTH(part_object)
+
+            # Does this need to be in a loop and have a maximum copy length ?
+            #
+            # Should we be doing the regular posix thing, handling an exception indicating
+            # a SIGINT or such which means we should resume our copy instead of consider an error ?
+            #
+            PyUnicode_CopyCharacters(resolved, offset, part_object, 0, part_length)
+
+            offset += part_length
+            part = part.next_part
+
+        return <str> resolved
+
     # _parse_string()
     #
     # Parse the string for this ValueClass, breaking it down into