diff options
Diffstat (limited to 'src/commands/ls.c')
-rw-r--r-- | src/commands/ls.c | 159 |
1 files changed, 80 insertions, 79 deletions
diff --git a/src/commands/ls.c b/src/commands/ls.c index 855168c..ce7206c 100644 --- a/src/commands/ls.c +++ b/src/commands/ls.c @@ -15,14 +15,14 @@ #define EXEC_COLOR ANSCII BOLD NEXT NORMAL GREEN COLOR #define BLK_COLOR ANSCII BOLD NEXT NORMAL YELLOW COLOR -struct Flags { +static struct { bool hidden; bool hide_dot; bool more_info; bool one_column; bool recurse; enum When colored; -}; +} flags; struct FileInfo { struct passwd* usr; @@ -206,14 +206,14 @@ static char* get_file_color(struct FileInfo* info) { return color; } -static void list_files(struct FileInfo* files, int file_len, struct FileListInfo info, struct Flags* flags, const char* dir_path) { +static void list_files(struct FileInfo* files, int file_len, struct FileListInfo info, const char* dir_path) { struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); if (!isatty(1)) { - flags->one_column = true; - if (flags->colored == AUTO) - flags->colored = NO; + flags.one_column = true; + if (flags.colored == AUTO) + flags.colored = NO; } char* color; @@ -223,7 +223,7 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo for (int i = 0; i < file_len; i++) { struct FileInfo finfo = files[i]; color = get_file_color(&finfo); - if (flags->more_info) { + if (flags.more_info) { printf("%s %*d %*s %*s %*s %s %s%s%s", finfo.mode, info.max_link, @@ -235,9 +235,9 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo info.max_size, finfo.size, finfo.date, - flags->colored != NO ? color : "", + flags.colored != NO ? color : "", finfo.name, - flags->colored != NO ? "\x1b[0m" : "" + flags.colored != NO ? "\x1b[0m" : "" ); if (finfo.type == DT_LNK) { char path[PATH_MAX]; @@ -254,21 +254,21 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo } else { putchar('\n'); } - } else if (flags->one_column) { - printf("%s%s%s\n", flags->colored != NO ? color : "", finfo.name, flags->colored != NO ? "\x1b[0m" : ""); + } else if (flags.one_column) { + printf("%s%s%s\n", flags.colored != NO ? color : "", finfo.name, flags.colored != NO ? "\x1b[0m" : ""); } else { if (info.total_len > w.ws_col) { if (i != 0 && i % row_count == 0) putchar('\n'); - printf("%s%*s%s", flags->colored != NO ? color : "", -column_width, - finfo.name, flags->colored != NO ? "\x1b[0m" : ""); + printf("%s%*s%s", flags.colored != NO ? color : "", -column_width, + finfo.name, flags.colored != NO ? "\x1b[0m" : ""); } else { - printf("%s%s%s ", flags->colored != NO ? color : "", finfo.name, - flags->colored != NO ? "\x1b[0m" : ""); + printf("%s%s%s ", flags.colored != NO ? color : "", finfo.name, + flags.colored != NO ? "\x1b[0m" : ""); } } } - if (!flags->more_info) printf("\n"); + if (!flags.more_info) printf("\n"); } static bool is_dot_dir(const char* path) { @@ -321,7 +321,7 @@ static void push_file( (*size)++; } -static bool recurse_directory(char* path, struct Flags* flags) { +static bool recurse_directory(char* path) { DIR* d; struct dirent* file; bool first = true; @@ -338,10 +338,10 @@ static bool recurse_directory(char* path, struct Flags* flags) { while((file = readdir(d)) != NULL) { if (file->d_type == DT_DIR) continue; - if (!flags->hidden && prefix(".", file->d_name)) continue; + if (!flags.hidden && prefix(".", file->d_name)) continue; if (is_dot_dir(file->d_name)) continue; if (first) { - if (flags->colored == NO) + if (flags.colored == NO) printf("\n%s:\n", path); else printf("\n%s%s:%s\n", DIR_COLOR, path, FILE_COLOR); @@ -350,10 +350,10 @@ static bool recurse_directory(char* path, struct Flags* flags) { push_file(&files, &info, &size, &capacity, file->d_name, path); } - list_files(files, size, info, flags, path); + list_files(files, size, info, path); free(files); - if (!flags->more_info) printf("\n"); + if (!flags.more_info) printf("\n"); closedir(d); @@ -362,11 +362,11 @@ static bool recurse_directory(char* path, struct Flags* flags) { while((file = readdir(d)) != NULL) { if (file->d_type != DT_DIR) continue; - if (!flags->hidden && prefix(".", file->d_name)) continue; + if (!flags.hidden && prefix(".", file->d_name)) continue; if (is_dot_dir(file->d_name)) continue; char buf[PATH_MAX]; append_path(buf, path, file->d_name); - recurse_directory(buf, flags); + recurse_directory(buf); } closedir(d); @@ -374,9 +374,9 @@ static bool recurse_directory(char* path, struct Flags* flags) { return true; } -static bool list_directory(char* path, struct Flags* flags) { - if (flags->recurse) { - return recurse_directory(path, flags); +static bool list_directory(char* path) { + if (flags.recurse) { + return recurse_directory(path); } DIR* d = get_directory(path); @@ -390,12 +390,12 @@ static bool list_directory(char* path, struct Flags* flags) { struct dirent* file; while ((file = readdir(d)) != NULL) { - if (!flags->hidden && prefix(".", file->d_name)) continue; - if (flags->hide_dot && is_dot_dir(file->d_name)) continue; + if (!flags.hidden && prefix(".", file->d_name)) continue; + if (flags.hide_dot && is_dot_dir(file->d_name)) continue; push_file(&files, &info, &size, &capacity, file->d_name, path); } - if (size > 0) list_files(files, size, info, flags, path); + if (size > 0) list_files(files, size, info, path); free(files); closedir(d); @@ -408,7 +408,7 @@ static bool is_dir(const char* path) { return S_ISDIR(s.st_mode); } -static void list_file_args(int start, int argc, char** argv, struct Flags* flags) { +static void list_file_args(int start, int argc, char** argv) { int capacity = 8; int size = 0; struct FileInfo* files = malloc(sizeof(struct FileInfo) * capacity); @@ -420,12 +420,12 @@ static void list_file_args(int start, int argc, char** argv, struct Flags* flags push_file((struct FileInfo**) &files, &info, &size, &capacity, argv[i], "."); } - if (size > 0) list_files(files, size, info, flags, "."); + if (size > 0) list_files(files, size, info, "."); free(files); } -static void help() { +static void help(void) { printf("Usage: ls [FILE]...\n\n"); printf("List directory contents\n\n"); printf("\t-1\tOne column output\n"); @@ -433,12 +433,54 @@ static void help() { printf("\t-a\tInclude names starting with .\n"); printf("\t-A\tLike -a but without . and ..\n"); printf("\t-R\tRecurse\n"); - exit(EXIT_SUCCESS); +} + +static int short_arg(char c, char* next) { + UNUSED(next); + switch (c) { + case 'R': + flags.recurse = true; + break; + case '1': + flags.one_column = true; + break; + case 'A': + flags.hide_dot = true; + flags.hidden = true; + break; + case 'a': + flags.hidden = true; + break; + case 'l': + flags.more_info = true; + break; + default: + error("error: unkown option -%c", c); + } + return ARG_UNUSED; +} + +static int long_arg(char* cur, char* next) { + UNUSED(next); + if (prefix("--color=", cur)) { + char* arg = cur + 8; + if (streql("yes", arg) || streql("always", arg)) { + flags.colored = YES; + } else if (streql("auto", arg)) { + flags.colored = AUTO; + } else if (streql("no", arg) || streql("never", arg)) { + flags.colored = NO; + } else { + error("error: invalid color options: %s", arg); + } + } else { + return ARG_IGNORE; + } + return ARG_UNUSED; } COMMAND(ls) { - struct Flags flags; flags.hidden = false; flags.more_info = false; flags.hide_dot = false; @@ -446,55 +488,14 @@ COMMAND(ls) { flags.recurse = false; flags.colored = AUTO; - int start = 0; - for (int i = 0; i < argc; i++) { - if (!prefix("-", argv[i])) break; - if (streql("--help", argv[i])) help(); - start++; - if (prefix("--color=", argv[i])) { - char* arg = argv[i] + 8; - if (streql("yes", arg) || streql("always", arg)) { - flags.colored = YES; - } else if (streql("auto", arg)) { - flags.colored = AUTO; - } else if (streql("no", arg) || streql("never", arg)) { - flags.colored = NO; - } else { - error("error: invalid color options: %s", arg); - } - continue; - } - for (size_t j = 1; j < strlen(argv[i]); j++) { - char c = argv[i][j]; - switch (c) { - case 'R': - flags.recurse = true; - break; - case '1': - flags.one_column = true; - break; - case 'A': - flags.hide_dot = true; - flags.hidden = true; - break; - case 'a': - flags.hidden = true; - break; - case 'l': - flags.more_info = true; - break; - default: - error("error: unkown option -%c", c); - } - } - } + int start = parse_args(argc, argv, help, short_arg, long_arg); if (argc - start == 0) { - list_directory(".", &flags); + list_directory("."); return EXIT_SUCCESS; } - list_file_args(start, argc, argv, &flags); + list_file_args(start, argc, argv); bool titled = argc - start > 1; for (int i = start; i < argc; i++) { @@ -505,7 +506,7 @@ COMMAND(ls) { else printf("\n%s:\n", argv[i]); } - if (list_directory(argv[i], &flags) && i + 1 != argc) + if (list_directory(argv[i]) && i + 1 != argc) if (titled && !flags.recurse) printf("\n"); } |