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)
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
#include <pthread.h>
#include <sys/time.h>
-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;
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* parsing.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/03/26 09:31:35 by ljiriste #+# #+# */
+/* Updated: 2024/03/28 09:32:31 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "philo.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+// 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);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* parsing_misc.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/03/26 10:42:02 by ljiriste #+# #+# */
+/* Updated: 2024/03/28 09:31:14 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "philo.h"
+#include <stdlib.h>
+
+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);
+}
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
# include <stddef.h>
# include <pthread.h>
# include <sys/time.h>
+# include <limits.h>
+# include <unistd.h>
+
+// 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
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