392 lines
10 KiB
C
392 lines
10 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* libtf.h :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2023/12/18 11:07:59 by mcolonna #+# #+# */
|
|
/* Updated: 2024/03/11 12:12:03 by mcolonna ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#ifndef LIBTF_H
|
|
# define LIBTF_H
|
|
|
|
# include <stddef.h>
|
|
# include <stdbool.h>
|
|
|
|
///// STR (part1) /////
|
|
/**
|
|
* t_string variables are char* which ends with '\0'.
|
|
*/
|
|
typedef char *t_string;
|
|
|
|
/**
|
|
* Same but the chars are constant.
|
|
*/
|
|
typedef const char *t_const_string;
|
|
|
|
///// ERR /////
|
|
// Functions who can raise an error must accept a t_err function
|
|
// and call it if an error occurs.
|
|
|
|
/**
|
|
* Function called when there's an error.
|
|
* The argument identifies what type of error is it (can be NULL).
|
|
* In this library, the possible arguments are:
|
|
* - "alloc error" Error when allocating memory.
|
|
* - "bad value" The value given to the function is bad.
|
|
* - "errno" The error is defined in errno.
|
|
* - "empty list" The list is empty and it shouldn't be.
|
|
*/
|
|
typedef void (t_err)(t_const_string);
|
|
|
|
/**
|
|
* Keep the error in memory to get it later with get_error().
|
|
*/
|
|
void err_remember(t_const_string msg);
|
|
|
|
/**
|
|
* If err_remember was called before, return the message of the error
|
|
* then drop it. Return NULL if there is no error to get.
|
|
*/
|
|
t_const_string err_get(void);
|
|
|
|
///// MEM /////
|
|
// Awesome malloc manager. When you alloc an address, you have to assign
|
|
// a t_memclass (mc) to it. Then, you can free every address assigned to
|
|
// a mc using mem_freeall(), or you can free the addresses one by one
|
|
// using mem_free() (you still have to use mem_freeall() to free the mc).
|
|
|
|
/**
|
|
* Represent a class of allocs.
|
|
* Must be created by mem_newclass() and freed by mem_freeall()
|
|
* Don't use after being freed.
|
|
*/
|
|
typedef void *t_memclass;
|
|
|
|
/**
|
|
* Create a t_memclass.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_memclass mem_newclass(t_err *err);
|
|
|
|
/**
|
|
* Create a t_memclass and add it to parent.
|
|
* It means if we freeall(parent), this mc is freeall too.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_memclass mem_subclass(t_err *err, t_memclass parent);
|
|
|
|
/**
|
|
* Alloc memory of the class 'mc' and of the size 'size'.
|
|
* If mc is NULL, do nothing.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
void *mem_alloc(t_err *err, t_memclass mc, size_t size);
|
|
|
|
/**
|
|
* Free all the memory of the specified class.
|
|
* 'mc' becomes unusable.
|
|
*/
|
|
void mem_freeall(t_memclass mc);
|
|
|
|
/**
|
|
* Free a pointer. If pointer is NULL, do nothing.
|
|
* /!\ Must use it only with address alloced with mem_alloc!!
|
|
*/
|
|
void mem_free(void *pointer);
|
|
|
|
///// STR (part2) /////
|
|
|
|
/**
|
|
* Return the length of the string.
|
|
*/
|
|
int str_len(t_const_string str);
|
|
|
|
/**
|
|
* Clone the string.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_string str_dup(t_err *err, t_memclass mc, t_const_string str);
|
|
|
|
/**
|
|
* Check if the char is in the given charset.
|
|
* Return always false if c is '\0'.
|
|
*/
|
|
bool char_isin(char c, t_const_string charset);
|
|
|
|
/**
|
|
* Check if the char is a digit ([0-9]).
|
|
*/
|
|
bool char_isdigit(char c);
|
|
|
|
/**
|
|
* Check if the char is an uppercase letter ([A-Z]).
|
|
*/
|
|
bool char_isupper(char c);
|
|
|
|
/**
|
|
* Check if the char is a lowercase letter ([a-z]).
|
|
*/
|
|
bool char_islower(char c);
|
|
|
|
/**
|
|
* Check if the char is a letter ([A-Za-z]).
|
|
*/
|
|
bool char_isalpha(char c);
|
|
/**
|
|
* Check if the char is a letter or a digit ([A-Za-z0-9]).
|
|
*/
|
|
bool char_isalphanum(char c);
|
|
|
|
/**
|
|
* Allows reading a string char by char.
|
|
*/
|
|
typedef struct s_stream
|
|
{
|
|
char (*_read)(const void **);
|
|
char (*_pop)(const void **);
|
|
const void *_data;
|
|
} t_stream;
|
|
|
|
/**
|
|
* Create a stream from a string.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_stream *streamstr_alloc(
|
|
t_err *err, t_memclass mc, t_const_string str);
|
|
/**
|
|
* Set 'stream' to a new stream using 'str'.
|
|
*/
|
|
void streamstr_init(t_stream *stream, t_const_string str);
|
|
|
|
/**
|
|
* Return the current char of the stream, or \0 if it's the end.
|
|
*/
|
|
char stream_read(t_stream *stream);
|
|
|
|
/**
|
|
* Return the current char of the stream, or \0 if it's the end.
|
|
* Go to the next char if it isn't the end.
|
|
*/
|
|
char stream_pop(t_stream *stream);
|
|
|
|
/**
|
|
* Skip specified chars in stream.
|
|
* For example if the stream is at "21012321" and charset is "012",
|
|
* it will skip the first '0', '1' and '2's to be at "321".
|
|
*/
|
|
void stream_skip(t_stream *stream, t_const_string charset);
|
|
|
|
/**
|
|
* Read an unsigned int in decimal, until a non-digit or the end of the stream.
|
|
* If there is no digit, or if it overflows the length of a unsigned int, err
|
|
* is called with "bad value" and 0 is returned.
|
|
* Possible errors: "bad value"
|
|
* Return 0 on error.
|
|
*/
|
|
unsigned int stream_readuint(t_err *err, t_stream *stream);
|
|
|
|
/**
|
|
* Read a signed int in decimal, until a non-digit or the end of the stream.
|
|
* If there is no digit, '+' or '-', or if it overflows the length of a signed
|
|
* int, err is called with "bad value" and -1 is returned.
|
|
* Possible errors: "bad value"
|
|
* Return 0 on error.
|
|
*/
|
|
int stream_readint(t_err *err, t_stream *stream);
|
|
|
|
/**
|
|
* Cast a string to an unsigned int in decimal.
|
|
* The string must match /[0-9]+/, and the result must not overflow the limits
|
|
* of a unsigned int. If it isn't respected, err is called with "bad value"
|
|
* and 0 is returned.
|
|
* Possible errors: "bad value"
|
|
* Return 0 on error.
|
|
*/
|
|
unsigned int str_touint(t_err *err, t_const_string str);
|
|
|
|
/**
|
|
* Cast a string to a signed int in decimal.
|
|
* The string must match /[-+]?[0-9]+/, and the result must not overflow the
|
|
* limits of an int. If it isn't respected, err is called with "bad value" and
|
|
* -1 is returned.
|
|
* Possible errors: "bad value"
|
|
* Return -1 on error.
|
|
*/
|
|
int str_toint(t_err *err, t_const_string str);
|
|
|
|
/**
|
|
* Split the given string by the given separators in charset.
|
|
* Return a list of strings ended by NULL, no empty string.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_string *str_split(
|
|
t_err *err, t_memclass mc, t_const_string str,
|
|
t_const_string charset);
|
|
|
|
/**
|
|
* Return a mem_alloc'd concatenation of the two strings.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_string str_join(t_err *err, t_memclass mc, t_const_string str1,
|
|
t_const_string str2);
|
|
|
|
/**
|
|
* Write an int as an str in decimal.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_string str_inttostr(t_err *err, t_memclass mc, int n);
|
|
|
|
/**
|
|
* Write an unsigned int as an str in decimal.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
t_string str_uinttostr(t_err *err, t_memclass mc, unsigned int n);
|
|
|
|
/**
|
|
* Return true if the strings are the same.
|
|
*/
|
|
bool str_eq(t_const_string str1, t_const_string str2);
|
|
|
|
///// IO /////
|
|
|
|
/**
|
|
* Write a string on fd.
|
|
* Possible errors: "errno"
|
|
*/
|
|
void print_str(t_err *err, int fd, t_const_string str);
|
|
|
|
/**
|
|
* Write a string on fd and finish it with a \n.
|
|
* Possible errors: "errno"
|
|
*/
|
|
void print_line(t_err *err, int fd, t_const_string str);
|
|
|
|
/**
|
|
* Conversions: %c %s %p %d %i %u %x %X %%
|
|
* Return -1 on error.
|
|
*/
|
|
int tf_printf(t_const_string format, ...);
|
|
|
|
/**
|
|
* Return the next line of the 'fd', including the '\n' if it exists.
|
|
* 'fd' must be between 0 and 4095 included.
|
|
* Possible error: "alloc error", "bad value", "errno"
|
|
* Return NULL if error, BUT it's not the only case it could return NULL!
|
|
* To avoid leaks and problems, must be called until it returns NULL.
|
|
*/
|
|
t_const_string read_line(t_err err, t_memclass mc, int fd);
|
|
|
|
///// LIST /////
|
|
|
|
/**
|
|
* Represents an element of a t_list.
|
|
* - value: mem_alloc'd pointer to the value of the element.
|
|
* - next: next element in the list, or NULL if it's the end of the list.
|
|
* - previous: previous element in the list, or NULL if it's the beginning of the
|
|
* list.
|
|
*/
|
|
typedef struct s_list_element
|
|
{
|
|
void *value;
|
|
struct s_list_element *next;
|
|
struct s_list_element *previous;
|
|
} t_list_element;
|
|
|
|
/**
|
|
* Represents a list.
|
|
* - first: first element of the list, or NULL if the list is empty.
|
|
* - last: last element of the list, or NULL if the list is empty.
|
|
* - size: number of elements in the list.
|
|
* - mc: memclass of the elements and their values.
|
|
* [!] All those fields must stay coherent.
|
|
*/
|
|
typedef struct s_list
|
|
{
|
|
t_list_element *first;
|
|
t_list_element *last;
|
|
int size;
|
|
t_memclass mc;
|
|
} t_list;
|
|
|
|
/**
|
|
* Create an empty list.
|
|
* The mc is saved to be used y list_addelement. You must do mem_freeall(mc)
|
|
* after finishing using the list.
|
|
*/
|
|
t_list list_createempty(t_memclass mc);
|
|
|
|
/**
|
|
* Add an element to the start of the list.
|
|
* The element is alloc'd with the mc of the list.
|
|
* Possible errors: "alloc error"
|
|
*/
|
|
void list_revadd(t_err *err, t_list *list, void *value);
|
|
|
|
/**
|
|
* Add an element to the end of the list.
|
|
* The element is alloc'd with the mc of the list.
|
|
* err is called with "alloc error" if the alloc doesn't work.
|
|
* Possible errors: "alloc error"
|
|
*/
|
|
void list_add(t_err *err, t_list *list, void *value);
|
|
|
|
/**
|
|
* Get the value at the specified index.
|
|
* Possible errors: "alloc error"
|
|
* Return NULL on error.
|
|
*/
|
|
void *list_get(t_err *err, const t_list *list, int index);
|
|
|
|
/**
|
|
* Return the last value from the list and remove it.
|
|
* Possible errors: "empty list"
|
|
* Return NULL on error.
|
|
*/
|
|
void *list_revpop(t_err *err, t_list *list);
|
|
|
|
/**
|
|
* Return the first value from the list and remove it.
|
|
* Possible errors: "empty list"
|
|
* Return NULL on error.
|
|
*/
|
|
void *list_pop(t_err *err, t_list *list);
|
|
|
|
/**
|
|
* Return the size of the list.
|
|
*/
|
|
int list_getsize(const t_list *list);
|
|
|
|
/**
|
|
* Move the first element to the end of the list.
|
|
* Does nothing if empty.
|
|
*/
|
|
void list_rotate(t_list *list);
|
|
|
|
/**
|
|
* Move the last element to the beginning of the list.
|
|
* Does nothing if empty.
|
|
*/
|
|
void list_revrotate(t_list *list);
|
|
|
|
///// DATA /////
|
|
|
|
/**
|
|
* Copy 'size' bytes of content from src to dest.
|
|
* The ranges CAN overlap.
|
|
*/
|
|
void data_cpy(void *dest, const void *src, size_t size);
|
|
|
|
#endif
|