diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
commit | be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 (patch) | |
tree | 9754ff1ca740f6346cf8483ec915d4054bc5da2d /fluent-bit/src/flb_slist.c | |
parent | Initial commit. (diff) | |
download | netdata-be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97.tar.xz netdata-be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97.zip |
Adding upstream version 1.44.3.upstream/1.44.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/src/flb_slist.c')
-rw-r--r-- | fluent-bit/src/flb_slist.c | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/fluent-bit/src/flb_slist.c b/fluent-bit/src/flb_slist.c new file mode 100644 index 00000000..512fe452 --- /dev/null +++ b/fluent-bit/src/flb_slist.c @@ -0,0 +1,356 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2015-2022 The Fluent Bit Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fluent-bit/flb_info.h> +#include <fluent-bit/flb_log.h> +#include <fluent-bit/flb_mem.h> +#include <fluent-bit/flb_sds.h> +#include <fluent-bit/flb_slist.h> + +/* Initialize slist */ +int flb_slist_create(struct mk_list *list) +{ + mk_list_init(list); + return 0; +} + +/* Append 'len' bytes of 'str' as a new string node into the list */ +int flb_slist_add_n(struct mk_list *head, const char *str, int len) +{ + struct flb_slist_entry *e; + + e = flb_malloc(sizeof(struct flb_slist_entry)); + if (!e) { + flb_errno(); + return -1; + } + + e->str = flb_sds_create_len(str, len); + if (!e->str) { + flb_free(e); + return -1; + } + + mk_list_add(&e->_head, head); + return 0; +} + +int flb_slist_add_sds(struct mk_list *head, flb_sds_t str) +{ + struct flb_slist_entry *e; + + e = flb_malloc(sizeof(struct flb_slist_entry)); + if (!e) { + flb_errno(); + return -1; + } + + e->str = str; + mk_list_add(&e->_head, head); + return 0; +} + +/* Append NULL terminated string as a new node into the list */ +int flb_slist_add(struct mk_list *head, const char *str) +{ + int len; + + if (!str) { + return -1; + } + + len = strlen(str); + if (len <= 0) { + return -1; + } + + return flb_slist_add_n(head, str, len); +} + +static inline int token_unescape(char *token) +{ + char *in = token; + char *out = token; + + while (*in) { + if ((in[0] == '\\') && (in[1] == '"')) { + *out = in[1]; + out++; + in += 2; + } + else { + *out = *in; + out++; + in++; + } + } + *out = 0; + return out - token; +} + +static flb_sds_t token_retrieve(char **str) +{ + int len; + int quoted = FLB_FALSE; + char *p; + char *start; + char *prev; + flb_sds_t out = NULL; + + if (!*str) { + return NULL; + } + + p = *str; + + /* Skip empty spaces */ + while (*p == ' ') { + p++; + } + start = p; + + if (*p == '"') { + quoted = FLB_TRUE; + p++; + start = p; + while (1) { + while (*p && *p != '"') { + p++; + } + + if (!*p) { + goto exit; + } + + prev = p - 1; + if (*prev == '\\') { + p++; + continue; + } + goto exit; + } + } + + while (*p && *p != ' ') { + p++; + } + + exit: + if (*p) { + out = flb_sds_create_len(start, p - start); + if (!out) { + *str = NULL; + return NULL; + } + if (quoted == FLB_TRUE) { + len = token_unescape(out); + flb_sds_len_set(out, len); + } + p++; + + while (*p && *p == ' ') { + p++; + } + *str = p; + } + else { + if (p > start) { + out = flb_sds_create(start); + } + *str = NULL; + } + + return out; +} + +int flb_slist_split_tokens(struct mk_list *list, const char *str, int max_split) +{ + int count = 0; + char *p; + char *buf; + flb_sds_t tmp = NULL; + + buf = (char *) str; + while ((tmp = token_retrieve(&buf))) { + flb_slist_add_sds(list, tmp); + if (!buf) { + break; + } + count++; + + /* Append remaining string if we use a maximum number of tokens */ + if (count >= max_split && max_split > 0) { + p = buf; + while (*p == ' ') { + p++; + } + + if (*p) { + flb_slist_add(list, p); + } + break; + } + } + + return 0; +} + +/* + * Split a string using a separator, every splitted content is appended to the end of + * the slist list head. + */ +int flb_slist_split_string(struct mk_list *list, const char *str, + int separator, int max_split) +{ + int i = 0; + int ret; + int count = 0; + int val_len; + int len; + int end; + char *p_init; + char *p_end; + + if (!str) { + return -1; + } + + len = strlen(str); + while (i < len) { + end = mk_string_char_search(str + i, separator, len - i); + if (end < 0) { + end = len - i; + } + else if ((end + i) == i) { + i++; + continue; + } + + p_init = (char *) str + i; + p_end = p_init + end - 1; + + /* Skip empty spaces */ + while (*p_init == ' ') { + p_init++; + } + + while (*p_end == ' ' && p_end >= p_init) { + p_end--; + } + + if (p_init > p_end) { + goto next; + } + + if (p_init == p_end) { + if (*p_init == ' ') { + goto next; + } + val_len = 1; + } + else { + val_len = (p_end - p_init) + 1; + } + + if (val_len == 0) { + goto next; + } + + ret = flb_slist_add_n(list, p_init, val_len); + if (ret == -1) { + return -1; + } + count++; + + /* Append remaining string as a new node ? */ + if (count >= max_split && max_split > 0) { + p_end = p_init + end; + if (*p_end == separator) { + p_end++; + } + while (*p_end == ' ') { + p_end++; + } + + if ((p_end - str) >= len) { + break; + } + + ret = flb_slist_add(list, p_end); + if (ret == -1) { + return -1; + } + count++; + break; + } + + next: + i += end + 1; + } + + return count; +} + +void flb_slist_dump(struct mk_list *list) +{ + struct mk_list *head; + struct flb_slist_entry *e; + + printf("[slist %p]\n", list); + mk_list_foreach(head, list) { + e = mk_list_entry(head, struct flb_slist_entry, _head); + printf(" - '%s'\n", e->str); + } +} + +void flb_slist_destroy(struct mk_list *list) +{ + struct mk_list *tmp; + struct mk_list *head; + struct flb_slist_entry *e; + + mk_list_foreach_safe(head, tmp, list) { + e = mk_list_entry(head, struct flb_slist_entry, _head); + flb_sds_destroy(e->str); + mk_list_del(&e->_head); + flb_free(e); + } +} + +/* Return the entry in position number 'n' */ +struct flb_slist_entry *flb_slist_entry_get(struct mk_list *list, int n) +{ + int i = 0; + struct mk_list *head; + struct flb_slist_entry *e; + + if (!list || mk_list_size(list) == 0) { + return NULL; + } + + mk_list_foreach(head, list) { + if (i == n) { + e = mk_list_entry(head, struct flb_slist_entry, _head); + return e; + } + i++; + } + + return NULL; +} |