Change everything to make main merge input files (a little like paste).
This change is made to test bonus part - using get_next_line with
multiple files.
Move logic to produce correct files from test script to Makefile.
Create logic to enable testing of all(a), mandatory(m) or bonus(b)
parts.
Remove dependency on a function available only through get_next_line* as
that may (and probably would) be part of only my implementation. Add
functions that substitute this function.
Update .gitignore to ignore more temporary directories and files that
are created by running test script.
LOGIC FOR PRODUCING THE CORRECT OUTPUT FOR BONUS PART NEEDS TO BE
IMPLEMENTED IN THE FOLLOWING COMMIT.
obj/
results/
tester
+tester_bonus
+tmp
CC = cc
CFLAGS = -Wall -Wextra -Werror -g -fdiagnostics-color=always
-GNLDIR = ../
-SRCDIR = src/
-OBJDIR = obj/
-INCLUDE = include/
+GNLDIR := ../../get_next_line/
+SRCDIR := src/
+OBJDIR := obj/
+INCLUDE := include/
-SRCS = $(shell find $(SRCDIR) -name '*.c' -type f -printf "%f\n")
-GNLSRCS = get_next_line.c get_next_line_utils.c
-OBJS = $(SRCS:%.c=$(OBJDIR)%.o)
-GNLOBJS = $(GNLSRCS:%.c=$(OBJDIR)%.o)
+SRCS := $(shell find $(SRCDIR) -name '*.c' -type f -printf "%f\n")
+GNLSRCS := get_next_line.c get_next_line_utils.c
+GNLBONUS := $(GNLSRCS:%.c=%_bonus.c)
+OBJS := $(SRCS:%.c=$(OBJDIR)%.o)
+GNLOBJS := $(GNLSRCS:%.c=$(OBJDIR)%.o)
+GNLBONUSOBJS = $(GNLBONUS:%.c=$(OBJDIR)%.o)
+TESTDIR := test_files/
+CORDIR := correct/
+TESTFILES := $(shell find $(TESTDIR) -type f | sort)
+CORFILES := $(TESTFILES:$(TESTDIR)%=$(CORDIR)%)
NAME = tester
+BONUS = tester_bonus
all : $(NAME)
+bonus : $(BONUS)
+all_tests : $(CORFILES)
+bonus_test : $(CORDIR)mix
$(NAME) : $(OBJS) $(GNLOBJS)
$(CC) $(CFLAGS) $^ -o $@
-
+
+$(BONUS) : $(OBJS) $(GNLBONUSOBJS)
+ $(CC) $(CFLAGS) $^ -o $@
+
$(OBJS) : $(OBJDIR)%.o : $(SRCDIR)%.c | $(OBJDIR)
- $(CC) $(CFLAGS) -c $< -o $@ -I$(GNLDIR) -I$(INCLUDE)
+ $(CC) $(CFLAGS) -c $< -o $@ -I$(INCLUDE)
-$(GNLOBJS) : $(OBJDIR)%.o : $(GNLDIR)%.c | $(OBJDIR)
+$(GNLOBJS) $(GNLBONUSOBJS) : $(OBJDIR)%.o : $(GNLDIR)%.c | $(OBJDIR)
ifndef BUFFER_SIZE
$(CC) $(CFLAGS) -c $< -o $@ -I$(GNLDIR)
else
endif
# GNLSRCS are added as phony for them to compile when BUFFER_SIZE changes
-.PHONY : $(addprefix $(GNLDIR), $(GNLSRCS))
+# main.c is added so that it can rebuilds when bonus is invoked
+.PHONY : $(addprefix $(GNLDIR), $(GNLSRCS) $(GNLBONUS)) $(SRCDIR)main.c
$(OBJDIR) :
mkdir $(OBJDIR)
$(RM) $(OBJDIR)*
fclean : clean
- $(RM) $(NAME)
+ $(RM) $(NAME) $(BONUS)
re : fclean
$(MAKE)
norminette :
- norminette $(GNLDIR)
+ norminette $(GNLSRCS)
+
+bonus_norminette :
+ norminette $(GNLBONUS)
+
+$(CORDIR)mix : $(TESTFILES) | $(CORDIR)
+ paste $^ > $@
+
+$(CORFILES) : $(CORDIR)% : $(TESTDIR)% | $(CORDIR)
+ sed "s/$$/\n$(SEP)/g" $< > $@
+
+$(CORDIR) :
+ mkdir $(CORDIR)
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/11 18:10:37 by ljiriste #+# #+# */
-/* Updated: 2023/10/12 13:10:56 by ljiriste ### ########.fr */
+/* Updated: 2023/10/25 13:34:23 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
void ft_putstr_fd(const char *str, int fd);
size_t ft_strlen(const char *str);
size_t ft_strlcpy(char *dst, const char *src, size_t size);
-
+char *ft_strjoin(const char *s1, const char *s2);
+char *ft_strjoin_arr(char *const *arr, const char *sep);
+size_t ft_strlcat(char *dst, const char *src, size_t size);
+char *get_next_line(int fd);
#endif
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_strjoin.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/08/15 15:04:10 by ljiriste #+# #+# */
+/* Updated: 2023/10/24 15:01:03 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdlib.h>
+#include "main.h"
+
+char *ft_strjoin(const char *s1, const char *s2)
+{
+ char *res;
+ size_t size;
+
+ if (s1 == NULL || s2 == NULL)
+ return (NULL);
+ size = ft_strlen(s1) + ft_strlen(s2) + 1;
+ res = malloc(size * sizeof(char));
+ if (res == NULL)
+ return (res);
+ res[0] = '\0';
+ ft_strlcat(res, s1, size);
+ ft_strlcat(res, s2, size);
+ return (res);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_strjoin_arr.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/10/24 15:09:27 by ljiriste #+# #+# */
+/* Updated: 2023/10/24 15:33:45 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdlib.h>
+#include "main.h"
+
+char *ft_strjoin_arr(char *const *arr, const char *sep)
+{
+ int i;
+ size_t len;
+ char *res;
+ size_t sep_len;
+ int seps;
+
+ i = 0;
+ len = 1;
+ sep_len = ft_strlen(sep);
+ while (arr[i])
+ len += ft_strlen(arr[i++]) + sep_len;
+ seps = i - 1;
+ res = malloc((len - sep_len) * sizeof(char));
+ if (!res)
+ return (res);
+ i = 0;
+ res[0] = '\0';
+ while (arr[i])
+ {
+ ft_strlcat(res, arr[i], len);
+ if (i < seps)
+ ft_strlcat(res, sep, len - sep_len);
+ ++i;
+ }
+ return (res);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_strlcat.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/06/12 17:32:33 by ljiriste #+# #+# */
+/* Updated: 2023/10/24 15:01:20 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stddef.h>
+#include <sys/types.h>
+#include "main.h"
+
+size_t ft_strlcat(char *dst, const char *src, size_t size)
+{
+ size_t length;
+
+ if ((dst == NULL && src == NULL) || size == 0)
+ return (0);
+ length = 0;
+ while (*dst && size > length)
+ {
+ ++dst;
+ ++length;
+ }
+ while (*src && size > length + 1)
+ {
+ *dst = *src;
+ ++src;
+ ++dst;
+ ++length;
+ }
+ if (size > length)
+ *dst = '\0';
+ while (*src)
+ {
+ ++length;
+ ++src;
+ }
+ return (length);
+}
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/12 14:52:24 by ljiriste #+# #+# */
-/* Updated: 2023/10/24 12:10:34 by ljiriste ### ########.fr */
+/* Updated: 2023/10/25 13:33:54 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
#include <unistd.h>
#include <stdlib.h>
#include "main.h"
-#include "get_next_line.h"
-int my_open(const char *fname)
+int *open_all(const int count, char *const *fname)
{
- int fd;
+ int *fds;
char *path;
+ char *tmp;
+ int i;
- path = ft_strdup(TEST_DIR);
+ i = 0;
+ fds = malloc(count * sizeof(int));
+ if (!fds)
+ return (fds);
+ while (i < count)
+ {
+ tmp = ft_strdup(TEST_DIR);
+ path = ft_strjoin(tmp, fname[i]);
+ fds[i++] = open(path, O_RDONLY);
+ free(path);
+ free(tmp);
+ }
+ return (fds);
+}
- ft_strncat_alloc(&path, fname, ft_strlen(fname));
- fd = open(path, O_RDONLY);
- free(path);
- return (fd);
+void close_all(int count, int *fds)
+{
+ while (count > 0)
+ close(fds[--count]);
+ free(fds);
+ return ;
}
char last_char(const char *str)
{
int fd;
char *path;
+ char *tmp;
- path = ft_strdup(RESULT_DIR);
- ft_strncat_alloc(&path, fname, ft_strlen(fname));
+ tmp = ft_strdup(RESULT_DIR);
+ path = ft_strjoin(tmp, fname);
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ ft_putstr_fd(path, 1);
free(path);
+ free(tmp);
return (fd);
}
-void test_gnl(int testfd, int resfd)
+void print_sep(const char *line, int resfd)
+{
+ if (last_char(line) == '\n')
+ {
+ ft_putstr_fd(SEPARATOR, resfd);
+ ft_putstr_fd("\n", resfd);
+ }
+ else
+ {
+ ft_putstr_fd("\n", resfd);
+ ft_putstr_fd(SEPARATOR, resfd);
+ }
+ return ;
+}
+
+void rotate_part(int *arr, int i, int size)
{
+ int tmp;
+
+ tmp = arr[i];
+ while (i + 1 < size)
+ {
+ arr[i] = arr[i+1];
+ ++i;
+ }
+ arr[i] = tmp;
+ return ;
+}
+
+void test_gnl(int *testfd, int resfd, int count)
+{
+ int i;
char *line;
- line = get_next_line(testfd);
- while (line)
+ while (count > 0)
{
- ft_putstr_fd(line, resfd);
- if (last_char(line) == '\n')
- {
- ft_putstr_fd(SEPARATOR, resfd);
- ft_putstr_fd("\n", resfd);
- }
- else
+ i = 0;
+ while (i < count)
{
- ft_putstr_fd("\n", resfd);
- ft_putstr_fd(SEPARATOR, resfd);
+ line = get_next_line(testfd[i++]);
+ if (!line)
+ {
+ rotate_part(testfd, --i, count--);
+ continue ;
+ }
+ ft_putstr_fd(line, resfd);
+ print_sep(line, resfd);
+ free(line);
}
- free(line);
- line = get_next_line(testfd);
}
- return ;
}
int main(int argc, char **argv)
{
- int i;
- int testfd;
- int resfd;
+ int *testfd;
+ int resfd;
+ char *resname;
if (argc < 2)
{
ft_putstr_fd("Error: Not enough arguments.\n", 2);
return (-1);
}
- i = 1;
- while (i < argc)
- {
- testfd = my_open(argv[i]);
- resfd = create_res_file(argv[i]);
- test_gnl(testfd, resfd);
- close(testfd);
- close(resfd);
- ++i;
- }
+ testfd = open_all(argc - 1, argv + 1);
+ if (!testfd)
+ return (1);
+ resname = ft_strjoin_arr(argv + 1, "_");
+ resfd = create_res_file(resname);
+ free(resname);
+ test_gnl(testfd, resfd, argc - 1);
+ close_all(argc - 1, testfd);
+ close(resfd);
return (0);
}
#!/bin/bash
-git pull
+b=0
+m=0
-printf "Running Norminette\n"
-make norminette > tmp
-if [ $? -ne 0 ]
-then
- printf "Norminette error:\n$(<tmp)\n"
- rm tmp
- exit 1
-fi
-printf "Compiling without externally providing BUFFER_SIZE\n"
-make --silent 2>tmp
-if [ $? -ne 0 ]
+for arg in "$@"
+do
+ if [ $arg == 'a' ]
+ then
+ b=1
+ m=1
+ elif [ $arg == 'b' ]
+ then
+ b=1
+ elif [ $arg == 'm' ]
+ then
+ m=1
+ fi
+done
+if [ $b -eq 0 ] && [ $m -eq 0 ]
then
- printf "Compilation failed:\n$(<tmp)\n"
- rm tmp
- exit 1
+ m=1
fi
+mkdir -p results
mkdir -p correct
+testing_sizes=(1 2 3 4 10 16 42 100 200 500 1000 9999 10000000)
SEP="---------------------"
-wait
-for file in $(ls test_files/)
-do
- sed "s/$/\n$SEP/g" test_files/$file > correct/$file
-done
+if [ $m -eq 1 ]
+then
+ printf "Running Norminette\n"
+ make norminette > tmp
+ if [ $? -ne 0 ]
+ then
+ printf "\033[31mNorminette error:\n$(<tmp)\n\033[0m"
+ rm tmp
+ exit 1
+ fi
+ printf "\033[32mNorminette run without an issue\n\033[0m"
+ printf "Compiling without externally providing BUFFER_SIZE\n"
+ make --silent tester 2>tmp
+ if [ $? -ne 0 ]
+ then
+ printf "Compilation failed:\n$(<tmp)\n"
+ rm tmp
+ exit 1
+ fi
+ printf "\033[32mCompilation successful\n\033[0m"
-mkdir -p results
-testing_sizes=(1 2 3 4 10 16 42 100 200 500 1000 9999 10000000)
+ make --silent all_tests SEP=$SEP
+ wait
+ for file in $(ls test_files/)
+ do
+ valgrind --quiet --leak-check=full --log-file='tmp' ./tester $file > /dev/null
+ wait
+ if $(cmp -s ./correct/$file ./results/$file)
+ then
+ printf "\033[32m"
+ printf "$file: OK\n"
+ printf "$(<tmp)\n"
+ else
+ printf "\033[31m"
+ printf "$file: KO\n"
+ printf "diff -y ./correct/$file ./results/$file\n"
+ printf "$(diff -y ./correct/$file ./results/$file)\n"
+ printf "$(<tmp)\n"
+ fi
+ done
-wait
+ for BS in ${testing_sizes[@]}
+ do
+ printf "\033[0m\nTrying BUFFER_SIZE = $BS\n"
+ make --silent BUFFER_SIZE=$BS
+ wait
+ for file in $(ls test_files/)
+ do
+ valgrind --quiet --leak-check=full --log-file='tmp' ./tester $file > /dev/null
+ wait
+ if $(cmp -s ./correct/$file ./results/$file)
+ then
+ printf "\033[32m"
+ printf "$file: OK\n"
+ printf "$(<tmp)\n"
+ else
+ printf "\033[31m"
+ printf "$file: KO\n"
+ printf "diff -y ./correct/$file ./results/$file\n"
+ printf "$(diff -y ./correct/$file ./results/$file)\n"
+ printf "$(<tmp)\n"
+ fi
+ done
+ done
+fi
-for file in $(ls test_files/)
-do
- valgrind --quiet --leak-check=full ./tester $file 2> tmp
- wait
- if $(cmp -s ./correct/$file ./results/$file)
- then
- printf "\033[32m"
- printf "$file: OK\n"
- printf "$(<tmp)\n"
- else
- printf "\033[31m"
- printf "$file: KO\n"
- printf "diff -y ./correct/$file ./results/$file\n"
- printf "$(diff -y ./correct/$file ./results/$file)\n"
- printf "$(<tmp)\n"
- fi
-done
+if [ $b -eq 1 ]
+then
+ printf "Testing bonus\n"
-for BS in ${testing_sizes[@]}
-do
- printf "\033[0m\nTrying BUFFER_SIZE = $BS\n"
- make --silent BUFFER_SIZE=$BS
- wait
- for file in $(ls test_files/)
+ printf "Running Norminette\n"
+ make bonus_norminette >tmp
+ if [ $? -ne 0 ]
+ then
+ printf "\033[31mNorminette error:\n$(<tmp)\n\033[0m"
+ rm tmp
+ exit 1
+ fi
+ printf "\033[32mNorminette run without an issue\n\033[0m"
+ printf "Compiling without externally providing BUFFER_SIZE\n"
+ make --silent bonus 2>tmp
+ if [ $? -ne 0 ]
+ then
+ printf "\033[31mCompilation failed:\n$(<tmp)\n\033[0m"
+ rm tmp
+ exit 1
+ fi
+ printf "\033[32mCompilation successful\n\033[0m"
+ make --silent bonus_test SEP=$SEP
+ for BS in ${testing_sizes[@]}
do
- valgrind --quiet --leak-check=full ./tester $file 2> tmp
+ printf "\033[0m\nTrying BUFFER_SIZE = $BS\n"
+ make --silent bonus BUFFER_SIZE=$BS
wait
- if $(cmp -s ./correct/$file ./results/$file)
+ mix_res_path=$(valgrind --quiet --leak-check=full --log-file='tmp' ./tester_bonus $(find ./test_files/ -type f -printf "%f\n" | sort))
+ if $(cmp -s ./correct/mix $mix_res_path)
then
printf "\033[32m"
- printf "$file: OK\n"
+ printf "bonus: OK\n"
printf "$(<tmp)\n"
else
printf "\033[31m"
- printf "$file: KO\n"
- printf "diff -y ./correct/$file ./results/$file\n"
- printf "$(diff -y ./correct/$file ./results/$file)\n"
+ printf "bonus: KO\n"
+ printf "diff -y ./correct/mix $mix_res_path\n"
+ printf "$(diff -y ./correct/mix $mix_res_path)\n"
printf "$(<tmp)\n"
fi
done
-done
-
+fi
wait
rm tmp