refactor(build): add static_library

This commit is contained in:
2025-09-12 01:43:26 +02:00
parent 25e259ae07
commit 56fa31d087
13 changed files with 349 additions and 152 deletions

View File

@@ -13,6 +13,16 @@ All the features listed are Thread-safe.
- Vectors - Vectors
- Stack - Stack
## Installation
Clone the repo, and then using `meson` install it:
```
$ meson setup build
$ cd build
$ meson install
```
## Usage ## Usage
See the `test/` folder for examples. See the `test/` folder for examples.

View File

@@ -5,27 +5,42 @@ project(
default_options: ['c_std=c17','warning_level=3'], default_options: ['c_std=c17','warning_level=3'],
) )
src = files( cc = meson.get_compiler('c')
# Sources without test files
lib_src = files(
'hashmap/myhashmap.c', 'hashmap/myhashmap.c',
'queue/myqueue.c', 'queue/myqueue.c',
'string/mystring.c', 'string/mystring.c',
'vector/myvector.c', 'vector/myvector.c',
'stack/mystack.c', 'stack/mystack.c',
'socket/mysocket.c',
) )
testlib = files( # Test files
test_src = files(
'test/test.c', 'test/test.c',
'test/hashmap/hm1.c', 'test/hashmap/hm1.c',
'test/queue/q1.c', 'test/queue/queue1.c',
'test/string/str1.c', 'test/string/str1.c',
'test/string/str2.c', 'test/string/str2.c',
'test/string/str3.c', 'test/string/str3.c',
'test/vector/v1.c', 'test/vector/vec1.c',
'test/stack/s1.c', 'test/stack/stack1.c',
'test/socket/socket1.c',
) )
sources = src + testlib # Windows Socket lib
winsock_dep = cc.find_library('ws2_32', required: false)
inc_dir = include_directories('string', 'queue', 'hashmap', 'vector') # Include directories
inc_dir = include_directories('string', 'queue', 'hashmap', 'vector', 'stack', 'socket')
executable('testlib', sources, include_directories: inc_dir) # Static library
myclib_lib = static_library('myclib', lib_src, include_directories: inc_dir, dependencies: winsock_dep, install: true)
# Install headers
install_headers(['hashmap/myhashmap.h', 'queue/myqueue.h', 'string/mystring.h', 'vector/myvector.h', 'stack/mystack.h', 'socket/mysocket.h'], subdir: 'myclib')
# Test executable
executable('testlib', lib_src + test_src, include_directories: inc_dir, dependencies: winsock_dep)

28
set/myset.c Normal file
View File

@@ -0,0 +1,28 @@
#include "myset.h"
#include <stdlib.h>
set_s *set_new(size_t element_size) {
if (element_size == 0) {
return NULL;
}
set_s *set = (set_s *)malloc(sizeof(set_s));
if (set == NULL) {
return NULL;
}
// TODO: think about how to deal the free_value for each element
return set;
}
int set_add(set_s *set, void *elem);
int set_remove(set_s *set, void *elem);
int set_clear(set_s *set);
int set_contains(set_s *set, void *elem);
void set_free(set_s *set);

27
set/myset.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef MYCLIB_SET_H
#define MYCLIB_SET_H
// TODO: WIP
#include <threads.h>
#include "../hashmap/myhashmap.h"
typedef struct set {
hashmap_s *map;
mtx_t lock;
} set_s;
set_s *set_new(size_t element_size);
int set_add(set_s *set, void *elem);
int set_remove(set_s *set, void *elem);
int set_clear(set_s *set);
int set_contains(set_s *set, void *elem);
void set_free(set_s *set);
#endif

39
socket/mysocket.c Normal file
View File

@@ -0,0 +1,39 @@
#include "mysocket.h"
#include <winsock2.h>
int sock_platform_init() {
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
return -1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
WSACleanup();
return -1;
}
#endif
return 0;
}
int sock_close(int socket) {
int ret = 0;
#ifdef _WIN32
ret = closesocket(socket);
#else
ret = close(socket);
#endif
return ret;
}
int sock_platform_shutdown() {
#ifdef _WIN32
WSACleanup();
#endif
return 0;
}

27
socket/mysocket.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef MYCLIB_SOCKET_H
#define MYCLIB_SOCKET_H
#ifdef _WIN32
/* Windows */
#include <winsock2.h>
#include <ws2tcpip.h>
#else
/* Unix */
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#endif
/* Run this before everything */
int sock_platform_init();
/* Use this to close a socket */
int sock_close(int socket);
/* Use at exit */
int sock_platform_shutdown();
#endif

View File

@@ -363,7 +363,7 @@ int string_tolower(string_s *string) {
/* Build Longest Prefix Suffix array */ /* Build Longest Prefix Suffix array */
static void build_lps(int *lps, const char *substring, size_t sub_len) { static void build_lps(int *lps, const char *substring, size_t sub_len) {
size_t len = 0; int len = 0;
size_t i = 1; size_t i = 1;
while (i < sub_len) { while (i < sub_len) {
@@ -396,8 +396,9 @@ int string_find(string_s *string, const char *substring) {
} }
size_t sub_len = strlen(substring); size_t sub_len = strlen(substring);
int lps[sub_len];
memset(lps, 0, sizeof(lps)); int *lps = (int *)malloc(sub_len * sizeof(int));
memset(lps, 0, sub_len * sizeof(int));
build_lps(lps, substring, sub_len); build_lps(lps, substring, sub_len);
size_t i = 0; /* string iterator */ size_t i = 0; /* string iterator */
@@ -407,9 +408,10 @@ int string_find(string_s *string, const char *substring) {
i++; i++;
j++; j++;
if (j == sub_len) { if (j == sub_len) {
free(lps);
mtx_unlock(&string->lock); mtx_unlock(&string->lock);
return i - j; return (int)(i - j);
} }
} else { } else {
if (j != 0) { if (j != 0) {
@@ -420,6 +422,8 @@ int string_find(string_s *string, const char *substring) {
} }
} }
free(lps);
mtx_unlock(&string->lock); mtx_unlock(&string->lock);
return -1; return -1;

View File

@@ -2,7 +2,7 @@
#include "../../queue/myqueue.h" #include "../../queue/myqueue.h"
void test_q1(void) { void test_queue1(void) {
/* Allocate a new queue */ /* Allocate a new queue */
queue_s *queue = queue_new(3, sizeof(int)); queue_s *queue = queue_new(3, sizeof(int));
assert(queue != NULL); assert(queue != NULL);

40
test/socket/socket1.c Normal file
View File

@@ -0,0 +1,40 @@
#include <stdio.h>
#include "../../socket/mysocket.h"
void test_socket1() {
sock_platform_init();
struct addrinfo hints, *res, *p;
char ipstr[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
char hostname[1024];
printf("hostname> ");
fscanf(stdin, "%s", hostname);
if (getaddrinfo(hostname, NULL, &hints, &res) != 0) {
fprintf(stderr, "getaddrinfo()\n");
sock_platform_shutdown();
}
for (p = res; p != NULL; p = p->ai_next) {
void *addr = 0;
char *ipver = 0;
struct sockaddr_in *ipv4;
if (p->ai_family == AF_INET) {
ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = "IPv4";
} else {
continue;
}
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
printf("%s: %s\n", ipver, ipstr);
}
sock_platform_shutdown();
}

View File

@@ -3,7 +3,7 @@
#include "../../stack/mystack.h" #include "../../stack/mystack.h"
void test_s1(void) { void test_stack1(void) {
stack_s *stack = stack_new(32, sizeof(int)); stack_s *stack = stack_new(32, sizeof(int));
int num = 10; int num = 10;
stack_push(stack, &num); stack_push(stack, &num);

View File

@@ -7,15 +7,17 @@
void test_hm1(void); void test_hm1(void);
void test_q1(void); void test_queue1(void);
void test_str1(void); void test_str1(void);
void test_str2(void); void test_str2(void);
void test_str3(void); void test_str3(void);
void test_v1(void); void test_vec1(void);
void test_s1(void); void test_stack1(void);
void test_socket1();
int main(void) { int main(void) {
puts("==== [Running Hashmap tests] ===="); puts("==== [Running Hashmap tests] ====");
@@ -24,7 +26,7 @@ int main(void) {
puts(""); puts("");
puts("==== [Running Queue tests] ===="); puts("==== [Running Queue tests] ====");
test_q1(); test_queue1();
puts("OK!"); puts("OK!");
puts(""); puts("");
@@ -36,12 +38,17 @@ int main(void) {
puts(""); puts("");
puts("==== [Running Vector tests] ===="); puts("==== [Running Vector tests] ====");
test_v1(); test_vec1();
puts("OK!"); puts("OK!");
puts(""); puts("");
puts("==== [Running Stack tests] ===="); puts("==== [Running Stack tests] ====");
test_s1(); test_stack1();
puts("OK!");
puts("");
puts("==== [Running Socket tests] ====");
test_socket1();
puts("OK!"); puts("OK!");
puts(""); puts("");

View File

@@ -30,7 +30,7 @@ int my_cmp(const void *a, const void *b) {
return ma->age - mb->age; return ma->age - mb->age;
} }
void test_v1() { void test_vec1() {
/* Allocate a new vector */ /* Allocate a new vector */
size_t elem_size = sizeof(my_elem_s); size_t elem_size = sizeof(my_elem_s);
vec_s *v = vec_new(10, elem_size); vec_s *v = vec_new(10, elem_size);

View File

@@ -90,11 +90,11 @@ void vec_free(vec_s *vec) {
size_t vec_size(vec_s *vec) { size_t vec_size(vec_s *vec) {
if (vec == NULL) { if (vec == NULL) {
return -1; return (size_t)-1;
} }
if (mtx_lock(&vec->lock) != thrd_success) { if (mtx_lock(&vec->lock) != thrd_success) {
return -1; return (size_t)-1;
} }
size_t size = vec->size; size_t size = vec->size;
@@ -106,11 +106,11 @@ size_t vec_size(vec_s *vec) {
size_t vec_cap(vec_s *vec) { size_t vec_cap(vec_s *vec) {
if (vec == NULL) { if (vec == NULL) {
return -1; return (size_t)-1;
} }
if (mtx_lock(&vec->lock) != thrd_success) { if (mtx_lock(&vec->lock) != thrd_success) {
return -1; return (size_t)-1;
} }
size_t cap = vec->capacity; size_t cap = vec->capacity;