diff --git a/CMakeLists.txt b/CMakeLists.txt index a9f8c85..fc3f7ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.6) project(ft_ls) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wextra -O0 -g") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wextra -O3 -g") link_directories(libft) # libraries include_directories(inc libft/includes) # headers diff --git a/Makefile b/Makefile index feb09a5..f40f5c2 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ OBJ = $(addprefix $(OBJ_DIR), $(OBJ_FILES)) # header files and directories -HEADER = ft_ls.h +HEADER = ft_ls_dir.h FT_LS_INC = ./inc/ LIBFT_INC = $(LIBFT_DIR)includes/ INC = -I $(LIBFT_DIR)includes/ -I $(FT_LS_INC) @@ -65,7 +65,7 @@ FLAGS := $(CC_FLAGS) \ # compiler -CC = gcc +CC = clang # rules diff --git a/inc/ft_ls.h b/inc/ft_ls.h index 64f7371..4ac5a94 100644 --- a/inc/ft_ls.h +++ b/inc/ft_ls.h @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_ls.h :+: :+: :+: */ +/* ft_ls_dir.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: gtertysh +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -62,7 +62,6 @@ typedef struct s_dir_elm typedef struct s_ft_ls { - t_list *lst_dir_content; t_flags *flgs; t_col_len *max_cols_padd; int dir_content_total; @@ -72,9 +71,13 @@ typedef struct s_ft_ls int files_print; } t_ft_ls; -void ft_ls(t_ft_ls *s_ls, t_list *paths, char *curr_path); +void ft_ls_dir(t_ft_ls *s_ls, t_list *root, char *parent_dir); +void ft_ls_fil(t_ft_ls *s_ls, t_list *root); -void print_content(t_ft_ls *s_ls, char *full_path_curr); +t_list *operands_parse(t_list *ops, t_ft_ls *s_ls); + +void print_content(t_ft_ls *s_ls, t_list *curr_dir_content, + char *cur_path); int parse_input(int ac, char **av, t_list **file_and_dirs, t_flags *flgs); @@ -83,10 +86,10 @@ t_list *init_content_node(char *full_path, char *filename, t_ft_ls *s_ls); void fill_path_lst(t_list **path_lst, char *path); -void sort_files(t_list **del, t_flags *flgs); -void sort_paths(t_list **dirs, t_flags *flgs); +void sort_content(t_list **del, t_flags *flgs); +void sort_paths(t_list **paths); -void output(t_ft_ls *s_ls); +void output(t_ft_ls *s_ls, t_list *curr_dir_content); void print_full_path(t_ft_ls *s_ls, char *path); int chck_flgs(char *flg, t_flags *flgs); diff --git a/libft/Makefile b/libft/Makefile index 019865a..89f2f85 100644 --- a/libft/Makefile +++ b/libft/Makefile @@ -79,6 +79,7 @@ SRC = ft_memset.c \ ft_lstadd_back.c \ ft_lst_len.c \ ft_lst_merge_sort.c \ + ft_lst_rev.c \ \ ft_realloc.c \ ft_read_file.c \ diff --git a/libft/ft_lst_rev.c b/libft/ft_lst_rev.c new file mode 100644 index 0000000..d4bf4cb --- /dev/null +++ b/libft/ft_lst_rev.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_rev.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/09 16:28:30 by gtertysh #+# #+# */ +/* Updated: 2016/11/09 17:06:02 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_rev(t_list **begin_list) +{ + t_list *prev; + t_list *next; + t_list *curr; + + prev = NULL; + curr = *begin_list; + while (curr) + { + next = curr->next; + curr->next = prev; + prev = curr; + curr = next; + } + *begin_list = prev; +} diff --git a/libft/includes/libft.h b/libft/includes/libft.h index 80bd4ca..2d9c17f 100644 --- a/libft/includes/libft.h +++ b/libft/includes/libft.h @@ -106,6 +106,7 @@ t_list *ft_lstfind(t_list *lst, void *data, size_t size); t_list *ft_lst_at(t_list *l, unsigned int at); void ft_lstadd_back(t_list **l, void *data, size_t size); void ft_lst_merge_sort(t_list **head_ptr, int (*cmp)()); +void ft_lst_rev(t_list **begin_list); void *ft_realloc(void *old, unsigned int new_size, unsigned int old_size); diff --git a/src/flags.c b/src/flags.c index 1c5f5a8..a7dbae4 100644 --- a/src/flags.c +++ b/src/flags.c @@ -16,6 +16,7 @@ void chck_short_flgs(char *flg, t_flags *flgs) 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->r == 0) flgs->r = (ft_strchr(flg, 'r') != NULL) ? 1 : 0; if (flgs->col == 0) flgs->col = (ft_strchr(flg, '1') != NULL) ? 1 : 0; } diff --git a/src/ft_ls.c b/src/ft_ls.c index 401dc35..294939b 100644 --- a/src/ft_ls.c +++ b/src/ft_ls.c @@ -1,5 +1,31 @@ #include "ft_ls.h" +int is_hidden(char *path) +{ + char *begin; + char *end; + + begin = path; + end = path + ft_strlen(path) - 1; + if (begin != end) + { + 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); +} + + char *get_full_path(char *path, char *dir_ent_name) { char *tmp; @@ -94,21 +120,15 @@ char *get_time(t_dir_elm *d_elm) return (time); } -void get_max_padd(t_ft_ls *s_ls, t_dir_elm *d_elem) +void set_columns_padd(t_dir_elm *de) { - if (d_elem && s_ls) - { - if (d_elem->cols_padd.link_col > s_ls->max_cols_padd->link_col) - s_ls->max_cols_padd->link_col = d_elem->cols_padd.link_col; - if (d_elem->cols_padd.name_col > s_ls->max_cols_padd->name_col) - s_ls->max_cols_padd->name_col = d_elem->cols_padd.name_col; - if (d_elem->cols_padd.group_col > s_ls->max_cols_padd->group_col) - s_ls->max_cols_padd->group_col = d_elem->cols_padd.group_col; - if (d_elem->cols_padd.size_col > s_ls->max_cols_padd->size_col) - s_ls->max_cols_padd->size_col = d_elem->cols_padd.size_col; - } + de->cols_padd.link_col = ft_num_len(de->stat_copy->st_nlink); + de->cols_padd.name_col = (int)ft_strlen(de->u_name); + de->cols_padd.group_col = (int)ft_strlen(de->g_name); + de->cols_padd.size_col = ft_num_len(de->stat_copy->st_size); } + void get_info_from_stat(t_dir_elm *dir_elm) { dir_elm->attr_str = get_attr(dir_elm); @@ -117,34 +137,39 @@ void get_info_from_stat(t_dir_elm *dir_elm) dir_elm->m_time = get_time(dir_elm); } -void set_columns_padd(t_dir_elm *de) +void to_null(t_dir_elm *de) { - de->cols_padd.link_col = ft_num_len(de->stat_copy->st_nlink); - de->cols_padd.name_col = (int)ft_strlen(de->u_name); - de->cols_padd.group_col = (int)ft_strlen(de->g_name); - de->cols_padd.size_col = ft_num_len(de->stat_copy->st_size); + de->stat_copy = NULL; + de->link_name = NULL; + de->attr_str = NULL; + de->g_name = NULL; + de->u_name = NULL; + de->m_time = NULL; } t_list *read_stat(char *full_path, char *filename, t_ft_ls *s_ls) { t_dir_elm de; - char *tmp_file_path; + char *tmp_file_path;; + to_null(&de); de.elm_name = ft_strdup(filename); + tmp_file_path = get_full_path(full_path, filename); + de.stat_copy = malloc(sizeof(struct stat)); + lstat(tmp_file_path, de.stat_copy); + free(tmp_file_path); if (s_ls->flgs->l) { - tmp_file_path = get_full_path(full_path, filename); - de.stat_copy = malloc(sizeof(struct stat)); - lstat(tmp_file_path, de.stat_copy); if (S_ISLNK(de.stat_copy->st_mode)) { de.link_name = ft_strnew(PATH_MAX); if (readlink(tmp_file_path, de.link_name, PATH_MAX) == -1) put_error(0); } + else + de.link_name = NULL; get_info_from_stat(&de); set_columns_padd(&de); - free(tmp_file_path); } return (ft_lstnew(&de, sizeof(t_dir_elm))); } @@ -153,47 +178,38 @@ t_list *init_content_node(char *full_path, char *filename, t_ft_ls *s_ls) { if (s_ls->flgs->a) return (read_stat(full_path, filename, s_ls)); - else if (*filename != '.') + else if (!is_hidden(filename) || ft_strcmp(filename, ".") == 0) return (read_stat(full_path, filename, s_ls)); return (NULL); } -t_list *extract_dirs_from_filenames(char *full_path, t_ft_ls *s_ls) +t_list *find_dirs(char *full_path, t_ft_ls *s_ls, t_list *curr_dir_content) { char *full_path_with_file; t_dir_elm *dir_elm; - t_list *dir_paths; - t_list *dir_content; + t_list *dirs; - dir_content = s_ls->lst_dir_content; - dir_paths = NULL; - while (dir_content) + dirs = NULL; + while (curr_dir_content) { - dir_elm = (t_dir_elm *)dir_content->content; + dir_elm = (t_dir_elm *)curr_dir_content->content; full_path_with_file = get_full_path(full_path, dir_elm->elm_name); -// if (S_ISDIR(dir_elm->stat_copy->st_mode) && (ft_strcmp(dir_elm->elm_name, ".") != 0) && (ft_strcmp(dir_elm->elm_name, "..") != 0)) -// { -// if (s_ls->flgs->a) -// fill_path_lst(&dir_paths, dir_elm->elm_name); -// else if (*dir_elm->elm_name != '.') -// fill_path_lst(&dir_paths, dir_elm->elm_name); -// } - if (opendir(full_path_with_file) && (ft_strcmp(dir_elm->elm_name, ".") != 0) && (ft_strcmp(dir_elm->elm_name, "..") != 0)) + if ((S_ISDIR(dir_elm->stat_copy->st_mode)) && (ft_strcmp(dir_elm->elm_name, ".") != 0) && (ft_strcmp(dir_elm->elm_name, "..") != 0)) { if (s_ls->flgs->a) - fill_path_lst(&dir_paths, dir_elm->elm_name); + ft_lstadd(&dirs, ft_lstnew(dir_elm, sizeof(t_dir_elm))); else if (*dir_elm->elm_name != '.') - fill_path_lst(&dir_paths, dir_elm->elm_name); + ft_lstadd(&dirs, ft_lstnew(dir_elm, sizeof(t_dir_elm))); } - dir_content = dir_content->next; + curr_dir_content = curr_dir_content->next; free(full_path_with_file); } - return (dir_paths); + return (dirs); } void get_padding_and_blocks(t_ft_ls *s_ls, t_dir_elm *d_elem) { - if (d_elem && s_ls) + if (d_elem && s_ls && s_ls->flgs->l) { if (d_elem->cols_padd.link_col > s_ls->max_cols_padd->link_col) s_ls->max_cols_padd->link_col = d_elem->cols_padd.link_col; @@ -208,68 +224,117 @@ void get_padding_and_blocks(t_ft_ls *s_ls, t_dir_elm *d_elem) } } -void extract_content(char *full_path, t_ft_ls *s_ls) +void extract_content(char *full_path, t_ft_ls *s_ls, t_list **dir_content) { DIR *dp; struct dirent *de; t_list *lst_elm; - s_ls->lst_dir_content = NULL; + *dir_content = NULL; if ((dp = opendir(full_path))) { while ((de = readdir(dp))) { if ((lst_elm = init_content_node(full_path, de->d_name, s_ls))) { - get_max_padd(s_ls, lst_elm->content); get_padding_and_blocks(s_ls, lst_elm->content); - ft_lstadd(&s_ls->lst_dir_content, lst_elm); + ft_lstadd(dir_content, lst_elm); } } closedir(dp); } - else - { - lst_elm = init_content_node(NULL, full_path, s_ls); - get_max_padd(s_ls, lst_elm->content); - ft_lstadd(&s_ls->lst_dir_content, lst_elm); - } } -void reset_max_cols(t_ft_ls *s_ls) +void reset_s_ls(t_ft_ls *s_ls) { s_ls->max_cols_padd->group_col = 0; s_ls->max_cols_padd->name_col = 0; s_ls->max_cols_padd->link_col = 0; s_ls->max_cols_padd->size_col = 0; + s_ls->dir_content_total = 0; } -void print_content(t_ft_ls *s_ls, char *full_path_curr) +void print_content(t_ft_ls *s_ls, t_list *curr_dir_content, char *cur_path) { - t_list *dirs; - - sort_files(&s_ls->lst_dir_content, s_ls->flgs); if ((!s_ls->one_dir && !s_ls->no_ops) || s_ls->flgs->R) - print_full_path(s_ls, full_path_curr); - output(s_ls); - if (s_ls->flgs->R) + print_full_path(s_ls, cur_path); + output(s_ls, curr_dir_content); +} + +t_list *operands_parse(t_list *ops, t_ft_ls *s_ls) +{ + t_list *tmp_rnr; + t_list *root; + t_list *lst_elm; + + root = NULL; + tmp_rnr = ops; + while (tmp_rnr) { - dirs = extract_dirs_from_filenames(full_path_curr, s_ls); - reset_max_cols(s_ls); - ft_ls(s_ls, dirs, full_path_curr); + if ((lst_elm = init_content_node(NULL, tmp_rnr->content, s_ls))) + { + get_padding_and_blocks(s_ls, lst_elm->content); + ft_lstadd(&root, lst_elm); + tmp_rnr = tmp_rnr->next; + } + } + return (root); +} + + +void free_struct_lst(t_list *curr_cont) +{ + t_dir_elm *tmp; + t_list *tmp1; + while (curr_cont) + { + tmp1 = curr_cont->next; + if (curr_cont->content) + { + tmp = (t_dir_elm *)curr_cont->content; + free(tmp->attr_str); + free(tmp->elm_name); + free(tmp->g_name); + free(tmp->u_name); + free(tmp->m_time); + free(tmp->link_name); + free(tmp->stat_copy); + free(tmp); + } + free(curr_cont); + curr_cont = tmp1; } } -void ft_ls(t_ft_ls *s_ls, t_list *paths, char *curr_path) +void ft_ls_fil(t_ft_ls *s_ls, t_list *root) { - char *cur_filename; + sort_content(&root, s_ls->flgs); + print_content(s_ls, root, NULL); + free_struct_lst(root); +} - sort_paths(&paths, s_ls->flgs); - while (paths) +void ft_ls_dir(t_ft_ls *s_ls, t_list *root, char *parent_dir) +{ + char *cur_path; + t_list *curr_dir_content; + + curr_dir_content = NULL; + sort_content(&root, s_ls->flgs); + reset_s_ls(s_ls); + while (root) { - cur_filename = get_full_path(curr_path, paths->content); - extract_content(cur_filename, s_ls); - print_content(s_ls, cur_filename); - paths = paths->next; + cur_path = get_full_path(parent_dir, ((t_dir_elm *)root->content)->elm_name); + extract_content(cur_path, s_ls, &curr_dir_content); + if (curr_dir_content) + { + sort_content(&curr_dir_content, s_ls->flgs); + print_content(s_ls, curr_dir_content, cur_path); + } + if (s_ls->flgs->R) + ft_ls_dir(s_ls, find_dirs(cur_path, s_ls, curr_dir_content), cur_path); + root = root->next; + free(cur_path); } + free_struct_lst(curr_dir_content); + free_struct_lst(root); } \ No newline at end of file diff --git a/src/main.c b/src/main.c index bc1aeae..cefbb16 100644 --- a/src/main.c +++ b/src/main.c @@ -30,25 +30,24 @@ void ft_ls_start(t_ft_ls *s_ls, t_list **file_and_dirs, int no_error_operands) if (file_and_dirs[FILS]) { s_ls->files_print = 1; - sort_paths(&file_and_dirs[FILS], s_ls->flgs); - ft_ls(s_ls, file_and_dirs[FILS], NULL); + ft_ls_fil(s_ls, operands_parse(file_and_dirs[FILS], s_ls)); s_ls->files_print = 0; s_ls->first_print = 0; } if (file_and_dirs[DIRS]) { - sort_paths(&file_and_dirs[DIRS], s_ls->flgs); + sort_paths(&file_and_dirs[DIRS]); if (ft_lst_len(file_and_dirs[FILS]) == 0 && ft_lst_len(file_and_dirs[DIRS]) == 1) if (!s_ls->flgs->R) s_ls->one_dir = 1; - ft_ls(s_ls, file_and_dirs[DIRS], NULL); + ft_ls_dir(s_ls, operands_parse(file_and_dirs[DIRS], s_ls), NULL); } if (no_error_operands && (!file_and_dirs[DIRS] && !file_and_dirs[FILS])) { s_ls->one_dir = 1; fill_path_lst(&file_and_dirs[DIRS], "."); - ft_ls(s_ls, file_and_dirs[DIRS], NULL); + ft_ls_dir(s_ls, operands_parse(file_and_dirs[DIRS], s_ls), NULL); } } @@ -64,6 +63,8 @@ int main(int argc, char **argv) init_base_structs(&s_ls, &flgs, &padding, file_and_dirs); no_error_operands = parse_input(argc, argv, file_and_dirs, s_ls.flgs); ft_ls_start(&s_ls, file_and_dirs, no_error_operands); + free(file_and_dirs[FILS]); + free(file_and_dirs[DIRS]); free(file_and_dirs); return 0; } diff --git a/src/output.c b/src/output.c index fa43dc1..9cc6349 100644 --- a/src/output.c +++ b/src/output.c @@ -73,18 +73,25 @@ void long_format(t_list *lst_d_elm, t_ft_ls *s_ls) void one_line(t_list *lst_d_elm, t_ft_ls *s_ls) { ft_putstr(((t_dir_elm *)lst_d_elm->content)->elm_name); - s_ls = s_ls; + s_ls = 0; if (lst_d_elm->next) ft_putstr(" "); else ft_putstr("\n"); } -void out(t_ft_ls *s_ls, void (*format_fun)(t_list *, t_ft_ls *)) +void one_column(t_list *lst_d_elm, t_ft_ls *s_ls) +{ + s_ls = 0; + ft_putstr(((t_dir_elm *)lst_d_elm->content)->elm_name); + ft_putstr("\n"); +} + +void out(t_ft_ls *s_ls, t_list *cdc, void (*format_fun)(t_list *, t_ft_ls *)) { t_list *lst_rnr; - lst_rnr = s_ls->lst_dir_content; + lst_rnr = cdc; while (lst_rnr) { if (s_ls->flgs->a) @@ -95,20 +102,22 @@ void out(t_ft_ls *s_ls, void (*format_fun)(t_list *, t_ft_ls *)) } } -void output(t_ft_ls *s_ls) +void output(t_ft_ls *s_ls, t_list *curr_dir_content) { if (s_ls->flgs->l) { if (!s_ls->files_print) - put_total(s_ls->dir_content_total); - out(s_ls, long_format); + put_total(s_ls->dir_content_total / 2); + out(s_ls, curr_dir_content, long_format); } + else if (s_ls->flgs->col) + out(s_ls, curr_dir_content, one_column); else - out(s_ls, one_line); + out(s_ls, curr_dir_content, one_line); // else if (s_ls.flgs->col) // one_column(s_ls); // else // mult_column(s_ls); // ft_lstiter_ret(s_ls.lst_dir_content, out); -} \ No newline at end of file +} diff --git a/src/sort.c b/src/sort.c index 94b2f86..fdc3218 100644 --- a/src/sort.c +++ b/src/sort.c @@ -76,7 +76,7 @@ void by_type_and_name(t_list **del) } -void sort_files(t_list **del, t_flags *flgs) +void sort_content(t_list **del, t_flags *flgs) { if (flgs->t) ft_lst_merge_sort(del, by_m_time); @@ -84,12 +84,12 @@ void sort_files(t_list **del, t_flags *flgs) ft_lst_merge_sort(del, by_name_lex); else ft_lst_merge_sort(del, by_name); + if (flgs->r) + ft_lst_rev(del); } -void sort_paths(t_list **dirs, t_flags *flgs) +void sort_paths(t_list **paths) { - if (flgs->abn) - ft_lst_merge_sort(dirs, path_by_name_lex); - else - ft_lst_merge_sort(dirs, path_by_name); + + ft_lst_merge_sort(paths, path_by_name); } \ No newline at end of file