From 8c13c75f3b576cc6fddf402eabeff9a359c9df2f Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Sat, 24 Sep 2016 17:47:04 +0200 Subject: [PATCH] recursion is now functionnal --- ls/.tags | 14 ++++++++++-- ls/includes/ftls.h | 27 +++++++++++++++++++++-- ls/libft | 2 +- ls/src/lib_dirents.c | 43 +++++++++++++++++++++++++++++++++++++ ls/src/lib_dirs.c | 27 +++++++++++++++++++++++ ls/src/lib_lsdata.c | 28 ++++++++++++++++++++++++ ls/src/lib_parse.c | 50 +++++++++++++++++++++++++++---------------- ls/src/lib_print.c | 51 ++++++++++++++++++++++++++++++++++---------- ls/src/main.c | 43 +++++++++++++++++++++++++++++++------ 9 files changed, 244 insertions(+), 41 deletions(-) create mode 100644 ls/src/lib_dirents.c create mode 100644 ls/src/lib_dirs.c create mode 100644 ls/src/lib_lsdata.c diff --git a/ls/.tags b/ls/.tags index 0815f4f2..aac50cdc 100644 --- a/ls/.tags +++ b/ls/.tags @@ -1,6 +1,16 @@ Mmain src/main.c /^int main(int ac, char **av)$/ +ft_dir_get_ents src/lib_dirs.c /^t_list *ft_dir_get_ents(t_lsdata *topdir)$/ +ft_ent_get_dirs src/lib_dirents.c /^t_list *ft_ent_get_dirs(t_list *ent)$/ +ft_ent_handle src/lib_dirents.c /^void ft_ent_handle(t_list **ent, t_lsdata *topdir,/ ft_error_dir src/lib_error.c /^void ft_error_dir(char *s)$/ ft_error_option src/lib_error.c /^void ft_error_option(char c)$/ -ft_ls src/lib_print.c /^void ft_ls(t_list **dirs_p)$/ -ft_parse_ls src/lib_parse.c /^void ft_parse_ls(int ac, char **av, t_list **dirs,/ +ft_ls_l src/lib_print.c /^void ft_ls_l(t_lsdata *data)$/ +ft_ls_print src/lib_print.c /^void ft_ls_print(t_list *ent, char *opts, t_lsdata/ +ft_ls_print_dirents src/lib_print.c /^void ft_ls_print_dirents(t_list *ent, char *opts)$/ +ft_ls_print_header src/lib_print.c /^void ft_ls_print_header(char *dirname)$/ +ft_lsdata_cmp0 src/lib_lsdata.c /^int ft_lsdata_cmp0(t_lsdata *dat1, char *dataref)/ +ft_lsdata_cmp_name src/lib_lsdata.c /^int ft_lsdata_cmp_name(t_lsdata *dat1, t_lsdata */ +ft_lsdata_cmp_time src/lib_lsdata.c /^int ft_lsdata_cmp_time(t_lsdata *dat1, t_lsdata */ +ft_lsdata_print src/lib_lsdata.c /^void ft_lsdata_print(t_list *ent)$/ +ft_parse_ls src/lib_parse.c /^void ft_parse_ls(int ac, char **av, t_list **dir, / ft_parse_ls_options src/lib_parse.c /^int ft_parse_ls_options(int ac, char **av, char */ diff --git a/ls/includes/ftls.h b/ls/includes/ftls.h index bb816d1d..743fa291 100644 --- a/ls/includes/ftls.h +++ b/ls/includes/ftls.h @@ -3,11 +3,34 @@ # define ALL_OPTS "lRart" # include "libft.h" # include +# include +# include +# include +# include + +typedef struct s_lsdata +{ + struct stat stat; + char *path; + struct dirent *dirent; +} t_lsdata; int ft_parse_ls_options(int ac, char **av, char *opts); -void ft_parse_ls(int ac, char **av, t_list **dirs, char * opts); +void ft_parse_ls(int ac, char **av, t_list **dir, t_list **ent, char *opts); -void ft_ls(t_list **dirs); +void ft_lsdata_print(t_list *ent); +int ft_lsdata_cmp_name(t_lsdata *dat1, t_lsdata *dat2); +int ft_lsdata_cmp_time(t_lsdata *dat1, t_lsdata *dat2); +int ft_lsdata_cmp0(t_lsdata *dat1, char *dataref); + +void ft_ent_handle(t_list **ent, t_lsdata *topdir, char *opts, int (*ft_sort)()); +t_list *ft_ent_get_dirs(t_list *ent); + +t_list *ft_dir_get_ents(t_lsdata *dir); + +void ft_ls_print(t_list *ent, char *opts, t_lsdata *topdir); +void ft_ls_print_header(char *dirname); +void ft_ls_print_dirents(t_list *ent, char *opts); void ft_error_option(char c); void ft_error_dir(char *s); diff --git a/ls/libft b/ls/libft index 55497a8a..8bfb8fb4 160000 --- a/ls/libft +++ b/ls/libft @@ -1 +1 @@ -Subproject commit 55497a8a27b8f6ef48d629f0ed0e381a8130db3f +Subproject commit 8bfb8fb462d914837fb76e95141cdce59b3c99f9 diff --git a/ls/src/lib_dirents.c b/ls/src/lib_dirents.c new file mode 100644 index 00000000..f1886651 --- /dev/null +++ b/ls/src/lib_dirents.c @@ -0,0 +1,43 @@ +#include "ftls.h" + +void ft_ent_handle(t_list **ent, t_lsdata *topdir, char *opts, int (*ft_sort)()) +{ + ft_lst_sort(ent, ft_sort); + if (ft_strchr(opts, 'r')) + ft_lst_reverse(ent); + if (!ft_strchr(opts, 'a')) + ft_lst_delif(ent, ".", &ft_lsdata_cmp0, &ft_lst_cfree); + ft_ls_print(*ent, opts, topdir); +} + +t_list *ft_ent_get_dirs(t_list *ent) +{ + t_lsdata *data; + struct dirent *dirent; + t_list *dir; + t_list *tmp; + + /* ft_printf("checking dir: %s\n", topdir->path); */ + dir = NULL; + while (ent) + { + data = ent->content; + dirent = data->dirent; + tmp = ent; + ent = ent->next; + /* ft_printf("checking: %s\n", data->path); */ + if (dirent->d_type == DT_DIR + && ft_strcmp(dirent->d_name, ".") + && ft_strcmp(dirent->d_name, "..")) + { + /* data->path = ft_strjoin(topdir->path, "/"); */ + /* data->path = ft_strjoin(data->path, dirent->d_name); */ + /* stat(data->path, &data->stat); */ + /* ft_printf("found dir: %s\n", data->path); */ + ft_lsteadd(&dir, tmp); + } + /* else */ + /* ft_printf("%s is not a dir\n", data->path); */ + } + return (dir); +} diff --git a/ls/src/lib_dirs.c b/ls/src/lib_dirs.c new file mode 100644 index 00000000..8be8745f --- /dev/null +++ b/ls/src/lib_dirs.c @@ -0,0 +1,27 @@ +#include "ftls.h" + +t_list *ft_dir_get_ents(t_lsdata *topdir) +{ + t_list *ent; + struct dirent *dirent; + t_lsdata data; + DIR *stream; + + ent = NULL; + stream = opendir(topdir->path); + while ((dirent = readdir(stream))) + { + data.path = ft_strjoin(topdir->path, "/"); + data.path = ft_strjoin(data.path, dirent->d_name); + /* ft_printf("looking at file: %s\n", data.path); */ + /* ft_printf("stat ret: %i\n", stat(data.path, &data.stat)); */ + stat(data.path, &data.stat); + data.dirent = dirent; + /* char *date = ctime(&data.stat.st_mtime); */ + /* date[ft_strlen(date) - 1] = '\0'; */ + /* ft_printf("%s %i %s\n", date, data.stat.st_ino, data.dirent->d_name); */ + ft_lstadd(&ent, ft_lstnew(&data, sizeof(data))); + } + closedir(stream); + return (ent); +} diff --git a/ls/src/lib_lsdata.c b/ls/src/lib_lsdata.c new file mode 100644 index 00000000..26bd7bf4 --- /dev/null +++ b/ls/src/lib_lsdata.c @@ -0,0 +1,28 @@ +#include "ftls.h" + +void ft_lsdata_print(t_list *ent) +{ + while (ent) + { + ft_printf("found recursively: %s\n", ((t_lsdata*)ent->content)->path); + ent = ent->next; + } +} + +int ft_lsdata_cmp_name(t_lsdata *dat1, t_lsdata *dat2) +{ + return (ft_strcmp(dat1->path, dat2->path)); +} + +int ft_lsdata_cmp_time(t_lsdata *dat1, t_lsdata *dat2) +{ + if (dat2->stat.st_mtime - dat1->stat.st_mtime) + return (dat2->stat.st_mtime - dat1->stat.st_mtime); + else + return (ft_strcmp(dat1->path, dat2->path)); +} + +int ft_lsdata_cmp0(t_lsdata *dat1, char *dataref) +{ + return (dat1->dirent->d_name[0] != *dataref); +} diff --git a/ls/src/lib_parse.c b/ls/src/lib_parse.c index f0066a42..251ec558 100644 --- a/ls/src/lib_parse.c +++ b/ls/src/lib_parse.c @@ -1,26 +1,42 @@ #include "ftls.h" -void ft_parse_ls(int ac, char **av, t_list **dirs, char *opts) +void ft_parse_ls(int ac, char **av, t_list **dir, t_list **ent, char *opts) { - int i; - DIR *dir; + int i; + t_lsdata data; + DIR *stream; - (void)dirs; + ft_bzero(opts, 7); i = ft_parse_ls_options(ac, av, opts); - ft_printf("options: %s\n", opts); - ft_strlsort(av + i, ac - i, &ft_strcmp); + /* ft_strlsort(av + i, ac - i, &ft_strcmp); */ + if (ac - i <= 1) + ft_strcat(opts, "0"); + /* ft_printf("options: %s\n", opts); */ + /* ft_printf("%i, %i\n", i, ac); */ if (i == ac) - ft_lstadd(dirs, ft_lstnew(opendir("."), sizeof(*dir))); + { + data.path = ft_strdup("."); + ft_printf("stat ret: %i\n", stat(data.path, &data.stat)); + ft_lstadd(dir, ft_lstnew(&data, sizeof(data))); + } while (i < ac) { - dir = opendir(av[i]); - if (dir) + data.path = ft_strdup(av[i]); + if (stat(data.path, &data.stat) < 0) { - ft_lstadd(dirs, ft_lstnew(dir, sizeof(*dir))); - /* ft_printf("found dir %s\n", av[i]); */ + ft_error_dir(data.path); + } + else if (!(stream = opendir(data.path))) + { + /* ft_printf("found file: %s\n", data.path); */ + ft_lstadd(ent, ft_lstnew(&data, sizeof(data))); } else - ft_error_dir(av[i]); + { + /* ft_printf("found dir: %s\n", data.path); */ + ft_lstadd(dir, ft_lstnew(&data, sizeof(data))); + closedir(stream); + } i++; } } @@ -30,13 +46,13 @@ int ft_parse_ls_options(int ac, char **av, char *opts) int i; int j; - i = 1; - while (i < ac) + i = 0; + while (++i < ac) { if (av[i][0] == '-' && av[i][1] != '\0') { - j = 1; - while(av[i][j]) + j = 0; + while(av[i][++j]) { if (ft_strchr(ALL_OPTS, av[i][j])) { @@ -45,12 +61,10 @@ int ft_parse_ls_options(int ac, char **av, char *opts) } else ft_error_option(av[i][j]); - j++; } } else break ; - i++; } return (i); } diff --git a/ls/src/lib_print.c b/ls/src/lib_print.c index 83d673a1..833db00c 100644 --- a/ls/src/lib_print.c +++ b/ls/src/lib_print.c @@ -1,16 +1,45 @@ #include "ftls.h" -void ft_ls(t_list **dirs_p) +void ft_ls_print(t_list *ent, char *opts, t_lsdata *topdir) { - t_list *ents; - struct dirent *dirent; - DIR *dir; + char *opt; - ents = NULL; - dir = (*dirs_p)->content;; - while ((dirent = readdir(dir))) - { - ft_lstadd(&ents, ft_lstnew(dirent, sizeof(*dirent))); - } - *dirs_p = (*dirs_p)->next; + if (!(opt = ft_strchr(opts, '0'))) + ft_ls_print_header(topdir->path); + else + *opt = '.'; + ft_ls_print_dirents(ent, opts); + ft_printf("\n"); +} + +void ft_ls_l(t_lsdata *data) +{ + char *date; + + /* date = ctime(&data->stat.st_mtimespec.tv_sec); */ + date = ctime(&data->stat.st_mtime); + date[ft_strlen(date) - 1] = '\0'; + ft_printf("%s %s\n", date, data->dirent->d_name); +} + +void ft_ls_print_dirents(t_list *ent, char *opts) +{ + t_lsdata *data; + struct dirent *dirent; + + while (ent) + { + data = ent->content; + dirent = data->dirent; + if (ft_strchr(opts, 'l')) + ft_ls_l(data); + else + ft_printf("%s\n", dirent->d_name); + ent = ent->next; + } +} + +void ft_ls_print_header(char *dirname) +{ + ft_printf("%s:\n", dirname); } diff --git a/ls/src/main.c b/ls/src/main.c index f72a6b1b..22dbf306 100644 --- a/ls/src/main.c +++ b/ls/src/main.c @@ -2,14 +2,43 @@ int main(int ac, char **av) { - t_list *dirs; - char *opts; + t_list *dir; + t_list *dir_r; + t_list *ent; + t_lsdata *dirdata; + int (*ft_sort)(); - dirs = NULL; + char *opts; + dir = NULL; + ent = NULL; opts = (char *)malloc(sizeof(char) * 7); - ft_bzero(opts, 7); - ft_parse_ls(ac, av, &dirs, opts); - while (dirs) - ft_ls(&dirs); + ft_parse_ls(ac, av, &dir, &ent, opts); + ft_sort = &ft_lsdata_cmp_name; + if (ft_strchr(opts, 't')) + ft_sort = &ft_lsdata_cmp_time; + ft_lst_sort(&dir, ft_sort); + ft_lst_sort(&ent, ft_sort); + if (ft_strchr(opts, 'r')) + { + ft_lst_reverse(&dir); + ft_lst_reverse(&ent); + } + if (ent) + ft_ent_handle(&ent, dir->content, opts, ft_sort); + while (dir) + { + dirdata = dir->content; + dir = dir->next; + /* ft_lstfree(ent); */ + ent = ft_dir_get_ents(dirdata); + ft_ent_handle(&ent, dirdata, opts, ft_sort); + if (ft_strchr(opts, 'R')) + { + dir_r = ft_ent_get_dirs(ent); + ft_lst_merge(&dir_r, dir); + dir = dir_r; + } + /* ft_lsdata_print(dir); */ + } return (0); }