add taskvar.string .foreach() method

parent a349b724
......@@ -52,6 +52,7 @@ GEN_TESTS = \
TESTS = \
$(GEN_TESTS) \
vtc/vmod_taskvar_foreach.vtc \
vtc/clash.vtc
$(GEN_VCCS): $(top_srcdir)/LICENSE tbl_types.h
......
......@@ -65,6 +65,15 @@ VCC_TYPE(STEVEDORE, stevedore)
#define DEF_STRING = 0
#define DEFDOC_STRING DEFDOC the empty string.
VCC_TYPE(STRING, string)
#ifdef VCCTPL
$Method VOID .foreach(STRING string, SUB sub, STRING delim=",")
Breaks ``string`` into a sequence of zero or more nonempty tokens,
seperated by ``delim``, and successively calls ``sub`` with the object
set to each token.
Processing ends for a nonempty ``return()`` from ``sub``.
#endif
// VCC_TYPE(STRINGS)
// VCC_TYPE(STRING_LIST)
......
......@@ -106,3 +106,41 @@ state_l(VRT_CTX, void *v, size_t sz)
#define VCC_TYPE(TYPE, type) var_code(vmod_, VMOD_TASKVAR_, vmod_taskvar_, TYPE, type)
#include "tbl_types.h"
VCL_VOID
vmod_string_foreach(VRT_CTX, struct VPFX(taskvar_string) *va,
VCL_STRING s, VCL_SUB sub, VCL_STRING delim)
{
char *p, *str, *save;
struct vmod_taskvar_string *v =
state_l(ctx, va, sizeof *v);
if (v == NULL)
return;
CHECK_OBJ(v, VMOD_TASKVAR_STRING_MAGIC);
if (v->protected) {
VRT_fail(ctx,
"attempt to set protected variable");
return;
}
str = WS_Copy(ctx->ws, s, -1);
if (str == NULL) {
VRT_fail(ctx, ".foreach() out of workspace");
return;
}
p = strtok_r(str, delim, &save);
while (p != NULL) {
v->var = p;
v->defined = 1;
VRT_call(ctx, sub);
if (VRT_handled(ctx))
break;
p = strtok_r(NULL, delim, &save);
}
v->var = NULL;
v->defined = 0;
}
......@@ -216,6 +216,8 @@ SYNOPSIS
:ref:`xstring.protected()`
:ref:`xstring.foreach()`
:ref:`taskvar.time()`
:ref:`xtime.get()`
......@@ -1063,6 +1065,21 @@ BOOL xstring.protected()
Return whether the taskvar is protected.
.. _xstring.foreach():
VOID xstring.foreach(STRING string, SUB sub, STRING delim)
----------------------------------------------------------
::
VOID xstring.foreach(STRING string, SUB sub, STRING delim=",")
Breaks ``string`` into a sequence of zero or more nonempty tokens,
seperated by ``delim``, and successively call ``sub`` with the object
set to each token.
Processing ends for a nonempty ``return()`` from ``sub``.
.. _taskvar.time():
new xtime = taskvar.time([TIME init])
......
......@@ -63,6 +63,8 @@ for the respective type names and the ``.get()`` fallback.
.. just a newline
#define VCCTPL
#define VMOD taskvar
#define VCC_TYPE(TYPE, type) \
$Object type([TYPE init])\n \
Construct a(n) TYPE taskvar with the default value `init`,\n \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment