Skip to content
Snippets Groups Projects
Commit a3cb4455 authored by iliya.saroukha's avatar iliya.saroukha
Browse files

feat: side project

parents
No related branches found
No related tags found
No related merge requests found
/.cache/
compile_commands.json
libvector*
vec_test
*.o
Makefile 0 → 100644
CC := clang
CFLAGS := -Wall -Wextra -g -pedantic -fPIC -fsanitize=address -fsanitize=leak -fsanitize=undefined
VPATH := struct
LDFLAGS := -L$(shell pwd)/ -lvector
SHELL := /bin/bash
TARGET := vec_test
$(TARGET): $(TARGET).o lib_dyn
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
$(TARGET).o: $(TARGET).c
$(CC) $(CFLAGS) -c -I$(shell pwd)/struct/ $<
.PHONY: lib_dyn
lib_dyn: vec.o
$(CC) $(CFLAGS) -shared -Wl,-soname,libvector.so.1 $^ -o libvector.so.1.0.0
@if [ ! -L libvector.so.1 ]; then \
ln -s libvector.so.1.0.0 libvector.so.1; \
fi
@if [ ! -L libvector.so ]; then \
ln -s libvector.so.1.0.0 libvector.so; \
fi
vec.o: vec.c vec.h
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean:
rm -f $(TARGET) *.o libvector.so libvector.so.1 libvector.so.1.0.0
#!/bin/bash
export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH
echo $LD_LIBRARY_PATH
#include "vec.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define err_init(x) \
if (x == NULL) { \
fprintf(stderr, "Function: %s [%s:%d]: `Vector not initialised!`\n\n", \
__func__, __FILE__, __LINE__); \
return; \
}
#define err_len_zero(x) \
if (x->len == 0) { \
fprintf(stderr, "Function: %s [%s:%d]: `Vector length is zero!`\n\n", \
__func__, __FILE__, __LINE__); \
return; \
}
#define print_arr(x, len) \
for (size_t i = 0; i < len; i++) { \
fprintf(stderr, "LOG:\tarr[%ld] -> %ld\n", i, x[i]); \
} \
fprintf(stderr, "\n");
struct _vec_t {
int64_t *data;
size_t len;
size_t capacity;
};
/**
* @brief Function that creates a vector based on an initial capacity specified
* by the user
*
* @param init_capacity Initial capacity specified
* @return Pointer to newly instantiated vector
*/
vec_t *vec_create(size_t init_capacity) {
if (init_capacity == 0) {
fprintf(stderr, "Initial size of the vector has to be a non-zero\n");
return NULL;
}
vec_t *vec = malloc(sizeof(vec_t));
if (vec == NULL) {
fprintf(stderr, "Allocation for new vector failed!\n");
return NULL;
}
vec->len = 0;
vec->capacity = init_capacity;
vec->data = malloc(init_capacity * sizeof(int64_t));
if (vec->data == NULL) {
fprintf(stderr, "Allocation for data member failed!\n");
return NULL;
}
return vec;
}
/**
* @brief Function that returns the current length of a given vector
*
* In case of an error, the value returned will be -1
*
* @param vec Vector whose length we'd like to obtain
* @return Length of vector OR -1 in case of an error
*/
ssize_t vec_length(vec_t *vec) {
if (vec == NULL) {
fprintf(stderr, "Vector not initialised!\n");
return -1;
}
return vec->len;
}
/**
* @brief Function that returns the value contained at a given index in the
* vector
*
* In case of an error, the value returned will be -1
*
* @param vec Vector from which we wish to obtain the value from a given index
* @param idx Index in the vector
* @return Value contained at the given index OR -1 in case of an error
*/
int64_t vec_get(vec_t *vec, size_t idx) {
if (vec == NULL) {
fprintf(stderr, "Vector not initialised!\n");
return -1;
}
if (idx > vec->capacity - 1) {
fprintf(stderr, "Index out of bounds\n");
return -1;
}
return vec->data[idx];
}
void vec_push(vec_t *vec, int64_t data) {
err_init(vec);
if (vec->len >= (size_t)(vec->capacity * 0.75)) {
size_t new_capacity = 2 * vec->capacity;
vec->data = realloc(vec->data, new_capacity * sizeof(int64_t));
vec->capacity = new_capacity;
}
vec->data[vec->len] = data;
vec->len++;
}
void vec_insert_at(vec_t *vec, int64_t data, size_t idx) {
err_init(vec);
err_len_zero(vec);
if (idx > vec->capacity - 1) {
fprintf(stderr, "Index out of bounds\n");
return;
}
if (idx <= vec->len) {
size_t size_to_copy = vec->len - idx;
int64_t incl_and_aftr_idx[size_to_copy];
memcpy((void *)incl_and_aftr_idx, (void *)(vec->data + idx),
size_to_copy * sizeof(int64_t));
for (size_t i = 0; i < size_to_copy; i++) {
vec_pop(vec);
}
vec_push(vec, data);
// print_arr(aftr_idx, size_to_copy);
for (size_t i = 0; i < size_to_copy; i++) {
vec_push(vec, incl_and_aftr_idx[i]);
}
}
}
bool is_in_vec(vec_t *vec, int64_t data) {
if (vec == NULL) {
fprintf(stderr, "Vector not initialised\n");
return false;
}
for (size_t i = 0; i < vec->len; i++) {
if (vec->data[i] == data) {
return true;
}
}
return false;
}
void vec_pop(vec_t *vec) {
err_init(vec);
err_len_zero(vec);
// needs resizing
// should be extracted into separate function
if (vec->len <= vec->capacity / 2) {
size_t new_size = vec->capacity / 2;
vec->data = realloc(vec->data, new_size * sizeof(int64_t));
vec->capacity = new_size;
}
vec->len--;
}
void vec_remove(vec_t *vec, size_t idx) {
err_init(vec);
err_len_zero(vec);
if (idx > vec->len) {
fprintf(stderr, "Index out of bounds!\n");
return;
}
if (vec->len == 1) {
vec_pop(vec);
return;
}
size_t size_to_copy = vec->len - (idx + 1);
int64_t aftr_idx[size_to_copy];
memcpy((void *)aftr_idx, (void *)(vec->data + idx + 1),
size_to_copy * sizeof(int64_t));
size_t size_to_pop = size_to_copy + 1;
for (size_t i = 0; i < size_to_pop; i++) {
vec_pop(vec);
}
// print_arr(aftr_idx, size_to_copy);
for (size_t i = 0; i < size_to_copy; i++) {
vec_push(vec, aftr_idx[i]);
}
}
/**
* @brief Function that prints out the content as well as the current length and
* capacity of a given vector
*
* @param vec
*/
void vec_print(vec_t *vec) {
err_init(vec);
fprintf(stdout, " ========= Vector Data =========\n");
fprintf(stdout, " Capacity: %zu\tCurrent Size: %zu\n", vec->capacity,
vec->len);
fprintf(stdout, " ===============================\n");
fprintf(stdout, " -------------------------------\n");
for (size_t i = 0; i < vec->len; i++) {
fprintf(stdout, "| Vector[%ld]\t->\tData: %ld |\n", i, vec->data[i]);
}
fprintf(stdout, " -------------------------------\n");
fprintf(stdout, "\n");
}
/**
* @brief Function that deallocates the memory of the vector that was passed as
* an argument to the function. Subsequently the pointer will be set to NULL,
* that way it can be re-used safely later in the program
*
* @param vec Vector which we to destroy
*/
void vec_destroy(vec_t **vec) {
if ((*vec) != NULL) {
free((*vec)->data);
free((*vec));
(*vec) = NULL;
}
}
#ifndef _VEC_H_
#define _VEC_H_
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
typedef struct _vec_t vec_t;
extern vec_t *vec_create(size_t init_len);
extern ssize_t vec_length(vec_t *vec);
extern int64_t vec_get(vec_t *vec, size_t idx);
extern void vec_push(vec_t *vec, int64_t data);
extern void vec_insert_at(vec_t *vec, int64_t data, size_t idx);
extern bool is_in_vec(vec_t *vec, int64_t data);
extern void vec_remove(vec_t *vec, size_t idx);
extern void vec_pop(vec_t *vec);
extern void vec_print(vec_t *vec);
extern void vec_destroy(vec_t **vec);
#endif
#include <vec.h>
#include <libgen.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define NB_OPTIONS 6
void print_menu(void) {
fprintf(stdout, "*********** Menu opts ***********\n");
fprintf(stdout, "1:\tPush number\n");
fprintf(stdout, "2:\tDelete at given index\n");
fprintf(stdout, "3:\tPop last value\n");
fprintf(stdout, "4:\tPrint the vector\n");
fprintf(stdout, "5:\tInsert at given index\n");
fprintf(stdout, "6:\tQuit program\n");
fprintf(stdout, "*********************************\n\n");
}
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\t./%s <initial length of vector>\n",
basename(argv[0]));
exit(EXIT_FAILURE);
}
int64_t init_size = atoi(argv[1]);
if (init_size < 1) {
fprintf(
stderr,
"The initial size of the vector has to be greater than zero!\n");
fprintf(stderr, "Exiting...\n");
exit(EXIT_FAILURE);
}
vec_t *new_vec = vec_create((size_t)init_size);
while (true) {
unsigned int user_input;
print_menu();
fprintf(stdout, "Your choice: ");
scanf("%u", &user_input);
fprintf(stdout, "\n");
if (user_input > NB_OPTIONS) {
fprintf(stderr, "Input has to be less or equal to %d\n",
NB_OPTIONS);
continue;
}
int64_t to_push;
size_t idx_to_drop;
size_t idx_to_insert;
system("clear");
switch (user_input) {
case 1:
fprintf(stdout,
"Specify the number you wish to push into the vector: ");
scanf("%ld", &to_push);
fprintf(stdout, "\n");
vec_push(new_vec, to_push);
break;
case 2:
fprintf(stdout,
"Specify the index of the number you wish to remove: ");
scanf("%zu", &idx_to_drop);
fprintf(stdout, "\n");
vec_remove(new_vec, idx_to_drop);
break;
case 3:
vec_pop(new_vec);
break;
case 4:
vec_print(new_vec);
break;
case 5:
fprintf(stdout,
"Specify the number you wish to push into the vector: ");
scanf("%ld", &to_push);
fprintf(stdout,
"Specify the index at which you wish to insert the number: ");
scanf("%zu", &idx_to_insert);
vec_insert_at(new_vec, to_push, idx_to_insert);
break;
case 6:
vec_destroy(&new_vec);
return EXIT_SUCCESS;
default:
break;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment