[PATCH v4 02/12] nxt_conf.c: Treat non-arrays as arrays of size 1

Alejandro Colomar alx.manpages at gmail.com
Thu Dec 23 19:24:59 UTC 2021


Similar to how C pointers to variables can always be considered as
pointers to the first element of an array of size 1 (see the
following code for an example of how they are equivalent),
treating non-NXT_CONF_VALUE_ARRAY as if they were
NXT_CONF_VALUE_ARRAYs of size 1 allows for simpler and more
generic code.

	void foo(ptrdiff_t sz, int arr[sz])
	{
		for (ptrdiff_t i = 0; i < sz; i++)
			arr[i] = 0;
	}

	void bar(void)
	{
		int  x;
		int  y[1];

		foo(1, &x);
		foo(1, y);
	}

nxt_conf_array_elements_count():
	Return a size of 1 when input is non-array, instead of
	causing undefined behavior.  That value (1) makes sense
	because it will be used as the limiter of a loop that
	loops over the array and calls
	nxt_conf_get_array_element(), which will return a correct
	element for such loops.

nxt_conf_get_array_element():
	Return the input pointer unmodified (i.e., a pointer to
	the unique element of a hypothetical array), instead of
	returning NULL, which wasn't very useful.

nxt_conf_array_qsort():
	Since it's a no-op for non-arrays, this doesn't need to be
	modified.

Example of (correct) usage:

	void baz(nxt_conf_value_t *x)
	{
		/* 'x' may or may not be a NXT_CONF_VALUE_ARRAY */

		ptrdiff_t         n;
		nxt_conf_value_t  *elem;

		n = nxt_conf_array_elements_count(x);
		for (ptrdiff_t i = 0; i < n; i++) {
			elem = nxt_conf_get_array_element(x, i);
			/* do some work with 'elem' */
		}
	}

Signed-off-by: Alejandro Colomar <alx.manpages at gmail.com>
Cc: Nginx Unit <unit at nginx.org>
Cc: "Valentin V. Bartenev" <vbart at nginx.com>
Cc: Zhidao HONG <z.hong at f5.com>
Cc: Igor Sysoev <igor at sysoev.ru>
Cc: Oisin Canty <o.canty at f5.com>
---
 src/nxt_conf.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/nxt_conf.c b/src/nxt_conf.c
index 1aca0a7..3f0cfa8 100644
--- a/src/nxt_conf.c
+++ b/src/nxt_conf.c
@@ -387,7 +387,7 @@ nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp,
 nxt_uint_t
 nxt_conf_array_elements_count(nxt_conf_value_t *value)
 {
-    return value->u.array->count;
+    return (value->type == NXT_CONF_VALUE_ARRAY) ? value->u.array->count : 1;
 }
 
 
@@ -736,7 +736,7 @@ nxt_conf_get_array_element(nxt_conf_value_t *value, uint32_t index)
     nxt_conf_array_t  *array;
 
     if (value->type != NXT_CONF_VALUE_ARRAY) {
-        return NULL;
+        return (index == 0) ? value : NULL;
     }
 
     array = value->u.array;
-- 
2.34.1



More information about the unit mailing list