summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/lib/monkey/mk_core/mk_string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluent-bit/lib/monkey/mk_core/mk_string.c')
-rw-r--r--src/fluent-bit/lib/monkey/mk_core/mk_string.c615
1 files changed, 615 insertions, 0 deletions
diff --git a/src/fluent-bit/lib/monkey/mk_core/mk_string.c b/src/fluent-bit/lib/monkey/mk_core/mk_string.c
new file mode 100644
index 000000000..b2fdc5714
--- /dev/null
+++ b/src/fluent-bit/lib/monkey/mk_core/mk_string.c
@@ -0,0 +1,615 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ==================
+ * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <mk_core/mk_core_info.h>
+#include <mk_core/mk_macros.h>
+#include <mk_core/mk_utils.h>
+#include <mk_core/mk_memory.h>
+#include <mk_core/mk_string.h>
+
+#include <stdio.h>
+
+/* OSX and Windows lacks of memrchr() */
+#if !defined(MK_HAVE_MEMRCHR)
+void *memrchr(const void *s, int c, size_t n)
+{
+ const unsigned char *cp;
+
+ if (n != 0) {
+ cp = (unsigned char *)s + n;
+ do {
+ if (*(--cp) == (unsigned char)c)
+ return((void *)cp);
+ } while (--n != 0);
+ }
+ return(NULL);
+}
+#endif
+
+#ifndef MK_HAVE_MEMMEM
+void *memmem(const void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen)
+{
+ char *null_terminated_haystack_buffer;
+ char *null_terminated_needle_buffer;
+ void *result;
+
+ result = NULL;
+
+ null_terminated_haystack_buffer = (char *) calloc(haystacklen + 1,
+ sizeof(char));
+
+ if(NULL != null_terminated_haystack_buffer){
+ null_terminated_needle_buffer = (char *) calloc(needlelen + 1,
+ sizeof(char));
+
+ if(NULL != null_terminated_needle_buffer){
+ strncpy(null_terminated_haystack_buffer, haystack, haystacklen);
+ strncpy(null_terminated_needle_buffer, needle, needlelen);
+
+ result = strstr(null_terminated_haystack_buffer,
+ null_terminated_needle_buffer);
+
+ if (result != NULL) {
+ result = (void *)
+ ((((uintptr_t) null_terminated_haystack_buffer) - \
+ ((uintptr_t) result)) +
+ ((uintptr_t) haystack));
+ }
+
+ free(null_terminated_needle_buffer);
+ }
+
+ free(null_terminated_haystack_buffer);
+ }
+
+ return result;
+}
+#endif
+
+/* Windows lack of strndup() & strcasestr() */
+#ifdef _WIN32
+char *strndup (const char *s, size_t n)
+{
+ char *result;
+ size_t len = strlen (s);
+
+ if (n < len) {
+ len = n;
+ }
+
+ result = (char *) mk_mem_alloc(len + 1);
+ if (!result) {
+ return 0;
+ }
+
+ result[len] = '\0';
+ return (char *) memcpy (result, s, len);
+}
+
+char *strcasestr(const char *phaystack, const char *pneedle)
+{
+ register const unsigned char *haystack, *needle;
+ register unsigned bl, bu, cl, cu;
+
+ haystack = (const unsigned char *) phaystack;
+ needle = (const unsigned char *) pneedle;
+
+ bl = tolower(*needle);
+ if (bl != '\0')
+ {
+ // Scan haystack until the first character of needle is found:
+ bu = toupper(bl);
+ haystack--; /* possible ANSI violation */
+ do
+ {
+ cl = *++haystack;
+ if (cl == '\0')
+ goto ret0;
+ }
+ while ((cl != bl) && (cl != bu));
+
+ cl = tolower(*++needle);
+ if (cl == '\0') {
+ goto foundneedle;
+ }
+
+ cu = toupper(cl);
+ ++needle;
+ goto jin;
+
+ for (;;)
+ {
+ register unsigned a;
+ register const unsigned char *rhaystack, *rneedle;
+ do
+ {
+ a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+ if ((a == bl) || (a == bu))
+ break;
+ a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+shloop:
+ ;
+ }
+ while ((a != bl) && (a != bu));
+
+jin:
+ a = *++haystack;
+ if (a == '\0') {
+ goto ret0;
+ }
+
+ if ((a != cl) && (a != cu)) {
+ goto shloop;
+ }
+
+ rhaystack = haystack-- + 1;
+ rneedle = needle;
+ a = tolower(*rneedle);
+
+ if (tolower(*rhaystack) == (int) a)
+ do
+ {
+ if (a == '\0')
+ goto foundneedle;
+ ++rhaystack;
+ a = tolower(*++needle);
+ if (tolower(*rhaystack) != (int) a)
+ break;
+ if (a == '\0')
+ goto foundneedle;
+ ++rhaystack;
+ a = tolower(*++needle);
+ }
+ while (tolower(*rhaystack) == (int) a);
+
+ needle = rneedle; /* took the register-poor approach */
+
+ if (a == '\0')
+ break;
+ } // for(;;)
+ } // if (bl != '\0')
+foundneedle:
+ return (char*) haystack;
+ret0:
+ return 0;
+}
+#endif
+
+/*
+ * Base function for search routines, it accept modifiers to enable/disable
+ * the case sensitive feature and also allow to specify a haystack len
+ * Get position of a substring.
+*/
+static int _mk_string_search(const char *string, const char *search,
+ int sensitive, int len)
+{
+ int i = 0;
+ char *p = NULL, *q = NULL;
+ char *s = NULL;
+
+ /* Fast path */
+ if (len <= 0) {
+ switch(sensitive) {
+ case MK_STR_SENSITIVE:
+ p = strstr(string, search);
+ break;
+ case MK_STR_INSENSITIVE:
+ p = strcasestr(string, search);
+ break;
+ }
+
+ if (p) {
+ return (p - string);
+ }
+ else {
+ return -1;
+ }
+ }
+
+ p = (char *) string;
+ do {
+ q = p;
+ s = (char *) search;
+ if (sensitive == MK_STR_SENSITIVE) {
+ while (*s && (*s == *q)) {
+ q++, s++;
+ }
+ }
+ else if (sensitive == MK_STR_INSENSITIVE) {
+ while (*s && (toupper(*q) == toupper(*s))) {
+ q++, s++;
+ }
+ }
+
+ /* match */
+ if (*s == 0) {
+ return (p - string);
+ }
+
+ i++;
+ if (i >= len) {
+ break;
+ }
+ } while (*p++);
+
+ return -1;
+}
+
+/* Lookup char into string, return position */
+int mk_string_char_search(const char *string, int c, int len)
+{
+ char *p;
+
+ if (len < 0) {
+ len = strlen(string);
+ }
+
+ p = memchr(string, c, len);
+ if (p) {
+ return (p - string);
+ }
+
+ return -1;
+}
+
+/* Find char into string searching in reverse order, returns position */
+int mk_string_char_search_r(const char *string, int c, int len)
+{
+ char *p;
+
+ if (len <= 0) {
+ len = strlen(string);
+ }
+
+ p = memrchr(string, c, len);
+ if (p) {
+ return (p - string);
+ }
+
+ return -1;
+}
+
+int mk_string_search(const char *haystack, const char *needle, int sensitive)
+{
+ return _mk_string_search(haystack, needle, sensitive, -1);
+}
+
+int mk_string_search_n(const char *haystack, const char *needle, int sensitive, int len)
+{
+ return _mk_string_search(haystack, needle, sensitive, len);
+}
+
+char *mk_string_casestr(char *heystack, char *needle)
+{
+ if (!heystack || !needle) {
+ return NULL;
+ }
+
+ return strcasestr(heystack, needle);
+}
+
+char *mk_string_dup(const char *s)
+{
+ size_t len;
+ char *p;
+
+ if (!s) {
+ return NULL;
+ }
+
+ len = strlen(s);
+ p = mk_mem_alloc(len + 1);
+ if (!p) {
+ return NULL;
+ }
+ memcpy(p, s, len);
+ p[len] = '\0';
+
+ return p;
+}
+
+struct mk_list *mk_string_split_line(const char *line)
+{
+ unsigned int i = 0, len, val_len;
+ int end;
+ char *val;
+ struct mk_list *list;
+ struct mk_string_line *new;
+
+ if (!line) {
+ return NULL;
+ }
+
+ list = mk_mem_alloc(sizeof(struct mk_list));
+ if (!list) {
+ return NULL;
+ }
+ mk_list_init(list);
+
+ len = strlen(line);
+
+ while (i < len) {
+ end = mk_string_char_search(line + i, ' ', len - i);
+
+ if (end >= 0 && end + i < len) {
+ end += i;
+
+ if (i == (unsigned int) end) {
+ i++;
+ continue;
+ }
+
+ val = mk_string_copy_substr(line, i, end);
+ val_len = end - i;
+ }
+ else {
+ val = mk_string_copy_substr(line, i, len);
+ val_len = len - i;
+ end = len;
+
+ }
+
+ /* Alloc node */
+ new = mk_mem_alloc(sizeof(struct mk_string_line));
+ new->val = val;
+ new->len = val_len;
+
+ mk_list_add(&new->_head, list);
+ i = end + 1;
+ }
+
+ return list;
+}
+
+void mk_string_split_free(struct mk_list *list)
+{
+ struct mk_list *head, *tmp;
+ struct mk_string_line *entry;
+
+ mk_list_foreach_safe(head, tmp, list) {
+ entry = mk_list_entry(head, struct mk_string_line, _head);
+ mk_list_del(&entry->_head);
+ mk_mem_free(entry->val);
+ mk_mem_free(entry);
+ }
+
+ mk_mem_free(list);
+}
+
+char *mk_string_build(char **buffer, unsigned long *len,
+ const char *format, ...)
+{
+ va_list ap;
+ int length;
+ char *ptr;
+ const size_t _mem_alloc = 64;
+ size_t alloc = 0;
+
+ /* *buffer *must* be an empty/NULL buffer */
+ mk_bug(*buffer);
+ *buffer = (char *) mk_mem_alloc(_mem_alloc);
+
+ if (!*buffer) {
+ return NULL;
+ }
+ alloc = _mem_alloc;
+
+ va_start(ap, format);
+ length = vsnprintf(*buffer, alloc, format, ap);
+ va_end(ap);
+
+ if (length < 0) {
+ return NULL;
+ }
+
+ if ((unsigned int) length >= alloc) {
+ ptr = mk_mem_realloc(*buffer, length + 1);
+ if (!ptr) {
+ return NULL;
+ }
+ *buffer = ptr;
+ alloc = length + 1;
+
+ va_start(ap, format);
+ length = vsnprintf(*buffer, alloc, format, ap);
+ va_end(ap);
+ }
+
+ ptr = *buffer;
+ ptr[length] = '\0';
+ *len = length;
+
+ return *buffer;
+}
+
+int mk_string_trim(char **str)
+{
+ unsigned int i;
+ unsigned int len;
+ char *left = 0, *right = 0;
+ char *buf;
+
+ buf = *str;
+ if (!buf) {
+ return -1;
+ }
+
+ len = strlen(buf);
+ left = buf;
+
+ if(len == 0) {
+ return 0;
+ }
+
+ /* left spaces */
+ while (left) {
+ if (isspace(*left)) {
+ left++;
+ }
+ else {
+ break;
+ }
+ }
+
+ right = buf + (len - 1);
+ /* Validate right v/s left */
+ if (right < left) {
+ buf[0] = '\0';
+ return -1;
+ }
+
+ /* Move back */
+ while (right != buf){
+ if (isspace(*right)) {
+ right--;
+ }
+ else {
+ break;
+ }
+ }
+
+ len = (right - left) + 1;
+ for(i=0; i<len; i++){
+ buf[i] = (char) left[i];
+ }
+ buf[i] = '\0';
+
+ return 0;
+}
+
+uint32_t digits10(uint64_t v) {
+ if (v < 10) return 1;
+ if (v < 100) return 2;
+ if (v < 1000) return 3;
+ if (v < 1000000000000UL) {
+ if (v < 100000000UL) {
+ if (v < 1000000) {
+ if (v < 10000) return 4;
+ return 5 + (v >= 100000);
+ }
+ return 7 + (v >= 10000000UL);
+ }
+ if (v < 10000000000UL) {
+ return 9 + (v >= 1000000000UL);
+ }
+ return 11 + (v >= 100000000000UL);
+ }
+ return 12 + digits10(v / 1000000000000UL);
+}
+
+#if defined(__GNUC__) || defined(_WIN32)
+int mk_string_itop(uint64_t value, mk_ptr_t *p)
+{
+ static const char digits[201] =
+ "0001020304050607080910111213141516171819"
+ "2021222324252627282930313233343536373839"
+ "4041424344454647484950515253545556575859"
+ "6061626364656667686970717273747576777879"
+ "8081828384858687888990919293949596979899";
+
+ uint32_t const length = digits10(value);
+ uint32_t next = length - 1;
+ char *dst = p->data;
+
+ while (value >= 100) {
+ int const i = (value % 100) * 2;
+ value /= 100;
+ dst[next] = digits[i + 1];
+ dst[next - 1] = digits[i];
+ next -= 2;
+ }
+
+ /* Handle last 1-2 digits */
+ if (value < 10) {
+ dst[next] = '0' + (uint32_t) value;
+ }
+ else {
+ int i = (uint32_t) value * 2;
+ dst[next] = digits[i + 1];
+ dst[next - 1] = digits[i];
+ }
+
+ dst = p->data + length;
+ *dst++ = '\r';
+ *dst++ = '\n';
+ *dst++ = '\0';
+
+ p->len = (dst - p->data - 1);
+ return p->len;
+}
+#endif
+
+/* Return a buffer with a new string from string */
+char *mk_string_copy_substr(const char *string, int pos_init, int pos_end)
+{
+ unsigned int size, bytes;
+ char *buffer = 0;
+
+ if (pos_init > pos_end) {
+ return NULL;
+ }
+
+ size = (unsigned int) (pos_end - pos_init) + 1;
+ if (size <= 2) {
+ size = 4;
+ }
+
+ buffer = mk_mem_alloc(size);
+
+ if (!buffer) {
+ return NULL;
+ }
+
+ bytes = pos_end - pos_init;
+ memcpy(buffer, string + pos_init, bytes);
+ buffer[bytes] = '\0';
+
+ return (char *) buffer;
+}
+
+char *mk_string_tolower(const char *in)
+{
+ char *out = mk_string_dup(in);
+ const char *ip = in;
+ char *op = out;
+
+ if (!out) {
+ return NULL;
+ }
+
+ while (*ip) {
+ *op = tolower(*ip);
+ ip++, op++;
+ }
+ *op = '\0';
+
+ return out;
+}