7 n__str_8h
gullradriel edited this page 2026-10-25 10:46:33 +01:00

include/nilorea/n_str.h

N_STR and string function declaration. More...

Structures

Name
struct N_STR
A box including a string and his lenght.

Defines

Name
BAD_METACHARS
list of evil characters

Detailed Description

N_STR and string function declaration.

Author: Castagnier Mickael

Version: 2.0

Date: 05/02/14

Macros Documentation

define BAD_METACHARS

#define BAD_METACHARS "/-+&;`'\\\"|*?~<>^()[]{}$\n\r\t "

list of evil characters

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * 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.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#ifndef N_STRFUNC
#define N_STRFUNC

#define BAD_METACHARS "/-+&;`'\\\"|*?~<>^()[]{}$\n\r\t "

#ifdef __cplusplus
extern "C" {
#endif


#include "n_common.h"
#include "n_list.h"

/* forward declaration for n_str_template_expand (avoids pulling in n_hash.h) */
struct HASH_TABLE;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <math.h>
#include <fcntl.h>
#include <unistd.h>
#include <inttypes.h>

typedef size_t NSTRBYTE;

typedef struct N_STR {
    char* data;
    size_t length;
    size_t written;
} N_STR;

#define WILDMAT_ABORT -2
#define WILDMAT_NEGATE_CLASS '^'
#undef WILDMAT_MATCH_TAR_PATTERN

#define local_strdup(__src_)                                                                                         \
    ({                                                                                                               \
        char* __local_strdup_str = NULL;                                                                             \
        size_t __local_strdup_len = strlen((__src_));                                                                \
        Malloc(__local_strdup_str, char, __local_strdup_len + 1);                                                    \
        if (!__local_strdup_str) {                                                                                   \
            n_log(LOG_ERR, "Couldn't allocate %d byte for duplicating \"%s\"", (int)strlen((__src_)) + 1, (__src_)); \
        } else {                                                                                                     \
            for (size_t __local_strdup_it = 0; __local_strdup_it <= __local_strdup_len; __local_strdup_it++) {       \
                __local_strdup_str[__local_strdup_it] = (__src_)[__local_strdup_it];                                 \
            }                                                                                                        \
        }                                                                                                            \
        __local_strdup_str;                                                                                          \
    })

#define strprintf(__n_var, ...)                                           \
    ({                                                                    \
        char* __strprintf_ptr = NULL;                                     \
        if (!(__n_var)) {                                                 \
            int __needed = snprintf(NULL, 0, __VA_ARGS__);                \
            if (__needed > 0) {                                           \
                Malloc(__n_var, char, (size_t)__needed + 1);              \
                if (__n_var) {                                            \
                    snprintf(__n_var, (size_t)__needed + 1, __VA_ARGS__); \
                    __strprintf_ptr = __n_var;                            \
                } else {                                                  \
                    n_log(LOG_ERR, "couldn't allocate %s with %d bytes",  \
                          #__n_var, __needed + 1);                        \
                }                                                         \
            }                                                             \
        } else {                                                          \
            n_log(LOG_ERR, "%s is already allocated.", #__n_var);         \
        }                                                                 \
        __strprintf_ptr;                                                  \
    })

#define nstrprintf(__nstr_var, __format, ...) \
    nstrprintf_ex(&(__nstr_var), (__format), ##__VA_ARGS__)

#define nstrprintf_cat(__nstr_var, __format, ...) \
    nstrprintf_cat_ex(&(__nstr_var), (__format), ##__VA_ARGS__)

#define nstrcat(__nstr_dst, __nstr_src)                                                          \
    ({                                                                                           \
        N_STR* __nstrcat_ret = NULL;                                                             \
        if (__nstr_src && __nstr_src->data) {                                                    \
            __nstrcat_ret = nstrcat_ex(&(__nstr_dst), __nstr_src->data, __nstr_src->written, 1); \
        }                                                                                        \
        __nstrcat_ret;                                                                           \
    })

#define nstrcat_bytes(__nstr_dst, __void_src) \
    nstrcat_bytes_ex(&(__nstr_dst), __void_src, strlen(__void_src))

#define n_remove_ending_cr(__nstr_var)                                                                                        \
    do {                                                                                                                      \
        if (__nstr_var && __nstr_var->data && __nstr_var->written > 0 && __nstr_var->data[__nstr_var->written - 1] == '\r') { \
            __nstr_var->data[__nstr_var->written - 1] = '\0';                                                                 \
            __nstr_var->written--;                                                                                            \
        }                                                                                                                     \
    } while (0)

#define n_replace_cr(__nstr_var, __replacement)                                    \
    do {                                                                           \
        if (__nstr_var && __nstr_var->data && __nstr_var->written > 0) {           \
            char* __replaced = str_replace(__nstr_var->data, "\r", __replacement); \
            if (__replaced) {                                                      \
                Free(__nstr_var->data);                                            \
                __nstr_var->data = __replaced;                                     \
                __nstr_var->written = strlen(__nstr_var->data);                    \
                __nstr_var->length = __nstr_var->written + 1;                      \
            }                                                                      \
        }                                                                          \
    } while (0)

#ifdef __windows__
const char* strcasestr(const char* s1, const char* s2);
#endif

char* trim_nocopy(char* s);
char* trim(const char* s);
char* nfgets(char* buffer, NSTRBYTE size, FILE* stream);
N_STR* new_nstr(NSTRBYTE size);
int empty_nstr(N_STR* nstr);
N_STR* nstrdup(N_STR* msg);
int char_to_nstr_ex(const char* from, NSTRBYTE nboct, N_STR** to);
N_STR* char_to_nstr(const char* src);
int char_to_nstr_nocopy_ex(char* from, NSTRBYTE nboct, N_STR** to);
N_STR* char_to_nstr_nocopy(char* src);
N_STR* nstrcat_ex(N_STR** dest, void* src, NSTRBYTE size, int resize_flag);
N_STR* nstrcat_bytes_ex(N_STR** dest, void* src, NSTRBYTE size);
int resize_nstr(N_STR* nstr, size_t size);
N_STR* nstrprintf_ex(N_STR** nstr_var, const char* format, ...) N_PRINTF_FORMAT(2, 3);
N_STR* nstrprintf_cat_ex(N_STR** nstr_var, const char* format, ...) N_PRINTF_FORMAT(2, 3);
N_STR* file_to_nstr(char* filename);
int nstr_to_fd(N_STR* str, FILE* out, int lock);
int nstr_to_file(N_STR* n_str, char* filename);

#define free_nstr(__ptr)                                    \
    {                                                       \
        if ((*__ptr)) {                                     \
            _free_nstr(__ptr);                              \
        } else {                                            \
            n_log(LOG_DEBUG, "%s is already NULL", #__ptr); \
        }                                                   \
    }

int _free_nstr(N_STR** ptr);
void free_nstr_ptr(void* ptr);
int free_nstr_nolog(N_STR** ptr);
void free_nstr_ptr_nolog(void* ptr);
int str_to_long_ex(const char* s, NSTRBYTE start, NSTRBYTE end, long int* i, const int base);
int str_to_long(const char* s, long int* i, const int base);
int str_to_long_long_ex(const char* s, NSTRBYTE start, NSTRBYTE end, long long int* i, const int base);
int str_to_long_long(const char* s, long long int* i, const int base);
int str_to_int_ex(const char* s, NSTRBYTE start, NSTRBYTE end, int* i, const int base);
int str_to_int_nolog(const char* s, NSTRBYTE start, NSTRBYTE end, int* i, const int base, N_STR** infos);
int str_to_int(const char* s, int* i, const int base);
int skipw(const char* string, char toskip, NSTRBYTE* iterator, int inc);
int skipu(const char* string, char toskip, NSTRBYTE* iterator, int inc);
int strup(const char* string, char* dest);
int strlo(const char* string, char* dest);
int strcpy_u(const char* from, char* to, NSTRBYTE to_size, char delim, NSTRBYTE* it);
char** split(const char* str, const char* delim, int empty);
int split_count(char** split_result);
int free_split_result(char*** tab);
char* join(char** splitresult, const char* delim);
int write_and_fit_ex(char** dest, NSTRBYTE* size, NSTRBYTE* written, const char* src, NSTRBYTE src_size, NSTRBYTE additional_padding);
int write_and_fit(char** dest, NSTRBYTE* size, NSTRBYTE* written, const char* src);
int scan_dir(const char* dir, LIST* result, const int recurse);
int scan_dir_ex(const char* dir, const char* pattern, LIST* result, const int recurse, const int mode);
int wildmat(register const char* text, register const char* p);
int wildmatcase(register const char* text, register const char* p);
char* str_replace(const char* string, const char* substr, const char* replacement);
int str_natcasecmp(const char* a, const char* b);
int str_natncasecmp(const char* a, size_t alen, const char* b, size_t blen);
int str_sanitize_ex(char* string, const NSTRBYTE string_len, const char* mask, const NSTRBYTE masklen, const char replacement);
int str_sanitize(char* string, const char* mask, const char replacement);

N_STR* n_str_template_expand(const char* tmpl, struct HASH_TABLE* vars);

N_STR* n_str_url_encode(const char* src);

int n_str_utf8_valid(const char* s, size_t len);


#ifdef __cplusplus
}
#endif
/* #ifndef N_STR*/
#endif