From 49a58576a7cd59146a8c56bb205de912a1c9adf3 Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Thu, 28 Mar 2024 09:33:12 +0100 Subject: [PATCH] Implement parsing of input --- philo/Makefile | 4 +- philo/main.c | 24 +----------- philo/parsing.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ philo/parsing_misc.c | 75 ++++++++++++++++++++++++++++++++++++ philo/philo.h | 23 ++++++++++- 5 files changed, 191 insertions(+), 25 deletions(-) create mode 100644 philo/parsing.c create mode 100644 philo/parsing_misc.c diff --git a/philo/Makefile b/philo/Makefile index e86af04..dde328d 100644 --- a/philo/Makefile +++ b/philo/Makefile @@ -1,12 +1,14 @@ CC := gcc CFLAGS := -Wall -Wextra -Werror -Wpedantic -#-std=c99 +-std=c99 NAME := philo INCDIR := . SRCDIR := . SRCS := main.c \ + parsing.c \ + parsing_misc.c \ SRCS := $(addprefix $(SRCDIR)/, $(SRCS)) OBJS := $(SRCS:%.c=%.o) diff --git a/philo/main.c b/philo/main.c index ee3eba9..244ec4f 100644 --- a/philo/main.c +++ b/philo/main.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/22 11:19:48 by ljiriste #+# #+# */ -/* Updated: 2024/03/26 09:13:38 by ljiriste ### ########.fr */ +/* Updated: 2024/03/26 11:01:24 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,28 +15,6 @@ #include #include -int parse_input(t_settings *settings, int argc, char **argv) -{ - if (argc != 5 && argc != 6) - return (1); - settings->end = 0; - settings->should_check_hunger = 0; - if (parse_arg(&settings->philo_count, argv[1]) - || parse_arg(&settings->time_to_die, argv[2]) - || parse_arg(&settings->time_to_eat, argv[3]) - || parse_arg(&settings->time_to_sleep, argv[4])) - { - return (1); - } - if (argc == 6) - { - if (parse_arg(&settings->min_eat_num, argv[5])) - return (1); - settings->should_check_hunger = 1; - } - return (0); -} - int main(int argc, char **argv) { t_diner diner; diff --git a/philo/parsing.c b/philo/parsing.c new file mode 100644 index 0000000..4e7575b --- /dev/null +++ b/philo/parsing.c @@ -0,0 +1,90 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/03/26 09:31:35 by ljiriste #+# #+# */ +/* Updated: 2024/03/28 09:32:31 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo.h" +#include +#include + +// Maybe this should be changed so that it only changes +// res when the parse is successful? +static int inner_parse_arg(t_big_uint *res, const char *arg) +{ + char *tmp; + + *res = ft_atobui(arg); + tmp = ft_buitoa(*res); + if (!same_number(tmp, arg)) + { + free(tmp); + return (1); + } + free(tmp); + return (0); +} + +static int parse_arg_size(size_t *res, const char *arg) +{ + t_big_uint tmp; + + if (inner_parse_arg(&tmp, arg)) + return (1); + if (tmp > (size_t)-1) + return (1); + *res = (size_t)tmp; + return (0); +} + +static int parse_arg_usec(useconds_t *res, const char *arg) +{ + t_big_uint tmp; + + if (inner_parse_arg(&tmp, arg)) + return (1); + if (tmp > (useconds_t)-1) + return (1); + *res = (useconds_t)tmp; + return (0); +} + +static int parse_arg_uint(unsigned int *res, const char *arg) +{ + t_big_uint tmp; + + if (inner_parse_arg(&tmp, arg)) + return (1); + if (tmp > (unsigned int)-1) + return (1); + *res = (unsigned int)tmp; + return (0); +} + +int parse_input(t_settings *settings, int argc, char **argv) +{ + if (argc != 5 && argc != 6) + return (1); + settings->end = 0; + settings->should_check_hunger = 0; + if (parse_arg_size(&settings->philo_count, argv[1]) + || parse_arg_usec(&settings->time_to_die, argv[2]) + || parse_arg_usec(&settings->time_to_eat, argv[3]) + || parse_arg_usec(&settings->time_to_sleep, argv[4])) + { + return (1); + } + if (argc == 6) + { + if (parse_arg_uint(&settings->min_eat_num, argv[5])) + return (1); + settings->should_check_hunger = 1; + } + return (0); +} diff --git a/philo/parsing_misc.c b/philo/parsing_misc.c new file mode 100644 index 0000000..64f136e --- /dev/null +++ b/philo/parsing_misc.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsing_misc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/03/26 10:42:02 by ljiriste #+# #+# */ +/* Updated: 2024/03/28 09:31:14 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "philo.h" +#include + +t_big_uint ft_atobui(const char *str) +{ + t_big_uint res; + + res = 0; + if (!str) + return (res); + while (*str == ' ' || *str == '+') + ++str; + while ('0' <= *str && *str <= '9') + { + res *= 10; + res += *str - '0'; + ++str; + } + return (res); +} + +char *ft_buitoa(t_big_uint num) +{ + char *res; + size_t size; + t_big_uint tmp; + + tmp = num; + size = 0; + while (tmp > 0) + { + ++size; + tmp /= 10; + } + if (size == 0) + size = 1; + res = malloc(size + 1); + if (!res) + return (NULL); + res[size--] = '\0'; + if (num == 0) + res[0] = '0'; + while (num > 0) + { + res[size--] = '0' + num % 10; + num /= 10; + } + return (res); +} + +int same_number(const char *num1, const char *num2) +{ + while (*num1 == ' ' || *num1 == '+' || *num1 == '0') + ++num1; + while (*num2 == ' ' || *num2 == '+' || *num2 == '0') + ++num2; + while (*num1 && *num2 && *num1 == *num2) + { + ++num1; + ++num2; + } + return ((int)*num1 - (int)*num2); +} diff --git a/philo/philo.h b/philo/philo.h index 5b27c95..399fc0e 100644 --- a/philo/philo.h +++ b/philo/philo.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/22 11:10:17 by ljiriste #+# #+# */ -/* Updated: 2024/03/26 09:55:46 by ljiriste ### ########.fr */ +/* Updated: 2024/03/28 09:32:08 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,22 @@ # include # include # include +# include +# include + +// This done to make parsing easier/non-repetitive +// but it cannot be a part of parsing.c as more files depend on it +// May it should have its own header file? +// +// This assumes useconds_t is not the biggest type +// The assumption is made because it is not easy to check +# if SIZE_MAX > UINT_MAX + +typedef size_t t_big_uint; +# else + +typedef unsigned int t_big_uint; +# endif //SIZE_MAX > UINT_MAX // The .start member holds the result of gettimeofday // Every other member that holds time info counts @@ -51,4 +67,9 @@ typedef struct s_diner pthread_mutex_t *forks; } t_diner; +int parse_input(t_settings *settings, int argc, char **argv); +t_big_uint ft_atobui(const char *str); +char *ft_buitoa(t_big_uint num); +int same_number(const char *num1, const char *num2); + #endif //PHILO_H -- 2.30.2