Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_nstr.c

Nilorea Library string api test.

Nilorea Library string api test

Author
Castagnier Mickael
Version
1.0
Date
26/05/2015
/*
* 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
*/
#include "nilorea/n_str.h"
#include "nilorea/n_log.h"
int main(void) {
char* chardest = NULL;
NSTRBYTE written = 0,
length = 0;
write_and_fit(&chardest, &length, &written, "Hello");
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit(&chardest, &length, &written, " ");
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit(&chardest, &length, &written, "world !");
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit(&chardest, &length, &written, "world ! ");
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit(&chardest, &length, &written, "world ! ");
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit(&chardest, &length, &written, "world ! ");
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
Free(chardest);
written = length = 0;
write_and_fit_ex(&chardest, &length, &written, "Hello", 5, 0);
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit_ex(&chardest, &length, &written, " ", 1, 0);
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit_ex(&chardest, &length, &written, "world !", 7, 0);
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit_ex(&chardest, &length, &written, "Hello", 5, 0);
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit_ex(&chardest, &length, &written, " ", 1, 10); // alocate 10 more byte if resize needed
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
write_and_fit_ex(&chardest, &length, &written, "world !", 7, 0);
n_log(LOG_INFO, "charstr (%d/%d): %s", written, length, chardest);
Free(chardest);
N_STR* nstr = NULL;
n_log(LOG_INFO, "NULL str:%s", _nstr(nstr));
nstrprintf(nstr, "Hello, file is %s line %d date %s", __FILE__, __LINE__, __TIME__);
n_log(LOG_INFO, "str:%s", _nstr(nstr));
nstrprintf_cat(nstr, " - This will be added at file %s line %d date %s", __FILE__, __LINE__, __TIME__);
n_log(LOG_INFO, "str:%s", _nstr(nstr));
free_nstr(&nstr);
nstr = new_nstr(0);
n_log(LOG_INFO, "EMPTY str:%s", _nstr(nstr));
nstrprintf(nstr, "Hello, file is %s line %d date %s", __FILE__, __LINE__, __TIME__);
n_log(LOG_INFO, "str:%s", _nstr(nstr));
nstrprintf_cat(nstr, " - This will be added at file %s line %d date %s", __FILE__, __LINE__, __TIME__);
n_log(LOG_INFO, "str:%s", _nstr(nstr));
nstrprintf_cat(nstr, " - some more texte");
N_STR* nstr2 = nstrdup(nstr);
n_log(LOG_INFO, "str: %s\n str2: %s", _nstr(nstr), _nstr(nstr2));
N_STR* nstr3 = NULL;
nstrcat(nstr3, nstr);
nstrcat(nstr3, nstr2);
n_log(LOG_INFO, "str:%s", _nstr(nstr3));
free_nstr(&nstr3);
nstr3 = new_nstr(10);
nstrcat(nstr3, nstr);
nstrcat(nstr3, nstr2);
n_log(LOG_INFO, "str:%s", _nstr(nstr3));
free_nstr(&nstr);
free_nstr(&nstr2);
free_nstr(&nstr3);
nstr = new_nstr(128);
char data[1048576] = "";
for (int it = 0; it < 1048575; it++) {
data[it] = (char)(32 + rand() % 63);
}
data[1048574] = '\0';
for (int it = 0; it < 100; it++) {
write_and_fit(&nstr->data, &nstr->length, &nstr->written, data);
}
free_nstr(&nstr);
/* test char_to_nstr and empty_nstr */
nstr = char_to_nstr("char_to_nstr test");
n_log(LOG_INFO, "char_to_nstr: %s", _nstr(nstr));
empty_nstr(nstr);
n_log(LOG_INFO, "after empty_nstr: '%s' written=%zu", _nstr(nstr), nstr->written);
free_nstr(&nstr);
/* test trim */
char* trimmed = trim(" spaces around ");
if (trimmed) {
n_log(LOG_INFO, "trim result: '%s'", trimmed);
Free(trimmed);
}
/* test trim_nocopy */
char trimbuf[] = " hello ";
char* trimptr = trim_nocopy(trimbuf);
n_log(LOG_INFO, "trim_nocopy result: '%s'", trimptr);
/* test str_to_int, str_to_long, str_to_long_long */
int ival = 0;
if (str_to_int("12345", &ival, 10) == TRUE) {
n_log(LOG_INFO, "str_to_int: %d", ival);
}
long int lval = 0;
if (str_to_long("9876543210", &lval, 10) == TRUE) {
n_log(LOG_INFO, "str_to_long: %ld", lval);
}
long long int llval = 0;
if (str_to_long_long("123456789012345", &llval, 10) == TRUE) {
n_log(LOG_INFO, "str_to_long_long: %lld", llval);
}
/* test strup, strlo */
char upper[32] = "";
char lower[32] = "";
strup("hello world", upper);
n_log(LOG_INFO, "strup: %s", upper);
strlo("HELLO WORLD", lower);
n_log(LOG_INFO, "strlo: %s", lower);
/* test split, split_count, join, free_split_result */
char** parts = split("one:two:three:four", ":", 0);
if (parts) {
int count = split_count(parts);
n_log(LOG_INFO, "split count: %d", count);
for (int it = 0; it < count; it++) {
n_log(LOG_INFO, " split[%d]: %s", it, parts[it]);
}
char* joined = join(parts, " - ");
if (joined) {
n_log(LOG_INFO, "join result: %s", joined);
Free(joined);
}
}
/* test wildmat, wildmatcase */
n_log(LOG_INFO, "wildmat(\"hello.txt\", \"*.txt\"): %d", wildmat("hello.txt", "*.txt"));
n_log(LOG_INFO, "wildmat(\"hello.txt\", \"*.csv\"): %d", wildmat("hello.txt", "*.csv"));
n_log(LOG_INFO, "wildmatcase(\"Hello.TXT\", \"*.txt\"): %d", wildmatcase("Hello.TXT", "*.txt"));
/* test str_replace */
char* replaced = str_replace("hello world hello", "hello", "bye");
if (replaced) {
n_log(LOG_INFO, "str_replace: %s", replaced);
Free(replaced);
}
/* test str_sanitize */
char sanitize_buf[] = "hello; rm -rf /";
str_sanitize(sanitize_buf, ";/", '_');
n_log(LOG_INFO, "str_sanitize: %s", sanitize_buf);
/* test file_to_nstr and nstr_to_file */
N_STR* file_content = char_to_nstr("file content test\nsecond line\n");
nstr_to_file(file_content, "nilorea_nstr_test.txt");
free_nstr(&file_content);
file_content = file_to_nstr("nilorea_nstr_test.txt");
if (file_content) {
n_log(LOG_INFO, "file_to_nstr: %s", _nstr(file_content));
free_nstr(&file_content);
}
/* an empty (0-byte) file is a valid read: file_to_nstr must return an empty
N_STR (data != NULL, written == 0), not NULL, and must log no error */
FILE* empty_fp = fopen("nilorea_nstr_empty.txt", "wb");
if (empty_fp)
fclose(empty_fp);
N_STR* empty_content = file_to_nstr("nilorea_nstr_empty.txt");
if (empty_content && empty_content->data && empty_content->written == 0)
n_log(LOG_INFO, "file_to_nstr on an empty file: OK (empty string, no error)");
else
n_log(LOG_ERR, "file_to_nstr on an empty file: FAILED (expected an empty N_STR)");
if (empty_content)
free_nstr(&empty_content);
/* test skipw, skipu */
char skipbuf[] = " hello";
NSTRBYTE it = 0;
skipw(skipbuf, ' ', &it, 1);
n_log(LOG_INFO, "skipw past spaces: pos=%zu char='%c'", it, skipbuf[it]);
it = 0;
skipu(skipbuf, 'h', &it, 1);
n_log(LOG_INFO, "skipu to 'h': pos=%zu char='%c'", it, skipbuf[it]);
/* test resize_nstr */
nstr = new_nstr(16);
n_log(LOG_INFO, "before resize: length=%zu", nstr->length);
resize_nstr(nstr, 256);
n_log(LOG_INFO, "after resize: length=%zu", nstr->length);
free_nstr(&nstr);
/* test scan_dir */
LIST* dir_list = new_generic_list(0);
if (scan_dir(".", dir_list, 0) == TRUE) {
n_log(LOG_INFO, "scan_dir found %zu entries", dir_list->nb_items);
}
list_destroy(&dir_list);
/* test n_str_url_encode */
int url_encode_errors = 0;
/* NULL input -> NULL */
N_STR* encoded = n_str_url_encode(NULL);
if (encoded != NULL) {
n_log(LOG_ERR, "FAIL: n_str_url_encode(NULL) expected NULL, got \"%s\"", _nstr(encoded));
url_encode_errors++;
free_nstr(&encoded);
} else {
n_log(LOG_INFO, "PASS: n_str_url_encode(NULL) == NULL");
}
/* empty string -> empty result */
encoded = n_str_url_encode("");
if (!encoded || strcmp(_nstr(encoded), "") != 0) {
n_log(LOG_ERR, "FAIL: n_str_url_encode(\"\") expected \"\", got \"%s\"", encoded ? _nstr(encoded) : "NULL");
url_encode_errors++;
} else {
n_log(LOG_INFO, "PASS: n_str_url_encode(\"\") == \"\"");
}
free_nstr(&encoded);
/* unreserved characters (A-Z a-z 0-9 - _ . ~) must be kept verbatim */
encoded = n_str_url_encode("Hello-World_1.0~");
if (!encoded || strcmp(_nstr(encoded), "Hello-World_1.0~") != 0) {
n_log(LOG_ERR, "FAIL: n_str_url_encode(\"Hello-World_1.0~\") expected verbatim, got \"%s\"", encoded ? _nstr(encoded) : "NULL");
url_encode_errors++;
} else {
n_log(LOG_INFO, "PASS: n_str_url_encode(\"Hello-World_1.0~\") == \"Hello-World_1.0~\"");
}
free_nstr(&encoded);
/* reserved / special characters must be percent-encoded */
encoded = n_str_url_encode("foo bar&baz=qux/path?q=1#frag");
const char* expected_reserved = "foo%20bar%26baz%3Dqux%2Fpath%3Fq%3D1%23frag";
if (!encoded || strcmp(_nstr(encoded), expected_reserved) != 0) {
n_log(LOG_ERR, "FAIL: n_str_url_encode(reserved chars) expected \"%s\", got \"%s\"", expected_reserved, encoded ? _nstr(encoded) : "NULL");
url_encode_errors++;
} else {
n_log(LOG_INFO, "PASS: n_str_url_encode(\"foo bar&baz=qux/path?q=1#frag\") == \"%s\"", expected_reserved);
}
free_nstr(&encoded);
/* bytes >= 0x80 (high-byte / non-ASCII) must be percent-encoded */
encoded = n_str_url_encode("\xC3\xA9\xFF");
if (!encoded || strcmp(_nstr(encoded), "%C3%A9%FF") != 0) {
n_log(LOG_ERR, "FAIL: n_str_url_encode(high bytes) expected \"%s\", got \"%s\"", "%C3%A9%FF", encoded ? _nstr(encoded) : "NULL");
url_encode_errors++;
} else {
n_log(LOG_INFO, "PASS: n_str_url_encode(\"\\xC3\\xA9\\xFF\") == \"%s\"", "%C3%A9%FF");
}
free_nstr(&encoded);
if (url_encode_errors > 0) {
n_log(LOG_ERR, "n_str_url_encode: %d test(s) failed", url_encode_errors);
exit(1);
}
exit(0);
}
int main(void)
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
Definition n_common.h:199
size_t nb_items
number of item currently in the list
Definition n_list.h:61
int list_destroy(LIST **list)
Empty and Free a list container.
Definition n_list.c:548
LIST * new_generic_list(size_t max_items)
Initialiaze a generic list container to max_items pointers.
Definition n_list.c:37
Structure of a generic LIST container.
Definition n_list.h:59
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_INFO
informational
Definition n_log.h:82
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
Definition n_str.h:68
char * data
the string
Definition n_str.h:63
size_t length
total allocation (in bytes) of the data buffer, padding included
Definition n_str.h:65
int str_to_long_long(const char *s, long long int *i, const int base)
Helper for string to integer.
Definition n_str.c:703
char * trim_nocopy(char *s)
trim and zero end the string, WARNING: keep and original pointer to delete the string correctly
Definition n_str.c:123
N_STR * n_str_url_encode(const char *src)
Percent-encode a C string per RFC 3986 (unreserved set kept as-is).
Definition n_str.c:1725
size_t NSTRBYTE
N_STR base unit.
Definition n_str.h:58
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
int split_count(char **split_result)
Count split elements.
Definition n_str.c:1000
int nstr_to_file(N_STR *str, char *filename)
Write a N_STR content into a file.
Definition n_str.c:424
char * join(char **splitresult, const char *delim)
join the array into a string
Definition n_str.c:1037
#define nstrcat(__nstr_dst, __nstr_src)
Macro to quickly concatenate two N_STR.
Definition n_str.h:125
N_STR * nstrdup(N_STR *str)
Duplicate a N_STR.
Definition n_str.c:716
int strlo(const char *string, char *dest)
Lower case a string.
Definition n_str.c:861
int write_and_fit(char **dest, NSTRBYTE *size, NSTRBYTE *written, const char *src)
Append src to *dest.
Definition n_str.c:1229
#define nstrprintf_cat(__nstr_var, __format,...)
Macro to quickly allocate and sprintf and cat to a N_STR.
Definition n_str.h:121
int resize_nstr(N_STR *nstr, size_t size)
reallocate a nstr internal buffer.
Definition n_str.c:1534
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
Definition n_str.c:255
int skipu(const char *string, char toskip, NSTRBYTE *iterator, int inc)
skip until 'toskip' occurence is found from 'iterator' to the next 'toskip' value.
Definition n_str.c:794
int empty_nstr(N_STR *nstr)
empty a N_STR string
Definition n_str.c:192
int wildmatcase(register const char *text, register const char *p)
Written by Rich Salz rsalz at osf.org, refurbished by me.
Definition n_str.c:1382
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
Definition n_str.c:207
char * str_replace(const char *string, const char *substr, const char *replacement)
Replace "substr" by "replacement" inside string taken from http://coding.debuntu.org/c-implementing-s...
Definition n_str.c:1448
char * trim(const char *s)
trim and put a \0 at the end, return new char *
Definition n_str.c:152
int skipw(const char *string, char toskip, NSTRBYTE *iterator, int inc)
skip while 'toskip' occurence is found from 'iterator' to the next non 'toskip' position.
Definition n_str.c:747
#define nstrprintf(__nstr_var, __format,...)
Macro to quickly allocate and sprintf to N_STR.
Definition n_str.h:117
int scan_dir(const char *dir, LIST *result, const int recurse)
Scan a list of directory and return a list of char *file.
Definition n_str.c:1240
int str_sanitize(char *string, const char *mask, const char replacement)
clean a string by replacing evil characteres
Definition n_str.c:1524
char ** split(const char *str, const char *delim, int empty)
split the strings into a an array of char *pointer , ended by a NULL one.
Definition n_str.c:920
int wildmat(register const char *text, register const char *p)
Written by Rich Salz rsalz at osf.org, refurbished by me.
Definition n_str.c:1318
int str_to_long(const char *s, long int *i, const int base)
Helper for string to integer.
Definition n_str.c:688
int write_and_fit_ex(char **dest, NSTRBYTE *size, NSTRBYTE *written, const char *src, NSTRBYTE src_size, NSTRBYTE additional_padding)
Append src_size bytes from src to *dest, updating size/written, growing the buffer if needed.
Definition n_str.c:1187
N_STR * file_to_nstr(char *filename)
Load a whole file into a N_STR.
Definition n_str.c:288
int free_split_result(char ***tab)
Free a split result allocated array.
Definition n_str.c:1016
int str_to_int(const char *s, int *i, const int base)
Helper for string to integer.
Definition n_str.c:553
int strup(const char *string, char *dest)
Upper case a string.
Definition n_str.c:840
A box including a string and his lenght.
Definition n_str.h:61
Generic log system.
N_STR and string function declaration.