summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_tstr.c
diff options
context:
space:
mode:
authorZhidao HONG <z.hong@f5.com>2022-11-20 23:15:01 +0800
committerZhidao HONG <z.hong@f5.com>2022-11-20 23:15:01 +0800
commit4735931ace321752c387dae04c8b217ef22897ee (patch)
treebb1a7a030094721d25683f999e828e7fab71c1f9 /src/nxt_tstr.c
parent0c9f417affcef25b2ede5aaf0967eb411a247e33 (diff)
downloadunit-4735931ace321752c387dae04c8b217ef22897ee.tar.gz
unit-4735931ace321752c387dae04c8b217ef22897ee.tar.bz2
Var: separating nxt_tstr_t from nxt_var_t.
It's for the introduction of njs support. For each option that supports native variable and JS template literals introduced next, it's unified as template string. No functional changes.
Diffstat (limited to 'src/nxt_tstr.c')
-rw-r--r--src/nxt_tstr.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c
new file mode 100644
index 00000000..dff61952
--- /dev/null
+++ b/src/nxt_tstr.c
@@ -0,0 +1,223 @@
+
+/*
+ * Copyright (C) NGINX, Inc.
+ */
+
+#include <nxt_main.h>
+
+
+typedef enum {
+ NXT_TSTR_CONST = 0,
+ NXT_TSTR_VAR,
+} nxt_tstr_type_t;
+
+
+struct nxt_tstr_s {
+ nxt_str_t str;
+ nxt_var_t *var;
+ nxt_tstr_flags_t flags;
+ nxt_tstr_type_t type;
+};
+
+
+struct nxt_tstr_query_s {
+ nxt_mp_t *pool;
+
+ nxt_tstr_state_t *state;
+ nxt_var_cache_t *cache;
+
+ nxt_uint_t waiting;
+ nxt_uint_t failed; /* 1 bit */
+
+ void *ctx;
+ void *data;
+
+ nxt_work_handler_t ready;
+ nxt_work_handler_t error;
+};
+
+
+nxt_tstr_state_t *
+nxt_tstr_state_new(nxt_mp_t *mp)
+{
+ nxt_tstr_state_t *state;
+
+ state = nxt_mp_get(mp, sizeof(nxt_tstr_state_t));
+ if (nxt_slow_path(state == NULL)) {
+ return NULL;
+ }
+
+ state->pool = mp;
+
+ state->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t));
+ if (nxt_slow_path(state->var_fields == NULL)) {
+ return NULL;
+ }
+
+ return state;
+}
+
+
+nxt_tstr_t *
+nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str,
+ nxt_tstr_flags_t flags)
+{
+ u_char *p;
+ nxt_tstr_t *tstr;
+ nxt_bool_t strz;
+
+ strz = (flags & NXT_TSTR_STRZ) != 0;
+
+ tstr = nxt_mp_get(state->pool, sizeof(nxt_tstr_t));
+ if (nxt_slow_path(tstr == NULL)) {
+ return NULL;
+ }
+
+ tstr->str.length = str->length + strz;
+
+ tstr->str.start = nxt_mp_nget(state->pool, tstr->str.length);
+ if (nxt_slow_path(tstr->str.start == NULL)) {
+ return NULL;
+ }
+
+ p = nxt_cpymem(tstr->str.start, str->start, str->length);
+
+ if (strz) {
+ *p = '\0';
+ }
+
+ tstr->flags = flags;
+
+ p = nxt_memchr(str->start, '$', str->length);
+
+ if (p != NULL) {
+ tstr->type = NXT_TSTR_VAR;
+
+ tstr->var = nxt_var_compile(&tstr->str, state->pool, state->var_fields);
+ if (nxt_slow_path(tstr->var == NULL)) {
+ return NULL;
+ }
+
+ } else {
+ tstr->type = NXT_TSTR_CONST;
+ }
+
+ return tstr;
+}
+
+
+nxt_int_t
+nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error)
+{
+ return nxt_var_test(str, state->var_fields, error);
+}
+
+
+nxt_bool_t
+nxt_tstr_is_const(nxt_tstr_t *tstr)
+{
+ return (tstr->type == NXT_TSTR_CONST);
+}
+
+
+void
+nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str)
+{
+ *str = tstr->str;
+
+ if (tstr->flags & NXT_TSTR_STRZ) {
+ str->length--;
+ }
+}
+
+
+nxt_int_t
+nxt_tstr_query_init(nxt_tstr_query_t **query_p, nxt_tstr_state_t *state,
+ nxt_var_cache_t *cache, void *ctx, nxt_mp_t *mp)
+{
+ nxt_tstr_query_t *query;
+
+ query = *query_p;
+
+ if (*query_p == NULL) {
+ query = nxt_mp_zget(mp, sizeof(nxt_tstr_query_t));
+ if (nxt_slow_path(query == NULL)) {
+ return NXT_ERROR;
+ }
+ }
+
+ query->pool = mp;
+ query->state = state;
+ query->cache = cache;
+ query->ctx = ctx;
+
+ *query_p = query;
+
+ return NXT_OK;
+}
+
+
+void
+nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr,
+ nxt_str_t *val)
+{
+ nxt_int_t ret;
+
+ if (nxt_tstr_is_const(tstr)) {
+ nxt_tstr_str(tstr, val);
+ return;
+ }
+
+ if (nxt_slow_path(query->failed)) {
+ return;
+ }
+
+ ret = nxt_var_interpreter(task, query->cache, tstr->var, val, query->ctx,
+ tstr->flags & NXT_TSTR_LOGGING);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ query->failed = 1;
+ return;
+ }
+
+ if (tstr->flags & NXT_TSTR_STRZ) {
+ val->length--;
+ }
+
+#if (NXT_DEBUG)
+ nxt_str_t str;
+
+ nxt_tstr_str(tstr, &str);
+
+ nxt_debug(task, "tstr: \"%V\" -> \"%V\"", &str, val);
+#endif
+}
+
+
+void
+nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query, void *data,
+ nxt_work_handler_t ready, nxt_work_handler_t error)
+{
+ query->data = data;
+ query->ready = ready;
+ query->error = error;
+
+ if (query->waiting == 0) {
+ nxt_work_queue_add(&task->thread->engine->fast_work_queue,
+ query->failed ? query->error : query->ready,
+ task, query->ctx, query->data);
+ }
+}
+
+
+void
+nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query,
+ nxt_bool_t failed)
+{
+ query->failed |= failed;
+
+ if (--query->waiting == 0) {
+ nxt_work_queue_add(&task->thread->engine->fast_work_queue,
+ query->failed ? query->error : query->ready,
+ task, query->ctx, query->data);
+ }
+}