diff --git a/inc/ft_ls.h b/inc/ft_ls.h index 9241525..378ed0b 100644 --- a/inc/ft_ls.h +++ b/inc/ft_ls.h @@ -54,26 +54,34 @@ typedef struct s_dir_elm t_flags *flags; } t_dir_elm; -void ft_ls( - t_list *filenames, - t_list *dir_paths, - t_flags *flgs, - char *par_dir); +typedef struct s_ft_ls +{ + t_list *lst_fil_names; + t_list *lst_dir_paths; + t_list *lst_fil_meta; + int one_dir; + int no_ops; + int first_print; + t_flags *flgs; +} t_ft_ls; -int parse_input( - int ac, - char **av, - t_list **str_paths, - t_flags *flgs); +void ft_ls(t_ft_ls *s_ls); -void init_dir_con_lst( - t_list **dir_content_lst, t_list *filenames, - t_flags *flgs, char *par_dir); +void ft_ls_fil(t_ft_ls *s_ls, char *full_path); + +void ft_ls_dir(t_ft_ls *s_ls, char *full_path); + +int parse_input(int ac, char **av, t_ft_ls *ft_ls_strct); + +void init_file_meta_lst(t_ft_ls *s_ls, char *full_path); void fill_path_lst(t_list **path_lst, char *path); -void sort_elms(t_list **del, t_flags *flgs); +void sort_files(t_list **del, t_flags *flgs); void sort_dirs(t_list **dirs, t_flags *flgs); -void output(t_list *del, char *current_dir, t_flags *flgs); + +void output(t_ft_ls *s_ls); +void print_full_path(t_ft_ls *s_ls, char *path); + int chck_flgs(char *flg, t_flags *flgs); void put_error(char *arg); diff --git a/src/flags.c b/src/flags.c index 4819e1b..1c5f5a8 100644 --- a/src/flags.c +++ b/src/flags.c @@ -4,7 +4,7 @@ int chck_long_flgs(char *flg, t_flags *flgs) { if (*(flg + 1) && (flg += 1)) { - if (flgs->abn == 0) flgs->abn = (ft_strcmp(flg, "all-by-name") == 0) + if (flgs->abn == 0) flgs->abn = (ft_strcmp(flg, "lex") == 0) ? 1 : 0; return (0); } @@ -12,11 +12,11 @@ int chck_long_flgs(char *flg, t_flags *flgs) } void chck_short_flgs(char *flg, t_flags *flgs) { - if (flgs->l == 0) flgs->l = (ft_strcmp(flg, "l") == 0) ? 1 : 0; - if (flgs->a == 0) flgs->a = (ft_strcmp(flg, "a") == 0) ? 1 : 0; - if (flgs->R == 0) flgs->R = (ft_strcmp(flg, "R") == 0) ? 1 : 0; - if (flgs->t == 0) flgs->t = (ft_strcmp(flg, "t") == 0) ? 1 : 0; - if (flgs->col == 0) flgs->col = (ft_strcmp(flg, "1") == 0) ? 1 : 0; + if (flgs->l == 0) flgs->l = (ft_strchr(flg, 'l') != NULL) ? 1 : 0; + if (flgs->a == 0) flgs->a = (ft_strchr(flg, 'a') != NULL) ? 1 : 0; + if (flgs->R == 0) flgs->R = (ft_strchr(flg, 'R') != NULL) ? 1 : 0; + if (flgs->t == 0) flgs->t = (ft_strchr(flg, 't') != NULL) ? 1 : 0; + if (flgs->col == 0) flgs->col = (ft_strchr(flg, '1') != NULL) ? 1 : 0; } int chck_flgs(char *flg, t_flags *flgs) diff --git a/src/ft_ls.c b/src/ft_ls.c index de200cc..e6ca76e 100644 --- a/src/ft_ls.c +++ b/src/ft_ls.c @@ -26,22 +26,24 @@ char *get_full_path(char *path, char *dir_ent_name) return (ft_strdup(dir_ent_name)); } -void init_dir_con_lst(t_list **dir_content_lst, t_list *filenames, - t_flags *flgs, char *par_dir) +void init_file_meta_lst(t_ft_ls *s_ls, char *full_path) { t_dir_elm de; char *tmp_path; + t_list *lst_rnr; - while (filenames) + lst_rnr = s_ls->lst_fil_names; + s_ls->lst_fil_meta = NULL; + while (lst_rnr) { - de.flags = flgs; + de.flags = s_ls->flgs; de.stat_buf_struc = malloc(sizeof(struct stat)); - de.elm_name = (char *)filenames->content; - tmp_path = get_full_path(par_dir, de.elm_name); + de.elm_name = (char *)lst_rnr->content; + tmp_path = get_full_path(full_path, de.elm_name); stat(tmp_path, de.stat_buf_struc); - ft_lstadd(dir_content_lst, ft_lstnew(&de, sizeof(t_dir_elm))); + ft_lstadd(&s_ls->lst_fil_meta, ft_lstnew(&de, sizeof(t_dir_elm))); free(tmp_path); - filenames = filenames->next; + lst_rnr = lst_rnr->next; } } @@ -81,61 +83,74 @@ void init_dir_con_lst(t_list **dir_content_lst, t_list *filenames, // closedir(dp); //} -t_list *extract_files_from_dir(char *dir, char *par_dir) +t_list *extract_filenames_from_dir(char *full_path) { DIR *dp; struct dirent *dir_ent; t_list *dir_files; - char *tmp_path; - tmp_path = get_full_path(par_dir, dir); - dp = opendir(tmp_path); + dp = opendir(full_path); dir_files = NULL; - while ((dir_ent = readdir(dp))) - fill_path_lst(&dir_files, dir_ent->d_name); + if (dp != NULL) + while ((dir_ent = readdir(dp))) + fill_path_lst(&dir_files, dir_ent->d_name); closedir(dp); - free(tmp_path); return (dir_files); } -t_list *extract_dirs_from_filenames(t_list *filenames, char *par_d) +t_ft_ls *extract_dirs_from_filenames(t_ft_ls *s_ls, char *full_path) { - t_list *dirs; - char *tmp_full_path; - dirs = NULL; + char *full_path_with_file; - while (filenames) + s_ls->lst_dir_paths = NULL; + while (s_ls->lst_fil_names) { - tmp_full_path = get_full_path(par_d, filenames->content); - if (opendir(tmp_full_path) && (ft_strcmp(filenames->content, ".") != 0) && (ft_strcmp(filenames->content, "..") != 0)) - fill_path_lst(&dirs, tmp_full_path); - free(tmp_full_path); - filenames = filenames->next; + full_path_with_file = get_full_path(full_path, s_ls->lst_fil_names->content); + if (opendir(full_path_with_file) && (ft_strcmp(s_ls->lst_fil_names->content, ".") != 0) && (ft_strcmp(s_ls->lst_fil_names->content, "..") != 0)) + { + if (s_ls->flgs->a) + fill_path_lst(&s_ls->lst_dir_paths, s_ls->lst_fil_names->content); + else if (*(char *)s_ls->lst_fil_names->content != '.') + fill_path_lst(&s_ls->lst_dir_paths, s_ls->lst_fil_names->content); + } + s_ls->lst_fil_names = s_ls->lst_fil_names->next; + free(full_path_with_file); } - return (dirs); + return (s_ls); } -void ft_ls(t_list *filenames, t_list *dir_paths, t_flags *flgs, - char *par_dir) +void ft_ls_dir(t_ft_ls *s_ls, char *full_path) { - t_list *dir_content_lst; + char *full_path_next; + t_list *tmp_rnr; - dir_content_lst = NULL; - if (filenames) + sort_dirs(&s_ls->lst_dir_paths, s_ls->flgs); + tmp_rnr = s_ls->lst_dir_paths; + while (tmp_rnr) { - init_dir_con_lst(&dir_content_lst, filenames, flgs, par_dir); - sort_elms(&dir_content_lst, flgs); - output(dir_content_lst, par_dir, flgs); - if (flgs->R) - ft_ls(NULL, extract_dirs_from_filenames(filenames, par_dir), flgs, NULL); - } - if (dir_paths) - { - sort_dirs(&dir_paths, flgs); - while (dir_paths) - { - ft_ls(extract_files_from_dir(dir_paths->content, par_dir), NULL, flgs, dir_paths->content); - dir_paths = dir_paths->next; - } + full_path_next = get_full_path(full_path, tmp_rnr->content); + s_ls->lst_fil_names = extract_filenames_from_dir(full_path_next); + ft_ls_fil(s_ls, full_path_next); + if (s_ls->flgs->R) + ft_ls_dir(extract_dirs_from_filenames(s_ls, full_path_next), full_path_next); + tmp_rnr = tmp_rnr->next; } +} + +void ft_ls_fil(t_ft_ls *s_ls, char *full_path) +{ + + init_file_meta_lst(s_ls, full_path); + sort_files(&s_ls->lst_fil_meta, s_ls->flgs); + if (full_path && !s_ls->one_dir && !s_ls->no_ops) + print_full_path(s_ls, full_path); + output(s_ls); +} + +void ft_ls(t_ft_ls *s_ls) +{ + if (s_ls->lst_fil_names) + ft_ls_fil(s_ls, NULL); + if (s_ls->lst_dir_paths) + ft_ls_dir(s_ls, NULL); } \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5765c9d..5acbf90 100644 --- a/src/main.c +++ b/src/main.c @@ -15,20 +15,23 @@ int main(int argc, char **argv) { static t_flags flgs; - t_list *str_paths[2]; - int no_errors; + static t_ft_ls s_ls; + int no_errors_and_valid_args; - str_paths[FILES] = NULL; - str_paths[DIRS] = NULL; - no_errors = parse_input(argc, argv, str_paths, &flgs); - if (str_paths[FILES] || str_paths[DIRS]) + s_ls.flgs = &flgs; + s_ls.first_print = 1; + no_errors_and_valid_args = parse_input(argc, argv, &s_ls); + if (s_ls.lst_dir_paths || s_ls.lst_fil_names) { - ft_ls(str_paths[FILES], str_paths[DIRS], &flgs, NULL); + if (ft_lst_len(s_ls.lst_dir_paths) == 1 && ft_lst_len(s_ls.lst_fil_names) == 0 && !s_ls.flgs->R) + s_ls.one_dir = 1; + ft_ls(&s_ls); } - else if (no_errors) + else if (no_errors_and_valid_args) { - fill_path_lst(&str_paths[DIRS], "./"); - ft_ls(NULL, str_paths[DIRS], &flgs, NULL); + s_ls.no_ops = 1; + fill_path_lst(&s_ls.lst_dir_paths, "./"); + ft_ls(&s_ls); } return 0; } diff --git a/src/output.c b/src/output.c index ac95ece..d622b63 100644 --- a/src/output.c +++ b/src/output.c @@ -6,13 +6,37 @@ void column_or_line(t_list *entity) d_elm = (t_dir_elm *)entity->content; ft_putstr(d_elm->elm_name); - if (entity->next) + if (!entity->next) + ft_putstr("\n"); + else if (d_elm->flags->col) + ft_putstr("\n"); + else + ft_putstr(" "); +} + +int is_hidden(char *path) +{ + char *begin; + char *end; + + begin = path; + end = path + ft_strlen(path) - 1; + if (begin != end) { - if (d_elm->flags->col) - ft_putstr("\n"); - else - ft_putstr(" "); + while (end != begin && *end != '/') + end--; + if (end == begin) + { + if (*end == '.') + return (1); + } + else if (*(end + 1) == '.') + return (1); } + else + if (*end == '.') + return (1); + return (0); } int out(t_list *entity) @@ -26,7 +50,7 @@ int out(t_list *entity) return (1); } else - if (*d_elm->elm_name != '.') + if (!is_hidden(d_elm->elm_name)) { column_or_line(entity); return (1); @@ -34,25 +58,16 @@ int out(t_list *entity) return (0); } -void print_full_path(char *path) +void print_full_path(t_ft_ls *s_ls, char *path) { char *cur_dir_semi_n; + s_ls = s_ls; cur_dir_semi_n = ft_strjoin(path, ":\n"); ft_putstr(cur_dir_semi_n); free(cur_dir_semi_n); } -void put_current_dir(char *cur_dir, t_flags *flgs) -{ - if (flgs->a) - print_full_path(cur_dir); - else - { - if (*cur_dir != '.') - print_full_path(cur_dir); - } -} int ft_lstiter_ret(t_list *lst, int (*f)(t_list *elem)) { @@ -68,10 +83,8 @@ int ft_lstiter_ret(t_list *lst, int (*f)(t_list *elem)) return (i); } -void output(t_list *del, char *current_dir, t_flags *flgs) +void output(t_ft_ls *s_ls) { - if (current_dir) - put_current_dir(current_dir, flgs); - if (ft_lstiter_ret(del, out)) - ft_putstr("\n"); + ft_lstiter_ret(s_ls->lst_fil_meta, out); + ft_putstr("\n"); } \ No newline at end of file diff --git a/src/parse_input.c b/src/parse_input.c index a41f99c..72c890c 100644 --- a/src/parse_input.c +++ b/src/parse_input.c @@ -24,7 +24,7 @@ void fill_path_lst(t_list **path_lst, char *path) ft_lstadd(path_lst, ft_lstnew(path, ft_strlen(path) + 1)); } -int parse_input(int ac, char **av, t_list **str_paths, t_flags *flgs) +int parse_input(int ac, char **av, t_ft_ls *ft_ls_strct) { int i; int open_type; @@ -36,13 +36,13 @@ int parse_input(int ac, char **av, t_list **str_paths, t_flags *flgs) return (no_errors); while (i < ac - 1) { - if (chck_flgs(av[i + 1], flgs)) + if (chck_flgs(av[i + 1], ft_ls_strct->flgs)) { open_type = chck_opn(av[i + 1]); if (open_type == 0) - fill_path_lst(&str_paths[FILES], av[i + 1]); + fill_path_lst(&ft_ls_strct->lst_fil_names, av[i + 1]); else if (open_type == 1) - fill_path_lst(&str_paths[DIRS], av[i + 1]); + fill_path_lst(&ft_ls_strct->lst_dir_paths, av[i + 1]); else if (open_type == -1) no_errors = 0; } diff --git a/src/sort.c b/src/sort.c index 3269d22..1c6d4ec 100644 --- a/src/sort.c +++ b/src/sort.c @@ -11,13 +11,20 @@ int by_name_and_same_type(t_dir_elm *a, t_dir_elm *b) return (0); } -int all_lex(t_dir_elm *a, t_dir_elm *b) +int by_name_lex(t_dir_elm *a, t_dir_elm *b) { if (ft_strcmp_lex(a->elm_name, b->elm_name) <= 0) return (1); return (0); } +int by_name(t_dir_elm *a, t_dir_elm *b) +{ + if (ft_strcmp(a->elm_name, b->elm_name) <= 0) + return (1); + return (0); +} + int by_size(t_dir_elm *a, t_dir_elm *b) { if (a->stat_buf_struc->st_size <= b->stat_buf_struc->st_size) @@ -27,10 +34,18 @@ int by_size(t_dir_elm *a, t_dir_elm *b) int by_m_time(t_dir_elm *a, t_dir_elm *b) { - if (a->stat_buf_struc->st_mtim.tv_sec >= - b->stat_buf_struc->st_mtim.tv_sec) + long dif; + + dif = a->stat_buf_struc->st_mtim.tv_sec - b->stat_buf_struc->st_mtim.tv_sec; + if (!dif) + dif = a->stat_buf_struc->st_mtim.tv_nsec - + b->stat_buf_struc->st_mtim.tv_nsec; + if (dif < 0) + return (0); + else if (dif > 0) return (1); - return (0); + else + return (by_name(a, b)); } int by_type(t_dir_elm *a, t_dir_elm *b) @@ -41,6 +56,13 @@ int by_type(t_dir_elm *a, t_dir_elm *b) } int path_by_name(char *a, char *b) +{ + if (ft_strcmp(a, b) <= 0) + return (1); + return (0); +} + +int path_by_name_lex(char *a, char *b) { if (ft_strcmp_lex(a, b) <= 0) return (1); @@ -54,18 +76,20 @@ void by_type_and_name(t_list **del) } -void sort_elms(t_list **del, t_flags *flgs) +void sort_files(t_list **del, t_flags *flgs) { if (flgs->t) ft_lst_merge_sort(del, by_m_time); - if (flgs->abn) - ft_lst_merge_sort(del, all_lex); + else if (flgs->abn) + ft_lst_merge_sort(del, by_name_lex); else - by_type_and_name(del); + ft_lst_merge_sort(del, by_name); } void sort_dirs(t_list **dirs, t_flags *flgs) { - flgs = flgs; - ft_lst_merge_sort(dirs, path_by_name); + if (flgs->abn) + ft_lst_merge_sort(dirs, path_by_name_lex); + else + ft_lst_merge_sort(dirs, path_by_name); } \ No newline at end of file