Initial commit
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) [year] [fullname]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
76
Makefile
Normal file
76
Makefile
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Compiler Flags
|
||||||
|
CC := gcc
|
||||||
|
CFLAGS := -g -Wall -Wextra -Werror -pedantic -fsanitize=address,undefined -fno-omit-frame-pointer
|
||||||
|
|
||||||
|
# Directory variables
|
||||||
|
LIBDIR := lib
|
||||||
|
OBJ := obj
|
||||||
|
INC := include
|
||||||
|
SRC := src
|
||||||
|
TEST := tests
|
||||||
|
|
||||||
|
# Filepath Pattern Matching
|
||||||
|
LIB := $(LIBDIR)/lib.a
|
||||||
|
SRCS := $(wildcard $(SRC)/*.c)
|
||||||
|
OBJS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
|
||||||
|
TESTS := $(wildcard $(TEST)/*.c)
|
||||||
|
TESTBINS := $(patsubst $(TEST)/%.c, $(TEST)/bin/%, $(TESTS))
|
||||||
|
|
||||||
|
# Commands must be labeled PHONY
|
||||||
|
.PHONY: all release clean test
|
||||||
|
|
||||||
|
# Compiler Release Flags
|
||||||
|
release: CFLAGS := -Wall -Wextra -Werror -pedantic -fsanitize=address,undefined -fno-omit-frame-pointer -O2 -DNDEBUG
|
||||||
|
release: clean $(LIB)
|
||||||
|
|
||||||
|
# Target for compilation.
|
||||||
|
all: $(LIB)
|
||||||
|
|
||||||
|
# Target / Dependencies
|
||||||
|
$(LIB): $(OBJS) | $(LIBDIR)
|
||||||
|
$(RM) $(LIB)
|
||||||
|
ar -cvrs $@ $^
|
||||||
|
|
||||||
|
$(OBJ)/%.o: $(SRC)/%.c $(SRC)/%.h | $(OBJ)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(OBJ)/%.o: $(SRC)/%.c | $(OBJ)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(TEST)/bin/%: $(TEST)/%.c $(LIB) | $(TEST)/bin
|
||||||
|
$(CC) $(CFLAGS) $< $(LIB) -o $@
|
||||||
|
|
||||||
|
# Make directories if none.
|
||||||
|
$(LIBDIR):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
$(INC):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
$(OBJ):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
$(TEST)/bin:
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
# Run the tests in the bin folder and track results
|
||||||
|
test: $(LIB) $(TEST)/bin $(TESTBINS)
|
||||||
|
@SUCCESS_COUNT=0; FAILURE_COUNT=0; \
|
||||||
|
for test in $(TESTBINS); do \
|
||||||
|
./$$test; \
|
||||||
|
EXIT_CODE=$$?; \
|
||||||
|
TEST_NAME=$(notdir $$test); \
|
||||||
|
if [ $$EXIT_CODE -eq 0 ]; then \
|
||||||
|
echo "\033[0;32m$$TEST_NAME: EXIT CODE: $$EXIT_CODE (SUCCESS)\033[0m"; \
|
||||||
|
SUCCESS_COUNT=$$((SUCCESS_COUNT + 1)); \
|
||||||
|
else \
|
||||||
|
echo "\033[0;31m$$TEST_NAME: EXIT CODE: $$EXIT_CODE (FAILURE)\033[0m"; \
|
||||||
|
FAILURE_COUNT=$$((FAILURE_COUNT + 1)); \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
echo "\n\nTests completed"; \
|
||||||
|
echo "SUCCESS: $$SUCCESS_COUNT"; \
|
||||||
|
echo "FAILURE: $$FAILURE_COUNT";
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) -r $(LIBDIR) $(OBJ) $(TEST)/bin/
|
||||||
28
README.md
Normal file
28
README.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# sv
|
||||||
|
|
||||||
|
## Description
|
||||||
|
String View implementation written in c.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Description](#description)
|
||||||
|
- [Features](#features)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [Credits / Resources](#credits--resources)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
## Features / TODOS
|
||||||
|
+ Easy strings.
|
||||||
|
+ Safe access.
|
||||||
|
+ Clear semantics
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## Credits / Resources
|
||||||
|
[Mongoose Webserver](https://mongoose.ws/)<br>
|
||||||
|
[Tsoding SV](https://github.com/tsoding/sv)<br>
|
||||||
|
[C Interfaces and Implementations - David Hanson](https://github.com/drh/cii)<br>
|
||||||
|
|
||||||
|
## License
|
||||||
|
This project is licensed under MIT - see the [LICENSE](LICENSE) file for details.
|
||||||
34
include/sv.h
Normal file
34
include/sv.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef SV_INCLUDED
|
||||||
|
#define SV_INCLUDED
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
struct String_View {
|
||||||
|
size_t len;
|
||||||
|
const char *buf;
|
||||||
|
};
|
||||||
|
typedef struct String_View SV;
|
||||||
|
|
||||||
|
// Macros for String_View printf
|
||||||
|
#define SV_FMT "%.*s"
|
||||||
|
#define SV_ARG(sv) (int) (sv).len, (sv).buf
|
||||||
|
|
||||||
|
// Null String
|
||||||
|
#define SV_NULL sv_strn(NULL, 0)
|
||||||
|
|
||||||
|
extern struct String_View sv_str(const char *s);
|
||||||
|
extern struct String_View sv_strn(const char *s, size_t n);
|
||||||
|
extern struct String_View sv_trim_left(struct String_View sv);
|
||||||
|
extern struct String_View sv_trim_right(struct String_View sv);
|
||||||
|
extern struct String_View sv_trim(struct String_View sv);
|
||||||
|
extern int sv_eq(const struct String_View sv1, const struct String_View sv2);
|
||||||
|
extern int sv_casecmp( const struct String_View sv1, const struct String_View sv2);
|
||||||
|
extern struct String_View sv_before_delim(const struct String_View sv,
|
||||||
|
const char *delims);
|
||||||
|
extern struct String_View sv_after_delim(const struct String_View sv,
|
||||||
|
const char *delims);
|
||||||
|
extern struct String_View sv_str_str(const struct String_View haystack,
|
||||||
|
const struct String_View needle);
|
||||||
|
extern size_t sv_pack_size(const struct String_View sv);
|
||||||
|
extern void sv_pack(unsigned char *buf, const struct String_View sv);
|
||||||
|
extern struct String_View sv_unpack(unsigned char *buf);
|
||||||
|
#endif
|
||||||
152
src/sv.c
Normal file
152
src/sv.c
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
#include "../include/sv.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static bool sv_is_space(int c) {
|
||||||
|
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f';
|
||||||
|
}
|
||||||
|
static int sv_tolc(char c) {
|
||||||
|
return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
|
||||||
|
}
|
||||||
|
static void sv_pack_u64(uint64_t i, unsigned char *buf){
|
||||||
|
*buf++ = i>>56;
|
||||||
|
*buf++ = i>>48;
|
||||||
|
*buf++ = i>>40;
|
||||||
|
*buf++ = i>>32;
|
||||||
|
*buf++ = i>>24;
|
||||||
|
*buf++ = i>>16;
|
||||||
|
*buf++ = i>>8;
|
||||||
|
*buf++ = i;
|
||||||
|
}
|
||||||
|
static uint64_t sv_unpack_u64(unsigned char *buf){
|
||||||
|
return ((unsigned long long int)buf[0]<<56) |
|
||||||
|
((unsigned long long int)buf[1]<<48) |
|
||||||
|
((unsigned long long int)buf[2]<<40) |
|
||||||
|
((unsigned long long int)buf[3]<<32) |
|
||||||
|
((unsigned long long int)buf[4]<<24) |
|
||||||
|
((unsigned long long int)buf[5]<<16) |
|
||||||
|
((unsigned long long int)buf[6]<<8) |
|
||||||
|
buf[7];
|
||||||
|
}
|
||||||
|
struct String_View sv_str(const char *s) {
|
||||||
|
struct String_View str = {s == NULL ? 0 : strlen(s), (char *) s };
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
struct String_View sv_strn(const char *s, size_t n) {
|
||||||
|
struct String_View str = {n, (char *) s};
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct String_View sv_trim(struct String_View s){
|
||||||
|
while (s.len > 0 && sv_is_space((int) *s.buf)) s.buf++, s.len--;
|
||||||
|
while (s.len > 0 && sv_is_space((int) *(s.buf + s.len - 1))) s.len--;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
struct String_View sv_trim_left(struct String_View s){
|
||||||
|
while (s.len > 0 && sv_is_space((int) *s.buf)) s.buf++, s.len--;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
struct String_View sv_trim_right(struct String_View s){
|
||||||
|
|
||||||
|
while (s.len > 0 && sv_is_space((int) *(s.buf + s.len - 1))) s.len--;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sv_eq( const struct String_View sv1, const struct String_View sv2){
|
||||||
|
if (sv1.len != sv2.len) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return memcmp(sv1.buf, sv2.buf, sv1.len) == 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int sv_casecmp(const struct String_View sv1, const struct String_View sv2){
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < sv1.len && i < sv2.len) {
|
||||||
|
int c1 = sv_tolc(sv1.buf[i]);
|
||||||
|
int c2 = sv_tolc(sv2.buf[i]);
|
||||||
|
if (c1 < c2) return -1;
|
||||||
|
if (c1 > c2) return 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < sv1.len) return 1;
|
||||||
|
if (i < sv2.len) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct String_View sv_before_delim(const struct String_View sv,const char *delims){
|
||||||
|
// Handle NULL pointer or empty string view
|
||||||
|
if (sv.buf == NULL || delims == NULL) {
|
||||||
|
return sv_strn(NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < sv.len) {
|
||||||
|
// Check if the current character is a delimiter
|
||||||
|
for (size_t j = 0; delims[j] != '\0'; j++) {
|
||||||
|
if (sv.buf[i] == delims[j]) {
|
||||||
|
struct String_View result = sv_strn(sv.buf, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the whole string if no delimiter was found
|
||||||
|
struct String_View result = sv_strn(sv.buf, i);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
struct String_View sv_after_delim(const struct String_View sv, const char *delims){
|
||||||
|
// Handle NULL pointer or empty string view
|
||||||
|
if (sv.buf == NULL || delims == NULL) {
|
||||||
|
return sv_strn(NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < sv.len) {
|
||||||
|
// Check if the current character is a delimiter
|
||||||
|
for (size_t j = 0; delims[j] != '\0'; j++) {
|
||||||
|
if (sv.buf[i] == delims[j]) {
|
||||||
|
struct String_View result = sv_strn(sv.buf+i+1, sv.len-i-1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the whole string if no delimiter was found
|
||||||
|
struct String_View result = sv_strn(sv.buf, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct String_View sv_str_str(const struct String_View haystack, const struct String_View needle){
|
||||||
|
size_t i;
|
||||||
|
if (needle.len > haystack.len) return sv_strn(NULL,0);
|
||||||
|
if (needle.len == 0) return haystack;
|
||||||
|
for (i = 0; i <= haystack.len - needle.len; i++) {
|
||||||
|
if (memcmp(haystack.buf + i, needle.buf, needle.len) == 0) {
|
||||||
|
return sv_strn(haystack.buf + i, haystack.len -i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sv_strn(NULL,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sv_pack_size(const struct String_View sv){
|
||||||
|
size_t result = 0;
|
||||||
|
result += sv.len;
|
||||||
|
result += sizeof(uint64_t);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void sv_pack(unsigned char *buf, const struct String_View sv){
|
||||||
|
sv_pack_u64(sv.len, buf);
|
||||||
|
size_t offset = sizeof(uint64_t);
|
||||||
|
memcpy(buf+offset, sv.buf, sv.len);
|
||||||
|
}
|
||||||
|
struct String_View sv_unpack(unsigned char *buf){
|
||||||
|
size_t len = sv_unpack_u64(buf);
|
||||||
|
return sv_strn((const char *)buf+sizeof(uint64_t),len);
|
||||||
|
}
|
||||||
15
tests/01_sv_str.c
Normal file
15
tests/01_sv_str.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello World!";
|
||||||
|
SV sv = sv_str(s);
|
||||||
|
|
||||||
|
assert(sv.buf != NULL);
|
||||||
|
assert(strlen(s) == sv.len);
|
||||||
|
assert( memcmp(sv.buf, s, strlen(s) ) == 0);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
15
tests/02_sv_strn.c
Normal file
15
tests/02_sv_strn.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello World!";
|
||||||
|
SV sv = sv_strn(s, strlen(s));
|
||||||
|
|
||||||
|
assert(sv.buf != NULL);
|
||||||
|
assert(strlen(s) == sv.len);
|
||||||
|
assert( memcmp(sv.buf, s, strlen(s) ) == 0);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
24
tests/03_trim_left.c
Normal file
24
tests/03_trim_left.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = " Hello World!";
|
||||||
|
const char *s2 = "Hello World!";
|
||||||
|
|
||||||
|
SV sv = sv_str(s);
|
||||||
|
|
||||||
|
assert(sv.buf != NULL);
|
||||||
|
assert(strlen(s) == sv.len);
|
||||||
|
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||||
|
SV sv2 = sv_trim_left(sv);
|
||||||
|
assert(sv2.len != strlen(s));
|
||||||
|
assert( memcmp(sv2.buf, s, sv2.len) != 0);
|
||||||
|
assert( memcmp(sv2.buf, s2, sv2.len) == 0);
|
||||||
|
assert( sv2.len == strlen(s2));
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
21
tests/04_trim_right.c
Normal file
21
tests/04_trim_right.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello World! ";
|
||||||
|
const char *s2 = "Hello World!";
|
||||||
|
|
||||||
|
SV sv = sv_str(s);
|
||||||
|
assert(sv.buf != NULL);
|
||||||
|
assert(strlen(s) == sv.len);
|
||||||
|
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||||
|
SV sv2 = sv_trim_right(sv);
|
||||||
|
assert(sv2.len == strlen(s2));
|
||||||
|
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||||
|
assert(sv2.len != strlen(s));
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
22
tests/05_trim.c
Normal file
22
tests/05_trim.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = " Hello World! ";
|
||||||
|
const char *s2 = "Hello World!";
|
||||||
|
|
||||||
|
SV sv = sv_str(s);
|
||||||
|
assert(sv.buf != NULL);
|
||||||
|
assert(strlen(s) == sv.len);
|
||||||
|
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||||
|
SV sv2 = sv_trim(sv);
|
||||||
|
assert(sv2.len == strlen(s2));
|
||||||
|
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||||
|
assert(sv2.len != strlen(s));
|
||||||
|
assert( memcmp(s, sv2.buf, sv2.len) != 0);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
25
tests/06_sv_eq.c
Normal file
25
tests/06_sv_eq.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = " Hello World! ";
|
||||||
|
const char *s2 = "Hello World!";
|
||||||
|
|
||||||
|
SV sv = sv_str(s);
|
||||||
|
SV sv3 = sv_str(s2);
|
||||||
|
assert(sv.buf != NULL);
|
||||||
|
assert(strlen(s) == sv.len);
|
||||||
|
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||||
|
SV sv2 = sv_trim(sv);
|
||||||
|
assert(sv2.len == strlen(s2));
|
||||||
|
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||||
|
assert(sv2.len != strlen(s));
|
||||||
|
assert( memcmp(s, sv2.buf, sv2.len) != 0);
|
||||||
|
assert( !sv_eq(sv, sv2));
|
||||||
|
assert( sv_eq(sv2,sv3));
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
29
tests/07_case_cmp.c
Normal file
29
tests/07_case_cmp.c
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = " Hello World! ";
|
||||||
|
const char *s2 = "Hello World!";
|
||||||
|
const char *s3 = "hElLo wOrLD!";
|
||||||
|
const char *s4 = "Goodbye World!";
|
||||||
|
|
||||||
|
SV sv = sv_str(s);
|
||||||
|
SV sv3 = sv_str(s3);
|
||||||
|
SV sv4 = sv_str(s4);
|
||||||
|
assert(sv.buf != NULL);
|
||||||
|
assert(strlen(s) == sv.len);
|
||||||
|
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||||
|
SV sv2 = sv_trim(sv);
|
||||||
|
assert(sv2.len == strlen(s2));
|
||||||
|
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||||
|
assert(sv2.len != strlen(s));
|
||||||
|
assert( memcmp(s, sv2.buf, sv2.len) != 0);
|
||||||
|
assert( !sv_eq(sv, sv2));
|
||||||
|
assert( sv_casecmp(sv2,sv3) == 0);
|
||||||
|
assert( sv_casecmp(sv3,sv4) == 1);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
18
tests/08_sv_before_delims.c
Normal file
18
tests/08_sv_before_delims.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello World!,Goodbye World!";
|
||||||
|
const char *s3 = "Hello World!";
|
||||||
|
|
||||||
|
struct String_View sv = sv_strn(s, strlen(s));
|
||||||
|
struct String_View sv2 = sv_before_delim(sv,",");
|
||||||
|
assert(sv2.len == strlen(s3));
|
||||||
|
assert( memcmp(sv2.buf, s3, sv2.len) == 0);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
18
tests/09_after_delims.c
Normal file
18
tests/09_after_delims.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello World!,Goodbye World!";
|
||||||
|
const char *s3 = "Goodbye World!";
|
||||||
|
|
||||||
|
struct String_View sv = sv_strn(s, strlen(s));
|
||||||
|
struct String_View sv2 = sv_after_delim(sv,",");
|
||||||
|
assert(sv2.len == strlen(s3));
|
||||||
|
assert( memcmp(sv2.buf, s3, sv2.len) == 0);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
20
tests/10_strstr.c
Normal file
20
tests/10_strstr.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello World!,Goodbye World!";
|
||||||
|
const char *n = "Goodbye";
|
||||||
|
const char *test = "Goodbye World!";
|
||||||
|
struct String_View sv = sv_strn(s, strlen(s));
|
||||||
|
struct String_View sv2 = sv_strn(n, strlen(n));
|
||||||
|
|
||||||
|
struct String_View found = sv_str_str(sv, sv2);
|
||||||
|
assert(found.len == strlen(test));
|
||||||
|
assert( memcmp(found.buf, test, found.len) == 0);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
24
tests/11_sv_pack.c
Normal file
24
tests/11_sv_pack.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello";
|
||||||
|
struct String_View sv = sv_strn(s, strlen(s));
|
||||||
|
size_t offset = sv_pack_size(sv);
|
||||||
|
unsigned char *buf = malloc(offset);
|
||||||
|
|
||||||
|
sv_pack(buf, sv);
|
||||||
|
|
||||||
|
struct String_View out = sv_unpack(buf);
|
||||||
|
assert(out.len == strlen(s));
|
||||||
|
assert( memcmp(out.buf, s, out.len) == 0);
|
||||||
|
assert( sv_eq(sv, out));
|
||||||
|
assert( sv_casecmp(sv, out ) == 0);
|
||||||
|
free(buf);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
21
tests/12_sv_pack2.c
Normal file
21
tests/12_sv_pack2.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../include/sv.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
const char *s = "Hello";
|
||||||
|
size_t offset = strlen(s) + sizeof(uint64_t);
|
||||||
|
unsigned char *buf = malloc(offset);
|
||||||
|
struct String_View sv = sv_strn(s, strlen(s));
|
||||||
|
sv_pack(buf, sv);
|
||||||
|
|
||||||
|
struct String_View out = sv_unpack(buf);
|
||||||
|
assert(out.len == strlen(s));
|
||||||
|
assert( memcmp(out.buf, s, out.len) == 0);
|
||||||
|
free(buf);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user