refactor(build): add static_library
This commit is contained in:
10
README.md
10
README.md
@@ -13,6 +13,16 @@ All the features listed are Thread-safe.
|
||||
- Vectors
|
||||
- Stack
|
||||
|
||||
## Installation
|
||||
|
||||
Clone the repo, and then using `meson` install it:
|
||||
|
||||
```
|
||||
$ meson setup build
|
||||
$ cd build
|
||||
$ meson install
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
See the `test/` folder for examples.
|
||||
|
||||
31
meson.build
31
meson.build
@@ -5,27 +5,42 @@ project(
|
||||
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',
|
||||
'queue/myqueue.c',
|
||||
'string/mystring.c',
|
||||
'vector/myvector.c',
|
||||
'stack/mystack.c',
|
||||
'socket/mysocket.c',
|
||||
)
|
||||
|
||||
testlib = files(
|
||||
# Test files
|
||||
test_src = files(
|
||||
'test/test.c',
|
||||
'test/hashmap/hm1.c',
|
||||
'test/queue/q1.c',
|
||||
'test/queue/queue1.c',
|
||||
'test/string/str1.c',
|
||||
'test/string/str2.c',
|
||||
'test/string/str3.c',
|
||||
'test/vector/v1.c',
|
||||
'test/stack/s1.c',
|
||||
'test/vector/vec1.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
28
set/myset.c
Normal 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
27
set/myset.h
Normal 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
39
socket/mysocket.c
Normal 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
27
socket/mysocket.h
Normal 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
|
||||
@@ -363,7 +363,7 @@ int string_tolower(string_s *string) {
|
||||
|
||||
/* Build Longest Prefix Suffix array */
|
||||
static void build_lps(int *lps, const char *substring, size_t sub_len) {
|
||||
size_t len = 0;
|
||||
int len = 0;
|
||||
size_t i = 1;
|
||||
|
||||
while (i < sub_len) {
|
||||
@@ -396,8 +396,9 @@ int string_find(string_s *string, const char *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);
|
||||
|
||||
size_t i = 0; /* string iterator */
|
||||
@@ -407,9 +408,10 @@ int string_find(string_s *string, const char *substring) {
|
||||
i++;
|
||||
j++;
|
||||
if (j == sub_len) {
|
||||
free(lps);
|
||||
mtx_unlock(&string->lock);
|
||||
|
||||
return i - j;
|
||||
return (int)(i - j);
|
||||
}
|
||||
} else {
|
||||
if (j != 0) {
|
||||
@@ -420,6 +422,8 @@ int string_find(string_s *string, const char *substring) {
|
||||
}
|
||||
}
|
||||
|
||||
free(lps);
|
||||
|
||||
mtx_unlock(&string->lock);
|
||||
|
||||
return -1;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "../../queue/myqueue.h"
|
||||
|
||||
void test_q1(void) {
|
||||
void test_queue1(void) {
|
||||
/* Allocate a new queue */
|
||||
queue_s *queue = queue_new(3, sizeof(int));
|
||||
assert(queue != NULL);
|
||||
40
test/socket/socket1.c
Normal file
40
test/socket/socket1.c
Normal 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();
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "../../stack/mystack.h"
|
||||
|
||||
void test_s1(void) {
|
||||
void test_stack1(void) {
|
||||
stack_s *stack = stack_new(32, sizeof(int));
|
||||
int num = 10;
|
||||
stack_push(stack, &num);
|
||||
19
test/test.c
19
test/test.c
@@ -7,15 +7,17 @@
|
||||
|
||||
void test_hm1(void);
|
||||
|
||||
void test_q1(void);
|
||||
void test_queue1(void);
|
||||
|
||||
void test_str1(void);
|
||||
void test_str2(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) {
|
||||
puts("==== [Running Hashmap tests] ====");
|
||||
@@ -24,7 +26,7 @@ int main(void) {
|
||||
puts("");
|
||||
|
||||
puts("==== [Running Queue tests] ====");
|
||||
test_q1();
|
||||
test_queue1();
|
||||
puts("OK!");
|
||||
puts("");
|
||||
|
||||
@@ -36,12 +38,17 @@ int main(void) {
|
||||
puts("");
|
||||
|
||||
puts("==== [Running Vector tests] ====");
|
||||
test_v1();
|
||||
test_vec1();
|
||||
puts("OK!");
|
||||
puts("");
|
||||
|
||||
puts("==== [Running Stack tests] ====");
|
||||
test_s1();
|
||||
test_stack1();
|
||||
puts("OK!");
|
||||
puts("");
|
||||
|
||||
puts("==== [Running Socket tests] ====");
|
||||
test_socket1();
|
||||
puts("OK!");
|
||||
puts("");
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ int my_cmp(const void *a, const void *b) {
|
||||
return ma->age - mb->age;
|
||||
}
|
||||
|
||||
void test_v1() {
|
||||
void test_vec1() {
|
||||
/* Allocate a new vector */
|
||||
size_t elem_size = sizeof(my_elem_s);
|
||||
vec_s *v = vec_new(10, elem_size);
|
||||
@@ -90,11 +90,11 @@ void vec_free(vec_s *vec) {
|
||||
|
||||
size_t vec_size(vec_s *vec) {
|
||||
if (vec == NULL) {
|
||||
return -1;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (mtx_lock(&vec->lock) != thrd_success) {
|
||||
return -1;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
size_t size = vec->size;
|
||||
@@ -106,11 +106,11 @@ size_t vec_size(vec_s *vec) {
|
||||
|
||||
size_t vec_cap(vec_s *vec) {
|
||||
if (vec == NULL) {
|
||||
return -1;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (mtx_lock(&vec->lock) != thrd_success) {
|
||||
return -1;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
size_t cap = vec->capacity;
|
||||
|
||||
Reference in New Issue
Block a user